[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.
This commit is contained in:
Hamish Knight
2024-12-27 14:44:55 +00:00
parent 61393dee3a
commit 5d631990bb
4 changed files with 23 additions and 0 deletions

View File

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

View File

@@ -78,6 +78,12 @@ namespace {
return MacroWalking::ArgumentsAndExpansion;
}
LazyInitializerWalking getLazyInitializerWalkingBehavior() override {
// Don't walk lazy initializers, we contextualize the getter body
// specially when synthesizing.
return LazyInitializerWalking::None;
}
PreWalkResult<Expr *> walkToExprPre(Expr *E) override {
if (auto CE = dyn_cast<AutoClosureExpr>(E)) {
CE->setParent(ParentDC);

View File

@@ -1679,6 +1679,7 @@ namespace {
// If we find a closure, update its declcontext and do *not* walk into it.
if (auto CE = dyn_cast<AbstractClosureExpr>(E)) {
CE->setParent(NewDC);
TypeChecker::computeCaptures(CE);
return Action::SkipNode(E);
}

View File

@@ -39,3 +39,12 @@ extension S: P {}
// CHECK: sil shared [serialized]{{.*}} @$s4main1SV11borrowedVarSivr : $@yield_once @convention(method) (S) -> @yields Int {
// CHECK: yield
// CHECK: } // end sil function '$s4main1SV11borrowedVarSivr'
// We type-check this function since it has a nested type, but we don't
// type-check the implicit lazy getter for 'x'. As such, the nested autoclosure
// won't have captures computed. Make sure we don't attempt to query the
// captures.
func testAutoclosureInLazyVar(_ y: Int?) {
struct R {}
lazy var x = y ?? 0
}