Skip to content

Commit 8ba8d95

Browse files
authored
Merge pull request #32258 from DougGregor/property-wrapper-opaque-result-crash-fix-5.3
[5.3] [Property wrappers] Reject opaque result types when there is no initializer
2 parents 2e6bf1a + 41fc033 commit 8ba8d95

File tree

3 files changed

+43
-11
lines changed

3 files changed

+43
-11
lines changed

lib/Sema/TypeCheckStorage.cpp

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2684,16 +2684,21 @@ PropertyWrapperBackingPropertyInfoRequest::evaluate(Evaluator &evaluator,
26842684
pbd->setInit(0, initializer);
26852685
pbd->setInitializerChecked(0);
26862686
wrappedValue = findWrappedValuePlaceholder(initializer);
2687-
} else if (!parentPBD->isInitialized(patternNumber) &&
2688-
wrapperInfo.defaultInit) {
2689-
// FIXME: Record this expression somewhere so that DI can perform the
2690-
// initialization itself.
2691-
auto typeExpr = TypeExpr::createImplicit(storageType, ctx);
2692-
Expr *initializer = CallExpr::createImplicit(ctx, typeExpr, {}, { });
2693-
typeCheckSynthesizedWrapperInitializer(pbd, backingVar, parentPBD,
2694-
initializer);
2695-
pbd->setInit(0, initializer);
2696-
pbd->setInitializerChecked(0);
2687+
} else {
2688+
if (!parentPBD->isInitialized(patternNumber) && wrapperInfo.defaultInit) {
2689+
// FIXME: Record this expression somewhere so that DI can perform the
2690+
// initialization itself.
2691+
auto typeExpr = TypeExpr::createImplicit(storageType, ctx);
2692+
Expr *initializer = CallExpr::createImplicit(ctx, typeExpr, {}, { });
2693+
typeCheckSynthesizedWrapperInitializer(pbd, backingVar, parentPBD,
2694+
initializer);
2695+
pbd->setInit(0, initializer);
2696+
pbd->setInitializerChecked(0);
2697+
}
2698+
2699+
if (var->getOpaqueResultTypeDecl()) {
2700+
var->diagnose(diag::opaque_type_var_no_underlying_type);
2701+
}
26972702
}
26982703

26992704
// If there is a projection property (projectedValue) in the wrapper,

test/decl/var/property_wrappers.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1972,4 +1972,4 @@ public struct NonVisibleImplicitInit {
19721972
public var wrappedValue: Bool {
19731973
return false
19741974
}
1975-
}
1975+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// RUN: %target-typecheck-verify-swift -swift-version 5 -disable-availability-checking
2+
3+
protocol P { }
4+
5+
@propertyWrapper
6+
struct WrapperWithDefaultInit<T> {
7+
private var stored: T?
8+
9+
var wrappedValue: T {
10+
get { stored! }
11+
set { stored = newValue }
12+
}
13+
14+
init() {
15+
self.stored = nil
16+
}
17+
}
18+
19+
// FB7699647 - crash with opaque result type and property wrappers.
20+
struct FB7699647 {
21+
@WrapperWithDefaultInit var property: some P // expected-error{{property declares an opaque return type, but cannot infer the underlying type from its initializer expression}}
22+
@WrapperWithDefaultInit() var otherProperty: some P // expected-error{{property declares an opaque return type, but cannot infer the underlying type from its initializer expression}}
23+
}
24+
25+
struct FB7699647b {
26+
@WrapperWithDefaultInit var property: some P // expected-error{{property declares an opaque return type, but cannot infer the underlying type from its initializer expression}}
27+
}

0 commit comments

Comments
 (0)