Skip to content

Commit da591ac

Browse files
committed
Sema: Make implicit elementwise struct init insensitive to lazy validation order.
With batch mode, other files may have forced lazy properties to get finalized before the implicit constructor is formed. Avoid the order dependency by making the behavior stable regardless of the type-checking phase of lazy declarations. Fixes rdar://problem/40903186.
1 parent b52ef8b commit da591ac

File tree

3 files changed

+24
-4
lines changed

3 files changed

+24
-4
lines changed

lib/Sema/CodeSynthesis.cpp

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1881,12 +1881,21 @@ ConstructorDecl *swift::createImplicitConstructor(TypeChecker &tc,
18811881
if (ICK == ImplicitConstructorKind::Memberwise) {
18821882
assert(isa<StructDecl>(decl) && "Only struct have memberwise constructor");
18831883

1884-
// Computed and static properties are not initialized.
1885-
for (auto var : decl->getStoredProperties()) {
1886-
if (var->isImplicit())
1884+
for (auto member : decl->getMembers()) {
1885+
auto var = dyn_cast<VarDecl>(member);
1886+
if (!var)
18871887
continue;
1888-
tc.validateDecl(var);
18891888

1889+
// Implicit, computed, and static properties are not initialized.
1890+
// The exception is lazy properties, which due to batch mode we may or
1891+
// may not have yet finalized, so they may currently be "stored" or
1892+
// "computed" in the current AST state.
1893+
if (var->isImplicit() || var->isStatic())
1894+
continue;
1895+
tc.validateDecl(var);
1896+
if (!var->hasStorage() && !var->getAttrs().hasAttribute<LazyAttr>())
1897+
continue;
1898+
18901899
// Initialized 'let' properties have storage, but don't get an argument
18911900
// to the memberwise initializer since they already have an initial
18921901
// value that cannot be overridden.
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
struct B {
2+
var other: Int = 0
3+
lazy var crash: String = {
4+
return ""
5+
}()
6+
}
7+
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %target-swift-frontend -c -primary-file %s -o %t/a.o -primary-file %S/Inputs/lazy_properties_batch_mode_b.swift -o %t/b.o
3+
func foo(_: B) {}
4+

0 commit comments

Comments
 (0)