Skip to content

Commit 6236b25

Browse files
authored
[Sema] Fixes for mutability handling in property wrappers (#76357)
Prevents a crash when a parameter references an invalid property wrapper. The original code assumed that mutability information would always be available, but this assumption fails when the property wrapper is invalid Resolves #65640
1 parent 854298a commit 6236b25

File tree

2 files changed

+28
-13
lines changed

2 files changed

+28
-13
lines changed

lib/Sema/TypeCheckStorage.cpp

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2816,31 +2816,36 @@ static VarDecl *synthesizeLocalWrappedValueVar(VarDecl *var) {
28162816
}
28172817
Identifier name = ctx.getIdentifier(nameBuf);
28182818

2819-
VarDecl *localVar = new (ctx) VarDecl(/*IsStatic=*/false,
2820-
VarDecl::Introducer::Var,
2821-
var->getLoc(), name, dc);
2822-
localVar->setImplicit();
2823-
localVar->getAttrs() = var->getAttrs();
2824-
localVar->overwriteAccess(var->getFormalAccess());
2825-
2819+
std::optional<StorageImplInfo> mutability;
28262820
if (var->hasImplicitPropertyWrapper()) {
28272821
// FIXME: This can have a setter, but we need a resolved wrapper type
28282822
// to figure it out.
2829-
localVar->setImplInfo(StorageImplInfo::getImmutableComputed());
2823+
mutability.emplace(StorageImplInfo::getImmutableComputed());
28302824
} else {
2831-
auto mutability = *var->getPropertyWrapperMutability();
2832-
if (mutability.Getter == PropertyWrapperMutability::Mutating) {
2825+
auto possibleMutability = var->getPropertyWrapperMutability();
2826+
if (!possibleMutability)
2827+
return nullptr;
2828+
2829+
if (possibleMutability->Getter == PropertyWrapperMutability::Mutating) {
28332830
ctx.Diags.diagnose(var->getLoc(), diag::property_wrapper_param_mutating);
28342831
return nullptr;
28352832
}
28362833

2837-
if (mutability.Setter == PropertyWrapperMutability::Nonmutating) {
2838-
localVar->setImplInfo(StorageImplInfo::getMutableComputed());
2834+
if (possibleMutability->Setter == PropertyWrapperMutability::Nonmutating) {
2835+
mutability.emplace(StorageImplInfo::getMutableComputed());
28392836
} else {
2840-
localVar->setImplInfo(StorageImplInfo::getImmutableComputed());
2837+
mutability.emplace(StorageImplInfo::getImmutableComputed());
28412838
}
28422839
}
28432840

2841+
VarDecl *localVar = new (ctx) VarDecl(/*IsStatic=*/false,
2842+
VarDecl::Introducer::Var,
2843+
var->getLoc(), name, dc);
2844+
localVar->setImplicit();
2845+
localVar->getAttrs() = var->getAttrs();
2846+
localVar->overwriteAccess(var->getFormalAccess());
2847+
localVar->setImplInfo(*mutability);
2848+
28442849
return localVar;
28452850
}
28462851

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// RUN: %target-typecheck-verify-swift -swift-version 5 -package-name myPkg
2+
3+
// https://github.com/swiftlang/swift/issues/65640
4+
5+
@propertyWrapper
6+
struct Wrapper {
7+
// expected-error@-1{{property wrapper type 'Wrapper' does not contain a non-static property named 'wrappedValue'}}
8+
init(wrappedValue: Int) {}
9+
}
10+
func test(@Wrapper x: Int) {}

0 commit comments

Comments
 (0)