Skip to content

Commit 96b7450

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 21681fa commit 96b7450

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
@@ -1888,12 +1888,21 @@ ConstructorDecl *swift::createImplicitConstructor(TypeChecker &tc,
18881888
if (ICK == ImplicitConstructorKind::Memberwise) {
18891889
assert(isa<StructDecl>(decl) && "Only struct have memberwise constructor");
18901890

1891-
// Computed and static properties are not initialized.
1892-
for (auto var : decl->getStoredProperties()) {
1893-
if (var->isImplicit())
1891+
for (auto member : decl->getMembers()) {
1892+
auto var = dyn_cast<VarDecl>(member);
1893+
if (!var)
18941894
continue;
1895-
tc.validateDecl(var);
18961895

1896+
// Implicit, computed, and static properties are not initialized.
1897+
// The exception is lazy properties, which due to batch mode we may or
1898+
// may not have yet finalized, so they may currently be "stored" or
1899+
// "computed" in the current AST state.
1900+
if (var->isImplicit() || var->isStatic())
1901+
continue;
1902+
tc.validateDecl(var);
1903+
if (!var->hasStorage() && !var->getAttrs().hasAttribute<LazyAttr>())
1904+
continue;
1905+
18971906
// Initialized 'let' properties have storage, but don't get an argument
18981907
// to the memberwise initializer since they already have an initial
18991908
// 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)