Skip to content

Commit 6d6fba5

Browse files
committed
Sema: Don't visit local types when computing captures
Ordinarily in valid code, pattern binding initializers in local types cannot capture anything from the outer scope. However one exception is lazy property initializers, which can reference the lazy property initializer context's 'self' parameter. If we computed captures for the outer function before synthesizing the lazy property getter, we would think that the 'self' parameter was a capture of the outer function, with hilarious results. Fixes <rdar://problem/54712320>.
1 parent 1a1f731 commit 6d6fba5

File tree

3 files changed

+33
-0
lines changed

3 files changed

+33
-0
lines changed

lib/Sema/TypeCheckCaptures.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -365,6 +365,11 @@ class FindCapturedVars : public ASTWalker {
365365
return false;
366366
}
367367

368+
// Don't walk into local types; we'll walk their initializers when we check
369+
// the local type itself.
370+
if (isa<NominalTypeDecl>(D))
371+
return false;
372+
368373
return true;
369374
}
370375

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
public class C2 {
2+
public final func f() {
3+
func local() {
4+
_ = {
5+
class Local {
6+
lazy var a = {
7+
return b
8+
}()
9+
var b = 123
10+
}
11+
}
12+
}
13+
}
14+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// RUN: %target-swift-emit-silgen -primary-file %s %S/Inputs/lazy_properties_other.swift -module-name lazy_properties_multi | %FileCheck %s
2+
// RUN: %target-swift-emit-silgen %S/Inputs/lazy_properties_other.swift -primary-file %s -module-name lazy_properties_multi | %FileCheck %s
3+
// RUN: %target-swift-emit-silgen %S/Inputs/lazy_properties_other.swift %s -module-name lazy_properties_multi | %FileCheck %s
4+
// RUN: %target-swift-emit-silgen %s %S/Inputs/lazy_properties_other.swift -module-name lazy_properties_multi | %FileCheck %s
5+
6+
7+
public class C1 {
8+
// CHECK-LABEL: sil [ossa] @$s21lazy_properties_multi2C1C1f1cyAA2C2C_tF : $@convention(method) (@guaranteed C2, @guaranteed C1) -> () {
9+
// CHECK: [[FN:%.*]] = function_ref @$s21lazy_properties_multi2C2C1fyyF : $@convention(method) (@guaranteed C2)
10+
// CHECK: apply [[FN]](%0) : $@convention(method) (@guaranteed C2) -> ()
11+
public func f(c: C2) {
12+
c.f()
13+
}
14+
}

0 commit comments

Comments
 (0)