Skip to content

Commit 53d65b0

Browse files
authored
Merge pull request #39064 from xymus/rdar82269657
[Sema] Build TRC for delayed functions bodies
2 parents 027a41d + 65c9a8f commit 53d65b0

File tree

4 files changed

+75
-0
lines changed

4 files changed

+75
-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: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
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.10 2>&1 \
5+
// RUN: | %FileCheck %s --check-prefixes TRC-API,TRC-INLINABLE,TRC-WITHTYPES,TRC-FULL
6+
// RUN: %target-swift-frontend -typecheck -dump-type-refinement-contexts %s -target x86_64-apple-macos10.10 -experimental-skip-non-inlinable-function-bodies-without-types 2>&1 \
7+
// RUN: | %FileCheck %s --check-prefixes TRC-API,TRC-INLINABLE,TRC-WITHTYPES,TRC-FULL-NOT
8+
// RUN: %target-swift-frontend -typecheck -dump-type-refinement-contexts %s -target x86_64-apple-macos10.10 -experimental-skip-non-inlinable-function-bodies 2>&1 \
9+
// RUN: | %FileCheck %s --check-prefixes TRC-API,TRC-INLINABLE,TRC-WITHTYPES-NOT,TRC-FULL-NOT
10+
// RUN: %target-swift-frontend -typecheck -dump-type-refinement-contexts %s -target x86_64-apple-macos10.10 -experimental-skip-all-function-bodies 2>&1 \
11+
// RUN: | %FileCheck %s --check-prefixes TRC-API,TRC-INLINABLE-NOT,TRC-WITHTYPES-NOT,TRC-FULL-NOT
12+
13+
// REQUIRES: OS=macosx
14+
15+
@available(macOS 10.12, *)
16+
public func foo() { }
17+
// TRC-API: (root versions=[10.10.0,+Inf)
18+
// TRC-API: (decl versions=[10.12,+Inf) decl=foo()
19+
20+
@inlinable public func inlinableFunc() {
21+
if #available(macOS 10.12, *) {
22+
foo()
23+
}
24+
}
25+
// TRC-INLINABLE: (condition_following_availability versions=[10.12,+Inf)
26+
// TRC-INLINABLE: (if_then versions=[10.12,+Inf)
27+
// TRC-INLINABLE-NOT-NOT: (condition_following_availability versions=[10.12,+Inf)
28+
// TRC-INLINABLE-NOT-NOT: (if_then versions=[10.12,+Inf)
29+
30+
public func funcWithType() {
31+
struct S {}
32+
if #available(macOS 10.13, *) {
33+
foo()
34+
}
35+
}
36+
// TRC-WITHTYPES: (condition_following_availability versions=[10.13,+Inf)
37+
// TRC-WITHTYPES: (if_then versions=[10.13,+Inf)
38+
// TRC-WITHTYPES-NOT-NOT: (condition_following_availability versions=[10.13,+Inf)
39+
// TRC-WITHTYPES-NOT-NOT: (if_then versions=[10.13,+Inf)
40+
41+
public func funcSkippable() {
42+
if #available(macOS 10.14, *) {
43+
foo()
44+
}
45+
}
46+
// TRC-FULL: (condition_following_availability versions=[10.14,+Inf)
47+
// TRC-FULL: (if_then versions=[10.14,+Inf)
48+
// TRC-FULL-NOT-NOT: (condition_following_availability versions=[10.14,+Inf)
49+
// TRC-FULL-NOT-NOT: (if_then versions=[10.14,+Inf)

0 commit comments

Comments
 (0)