Skip to content

Commit 5d63199

Browse files
committed
[Sema] Avoid walking lazy inits in ContextualizeClosuresAndMacros
We want these to be contextualized as part of their implicit getter, avoid attempting to contextualize as part of the PatternBindingDecl. This avoid incorrectly computing captures as part of the PatternBindingDecl; as such we also need to update ActorIsolationChecker to walk lazy inits as part of the accessor.
1 parent 61393de commit 5d63199

File tree

4 files changed

+23
-0
lines changed

4 files changed

+23
-0
lines changed

lib/Sema/TypeCheckConcurrency.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2926,6 +2926,13 @@ namespace {
29262926
return MacroWalking::Expansion;
29272927
}
29282928

2929+
LazyInitializerWalking getLazyInitializerWalkingBehavior() override {
2930+
// We want to walk lazy initializers as part of their implicit getters
2931+
// since we're interested in querying capture information, and captures
2932+
// for lazy inits are computed as part of type-checking the accessor.
2933+
return LazyInitializerWalking::InAccessor;
2934+
}
2935+
29292936
PreWalkResult<Pattern *> walkToPatternPre(Pattern *pattern) override {
29302937
// Walking into patterns leads to nothing good because then we
29312938
// end up visiting the AccessorDecls of a top-level

lib/Sema/TypeCheckStmt.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,12 @@ namespace {
7878
return MacroWalking::ArgumentsAndExpansion;
7979
}
8080

81+
LazyInitializerWalking getLazyInitializerWalkingBehavior() override {
82+
// Don't walk lazy initializers, we contextualize the getter body
83+
// specially when synthesizing.
84+
return LazyInitializerWalking::None;
85+
}
86+
8187
PreWalkResult<Expr *> walkToExprPre(Expr *E) override {
8288
if (auto CE = dyn_cast<AutoClosureExpr>(E)) {
8389
CE->setParent(ParentDC);

lib/Sema/TypeCheckStorage.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1679,6 +1679,7 @@ namespace {
16791679
// If we find a closure, update its declcontext and do *not* walk into it.
16801680
if (auto CE = dyn_cast<AbstractClosureExpr>(E)) {
16811681
CE->setParent(NewDC);
1682+
TypeChecker::computeCaptures(CE);
16821683
return Action::SkipNode(E);
16831684
}
16841685

test/SILGen/skip_function_bodies_storage.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,3 +39,12 @@ extension S: P {}
3939
// CHECK: sil shared [serialized]{{.*}} @$s4main1SV11borrowedVarSivr : $@yield_once @convention(method) (S) -> @yields Int {
4040
// CHECK: yield
4141
// CHECK: } // end sil function '$s4main1SV11borrowedVarSivr'
42+
43+
// We type-check this function since it has a nested type, but we don't
44+
// type-check the implicit lazy getter for 'x'. As such, the nested autoclosure
45+
// won't have captures computed. Make sure we don't attempt to query the
46+
// captures.
47+
func testAutoclosureInLazyVar(_ y: Int?) {
48+
struct R {}
49+
lazy var x = y ?? 0
50+
}

0 commit comments

Comments
 (0)