Skip to content

Commit 07a85b4

Browse files
committed
[Sema] Build the TRC for delayed functions bodies
We used to build the full TypeRefinementContext of a source file before parsing delayed function bodies. This can lead to availability checking errors in delayed function bodies as the TRCs are incomplete. Complete the TRC of each delayed function before type-checking them to fix this. rdar://82269657
1 parent b201d48 commit 07a85b4

File tree

4 files changed

+51
-0
lines changed

4 files changed

+51
-0
lines changed

lib/Sema/TypeCheckAvailability.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -916,6 +916,25 @@ void TypeChecker::buildTypeRefinementContextHierarchy(SourceFile &SF) {
916916
}
917917
}
918918

919+
void TypeChecker::buildTypeRefinementContextHierarchyDelayed(SourceFile &SF, AbstractFunctionDecl *AFD) {
920+
// If there's no TRC for the file, we likely don't want this one either.
921+
// RootTRC is not set when availability checking is disabled.
922+
TypeRefinementContext *RootTRC = SF.getTypeRefinementContext();
923+
if(!RootTRC)
924+
return;
925+
926+
if (AFD->getBodyKind() != AbstractFunctionDecl::BodyKind::Unparsed)
927+
return;
928+
929+
// Parse the function body.
930+
AFD->getBody(/*canSynthesize=*/true);
931+
932+
// Build the refinement context for the function body.
933+
ASTContext &Context = SF.getASTContext();
934+
TypeRefinementContextBuilder Builder(RootTRC, Context);
935+
Builder.build(AFD);
936+
}
937+
919938
TypeRefinementContext *
920939
TypeChecker::getOrBuildTypeRefinementContext(SourceFile *SF) {
921940
TypeRefinementContext *TRC = SF->getTypeRefinementContext();

lib/Sema/TypeChecker.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,9 @@ static void typeCheckDelayedFunctions(SourceFile &SF) {
252252
while (currentFunctionIdx < SF.DelayedFunctions.size()) {
253253
auto *AFD = SF.DelayedFunctions[currentFunctionIdx];
254254
assert(!AFD->getDeclContext()->isLocalContext());
255+
256+
TypeChecker::buildTypeRefinementContextHierarchyDelayed(SF, AFD);
257+
255258
(void) AFD->getTypecheckedBody();
256259
++currentFunctionIdx;
257260
}

lib/Sema/TypeChecker.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -961,6 +961,10 @@ AvailabilityContext overApproximateAvailabilityAtLocation(
961961
/// Walk the AST to build the hierarchy of TypeRefinementContexts
962962
void buildTypeRefinementContextHierarchy(SourceFile &SF);
963963

964+
/// Walk the AST to complete the hierarchy of TypeRefinementContexts for
965+
/// the delayed function body of \p AFD.
966+
void buildTypeRefinementContextHierarchyDelayed(SourceFile &SF, AbstractFunctionDecl *AFD);
967+
964968
/// Build the hierarchy of TypeRefinementContexts for the entire
965969
/// source file, if it has not already been built. Returns the root
966970
/// TypeRefinementContext for the source file.
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/// Check for reliable availability checking in inlinable code even when
2+
/// skipping some function bodies. rdar://82269657
3+
4+
// RUN: %target-swift-frontend -typecheck -dump-type-refinement-contexts %s -target x86_64-apple-macos10.12
5+
// RUN: %target-swift-frontend -typecheck -dump-type-refinement-contexts %s -target x86_64-apple-macos10.12 -experimental-skip-non-inlinable-function-bodies
6+
// RUN: %target-swift-frontend -typecheck -dump-type-refinement-contexts %s -target x86_64-apple-macos10.12 -experimental-skip-non-inlinable-function-bodies-without-types
7+
// RUN: %target-swift-frontend -typecheck -dump-type-refinement-contexts %s -target x86_64-apple-macos10.12 -experimental-skip-all-function-bodies
8+
9+
// REQUIRES: OS=macosx
10+
11+
@available(macOS 10.14, *)
12+
public func foo() { }
13+
14+
@inlinable public func inlinableFunc() {
15+
if #available(macOS 10.14, *) {
16+
foo()
17+
}
18+
}
19+
20+
public func funcWithType() {
21+
struct S {}
22+
if #available(macOS 10.14, *) {
23+
foo()
24+
}
25+
}

0 commit comments

Comments
 (0)