Skip to content

Commit db6d6e3

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 7685c18 commit db6d6e3

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
@@ -6355,10 +6355,12 @@ Type ParamDecl::getVarargBaseTy(Type VarArgT) {
63556355

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

lib/Sema/TypeCheckDeclPrimary.cpp

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

30283028
auto *SF = param->getDeclContext()->getParentSourceFile();
3029-
param->visitAuxiliaryDecls([&](VarDecl *auxiliaryDecl) {
3030-
if (!isa<ParamDecl>(auxiliaryDecl))
3031-
DeclChecker(param->getASTContext(), SF).visitBoundVariable(auxiliaryDecl);
3032-
});
3029+
if (!param->isInvalid()) {
3030+
param->visitAuxiliaryDecls([&](VarDecl *auxiliaryDecl) {
3031+
if (!isa<ParamDecl>(auxiliaryDecl))
3032+
DeclChecker(param->getASTContext(), SF).visitBoundVariable(auxiliaryDecl);
3033+
});
3034+
}
30333035
}
30343036

30353037
// 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)