Skip to content

Commit 159c946

Browse files
authored
Merge pull request #39081 from xymus/rdar82269657-5.5
[5.5][Sema] Build TRC for delayed functions to fix availability issues in emit-module-separately
2 parents 01865c0 + 28945da commit 159c946

File tree

4 files changed

+73
-0
lines changed

4 files changed

+73
-0
lines changed

lib/Sema/TypeCheckAvailability.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -873,6 +873,25 @@ void TypeChecker::buildTypeRefinementContextHierarchy(SourceFile &SF) {
873873
}
874874
}
875875

876+
void TypeChecker::buildTypeRefinementContextHierarchyDelayed(SourceFile &SF, AbstractFunctionDecl *AFD) {
877+
// If there's no TRC for the file, we likely don't want this one either.
878+
// RootTRC is not set when availability checking is disabled.
879+
TypeRefinementContext *RootTRC = SF.getTypeRefinementContext();
880+
if(!RootTRC)
881+
return;
882+
883+
if (AFD->getBodyKind() != AbstractFunctionDecl::BodyKind::Unparsed)
884+
return;
885+
886+
// Parse the function body.
887+
AFD->getBody(/*canSynthesize=*/true);
888+
889+
// Build the refinement context for the function body.
890+
ASTContext &Context = SF.getASTContext();
891+
TypeRefinementContextBuilder Builder(RootTRC, Context);
892+
Builder.build(AFD);
893+
}
894+
876895
TypeRefinementContext *
877896
TypeChecker::getOrBuildTypeRefinementContext(SourceFile *SF) {
878897
TypeRefinementContext *TRC = SF->getTypeRefinementContext();

lib/Sema/TypeChecker.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,7 @@ static void typeCheckDelayedFunctions(SourceFile &SF) {
256256
++currentFunctionIdx) {
257257
auto *AFD = SF.DelayedFunctions[currentFunctionIdx];
258258
assert(!AFD->getDeclContext()->isLocalContext());
259+
TypeChecker::buildTypeRefinementContextHierarchyDelayed(SF, AFD);
259260
(void)AFD->getTypecheckedBody();
260261
}
261262

lib/Sema/TypeChecker.h

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

961+
/// Walk the AST to complete the hierarchy of TypeRefinementContexts for
962+
/// the delayed function body of \p AFD.
963+
void buildTypeRefinementContextHierarchyDelayed(SourceFile &SF, AbstractFunctionDecl *AFD);
964+
961965
/// Build the hierarchy of TypeRefinementContexts for the entire
962966
/// source file, if it has not already been built. Returns the root
963967
/// 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)