[TypeChecker] Avoid checking lazy property accessors if they haven't been synthesized yet

Ttheir availability is going to match the property itself.
This is a workaround for lazy type-checking because synthesis
of accessors for such properties requires a reference to
`self` which won't be available because pattern binding
for the variable was skipped.

Resolves: rdar://129359362
Resolves: rdar://159463230
Resolves: https://github.com/swiftlang/swift/issues/84041
This commit is contained in:
Pavel Yaskevich
2025-09-02 15:43:15 -07:00
parent a80ba340db
commit 6e7de5c1e0
3 changed files with 28 additions and 0 deletions

View File

@@ -2707,6 +2707,25 @@ private:
return;
}
// Avoid checking lazy property accessors if they haven't been
// synthesized yet, their availability is going to match the
// property itself. This is a workaround for lazy type-checking
// because synthesis of accessors for such properties requires
// a reference to `self` which won't be available because pattern
// binding for the variable was skipped.
//
// TODO: To fix this properly `getParentPatternBinding()`
// has to be refactored into a request to help establish association
// between a variable declaration and its pattern binding on demand
// instead of by using `typeCheckPatternBinding` called from the
// declaration checker.
if (D->getAttrs().hasAttribute<LazyAttr>()) {
auto *DC = D->getDeclContext();
if (DC->isTypeContext() && !(D->getAccessor(AccessorKind::Get) &&
D->getAccessor(AccessorKind::Set)))
return;
}
DeclAvailabilityFlags flags;
if (InInOutExpr)
flags |= DeclAvailabilityFlag::ForInout;

View File

@@ -402,3 +402,7 @@ extension PublicStruct {
lhs = rhs
}
}
public class LazyPropertyWithClosureType {
public lazy var lazyVar: Int = { 2 }()
}

View File

@@ -142,3 +142,8 @@ func testOperators() {
var a: PublicStruct
a <<< PublicStruct(x: 2)
}
func testLazyPropertyWithInitClosureReference(t: LazyPropertyWithClosureType) {
_ = t.lazyVar
t.lazyVar = 42
}