Skip to content

Commit 7e1ed77

Browse files
authored
Merge pull request swiftlang#28099 from theblixguy/fix/SR-10937
[PropertyWrappers] Fix a crash when using multiple wrappers of the same type
2 parents b8122db + a2d0bf6 commit 7e1ed77

File tree

2 files changed

+43
-4
lines changed

2 files changed

+43
-4
lines changed

lib/AST/Decl.cpp

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6127,13 +6127,25 @@ Expr *swift::findOriginalPropertyWrapperInitialValue(VarDecl *var,
61276127
if (!call->isImplicit())
61286128
return { true, E };
61296129

6130-
// ... producing a value of the same nominal type as the innermost
6131-
// property wrapper.
6130+
// ... which may call the constructor of another property
6131+
// wrapper if there are multiple wrappers attached to the
6132+
// property.
6133+
if (auto tuple = dyn_cast<TupleExpr>(call->getArg())) {
6134+
if (tuple->getNumElements() > 0) {
6135+
auto elem = tuple->getElement(0);
6136+
if (elem->isImplicit() && isa<CallExpr>(elem)) {
6137+
return { true, E };
6138+
}
6139+
}
6140+
}
6141+
6142+
// ... producing a value of the same nominal type as the
6143+
// innermost property wrapper.
61326144
if (!call->getType() ||
61336145
call->getType()->getAnyNominal() != innermostNominal)
6134-
return { true, E };
6146+
return { false, E };
61356147

6136-
// Find the implicit initialValue argument.
6148+
// Find the implicit initialValue/wrappedValue argument.
61376149
if (auto tuple = dyn_cast<TupleExpr>(call->getArg())) {
61386150
ASTContext &ctx = innermostNominal->getASTContext();
61396151
for (unsigned i : range(tuple->getNumElements())) {
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// RUN: %target-swift-frontend -emit-sil %s
2+
3+
@propertyWrapper
4+
struct Foo<T> {
5+
init(wrappedValue: T) {
6+
self.wrappedValue = wrappedValue
7+
}
8+
9+
var wrappedValue: T
10+
}
11+
12+
@propertyWrapper
13+
struct Bar<T> {
14+
init(wrappedValue: T) {
15+
self.wrappedValue = wrappedValue
16+
}
17+
18+
var wrappedValue: T
19+
}
20+
21+
struct Container {
22+
@Foo @Foo var x: Int = 0
23+
@Foo @Foo @Bar @Bar var y: Int = 1
24+
@Foo @Bar @Foo @Foo var z: Int = 2
25+
}
26+
27+
_ = Container()

0 commit comments

Comments
 (0)