Skip to content

Commit 0248250

Browse files
committed
[Property Wrappers] Fix a diagnostic crash when a parameter has a wrapped value
mismatch. If there's an error in property wrapper application, the backing property wrapper type request will return a null type, which would cause the compiler to crash because most error recovery code expects ErrorType. If the wrapper application has an error, use the interface type of the parameter instead.
1 parent 9df8944 commit 0248250

File tree

3 files changed

+23
-7
lines changed

3 files changed

+23
-7
lines changed

lib/AST/Decl.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6354,10 +6354,12 @@ Type ParamDecl::getVarargBaseTy(Type VarArgT) {
63546354

63556355
AnyFunctionType::Param ParamDecl::toFunctionParam(Type type) const {
63566356
if (!type) {
6357+
type = getInterfaceType();
6358+
63576359
if (hasExternalPropertyWrapper()) {
6358-
type = getPropertyWrapperBackingPropertyType();
6359-
} else {
6360-
type = getInterfaceType();
6360+
if (auto wrapper = getPropertyWrapperBackingPropertyType()) {
6361+
type = wrapper;
6362+
}
63616363
}
63626364
}
63636365

lib/Sema/TypeCheckDeclPrimary.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3034,10 +3034,12 @@ void TypeChecker::checkParameterList(ParameterList *params,
30343034
(void) param->getPropertyWrapperInitializerInfo();
30353035

30363036
auto *SF = param->getDeclContext()->getParentSourceFile();
3037-
param->visitAuxiliaryDecls([&](VarDecl *auxiliaryDecl) {
3038-
if (!isa<ParamDecl>(auxiliaryDecl))
3039-
DeclChecker(param->getASTContext(), SF).visitBoundVariable(auxiliaryDecl);
3040-
});
3037+
if (!param->isInvalid()) {
3038+
param->visitAuxiliaryDecls([&](VarDecl *auxiliaryDecl) {
3039+
if (!isa<ParamDecl>(auxiliaryDecl))
3040+
DeclChecker(param->getASTContext(), SF).visitBoundVariable(auxiliaryDecl);
3041+
});
3042+
}
30413043
}
30423044

30433045
// For source compatibilty, allow duplicate internal parameter names

test/Sema/property_wrapper_parameter_invalid.swift

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,3 +187,15 @@ func testMissingWrapperType() {
187187
return
188188
}
189189
}
190+
191+
@propertyWrapper
192+
struct OptionalWrapper<Value> { // expected-note {{'Value' declared as parameter to type 'OptionalWrapper'}}
193+
var wrappedValue: Value?
194+
var projectedValue: Self { self }
195+
init(wrappedValue: Value?) { self.wrappedValue = wrappedValue }
196+
init(projectedValue: Self) { self = projectedValue }
197+
}
198+
199+
// expected-error@+2 {{generic parameter 'Value' could not be inferred}} expected-note@+2 {{}}
200+
// expected-error@+1 {{property type 'Int' does not match 'wrappedValue' type 'Value?'}}
201+
func testWrappedValueMismatch(@OptionalWrapper value: Int) {}

0 commit comments

Comments
 (0)