Skip to content

Commit 71cd85c

Browse files
authored
Merge pull request #36611 from hborla/property-wrapper-csgen-crash
[ConstraintSystem] Fix a property wrapper constraint generation crash.
2 parents 86c9e87 + d232465 commit 71cd85c

File tree

2 files changed

+31
-19
lines changed

2 files changed

+31
-19
lines changed

lib/Sema/CSGen.cpp

Lines changed: 14 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3572,9 +3572,7 @@ static bool generateWrappedPropertyTypeConstraints(
35723572
Type propertyType) {
35733573
auto dc = wrappedVar->getInnermostDeclContext();
35743574

3575-
Type wrapperType = LValueType::get(initializerType);
35763575
Type wrappedValueType;
3577-
35783576
auto wrapperAttributes = wrappedVar->getAttachedPropertyWrappers();
35793577
for (unsigned i : indices(wrapperAttributes)) {
35803578
// FIXME: We should somehow pass an OpenUnboundGenericTypeFn to
@@ -3585,16 +3583,20 @@ static bool generateWrappedPropertyTypeConstraints(
35853583
if (rawWrapperType->hasError() || !wrapperInfo)
35863584
return true;
35873585

3588-
// The former wrappedValue type must be equal to the current wrapper type
3589-
if (wrappedValueType) {
3590-
auto *typeRepr = wrapperAttributes[i]->getTypeRepr();
3591-
auto *locator =
3592-
cs.getConstraintLocator(typeRepr, LocatorPathElt::ContextualType());
3593-
wrapperType = cs.replaceInferableTypesWithTypeVars(rawWrapperType,
3594-
locator);
3586+
auto *typeExpr = wrapperAttributes[i]->getTypeExpr();
3587+
auto *locator = cs.getConstraintLocator(typeExpr);
3588+
auto wrapperType = cs.replaceInferableTypesWithTypeVars(rawWrapperType, locator);
3589+
cs.setType(typeExpr, wrapperType);
3590+
3591+
if (!wrappedValueType) {
3592+
// Equate the outermost wrapper type to the initializer type.
3593+
if (initializerType)
3594+
cs.addConstraint(ConstraintKind::Equal, wrapperType, initializerType, locator);
3595+
} else {
3596+
// The former wrappedValue type must be equal to the current wrapper type
35953597
cs.addConstraint(ConstraintKind::Equal, wrapperType, wrappedValueType,
3596-
locator);
3597-
cs.setContextualType(typeRepr, TypeLoc::withoutLoc(wrappedValueType),
3598+
cs.getConstraintLocator(locator, LocatorPathElt::ContextualType()));
3599+
cs.setContextualType(typeExpr, TypeLoc::withoutLoc(wrappedValueType),
35983600
CTP_ComposedPropertyWrapper);
35993601
}
36003602

@@ -3900,19 +3902,12 @@ bool ConstraintSystem::generateConstraints(
39003902

39013903
case SolutionApplicationTarget::Kind::uninitializedWrappedVar: {
39023904
auto *wrappedVar = target.getAsUninitializedWrappedVar();
3903-
auto *outermostWrapper = wrappedVar->getAttachedPropertyWrappers().front();
3904-
auto *typeExpr = outermostWrapper->getTypeExpr();
3905-
auto backingType = replaceInferableTypesWithTypeVars(
3906-
outermostWrapper->getType(),getConstraintLocator(typeExpr));
3907-
3908-
setType(typeExpr, backingType);
3909-
39103905
auto propertyType = getVarType(wrappedVar);
39113906
if (propertyType->hasError())
39123907
return true;
39133908

39143909
return generateWrappedPropertyTypeConstraints(
3915-
*this, backingType, wrappedVar, propertyType);
3910+
*this, /*initializerType=*/Type(), wrappedVar, propertyType);
39163911
}
39173912
}
39183913
}

test/decl/var/property_wrappers.swift

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2076,3 +2076,20 @@ struct OptionalWrapper<T> {
20762076
struct UseOptionalWrapper {
20772077
@OptionalWrapper var p: Int?? // Okay
20782078
}
2079+
2080+
@propertyWrapper
2081+
struct WrapperWithFailableInit<Value> {
2082+
var wrappedValue: Value
2083+
2084+
init(_ base: WrapperWithFailableInit<Value>) { fatalError() }
2085+
2086+
init?(_ base: WrapperWithFailableInit<Value?>) { fatalError() }
2087+
}
2088+
2089+
struct TestInitError {
2090+
// FIXME: bad diagnostics when a wrapper does not support init from wrapped value
2091+
2092+
// expected-error@+2 {{extraneous argument label 'wrappedValue:' in call}}
2093+
// expected-error@+1 {{cannot convert value of type 'Int' to specified type 'WrapperWithFailableInit<Int>'}}
2094+
@WrapperWithFailableInit var value: Int = 10
2095+
}

0 commit comments

Comments
 (0)