Skip to content

Commit d232465

Browse files
committed
[ConstraintSystem] Fix a property wrapper constraint generation crash.
1 parent 6f4b62a commit d232465

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
@@ -3560,9 +3560,7 @@ static bool generateWrappedPropertyTypeConstraints(
35603560
Type propertyType) {
35613561
auto dc = wrappedVar->getInnermostDeclContext();
35623562

3563-
Type wrapperType = LValueType::get(initializerType);
35643563
Type wrappedValueType;
3565-
35663564
auto wrapperAttributes = wrappedVar->getAttachedPropertyWrappers();
35673565
for (unsigned i : indices(wrapperAttributes)) {
35683566
// FIXME: We should somehow pass an OpenUnboundGenericTypeFn to
@@ -3573,16 +3571,20 @@ static bool generateWrappedPropertyTypeConstraints(
35733571
if (rawWrapperType->hasError() || !wrapperInfo)
35743572
return true;
35753573

3576-
// The former wrappedValue type must be equal to the current wrapper type
3577-
if (wrappedValueType) {
3578-
auto *typeRepr = wrapperAttributes[i]->getTypeRepr();
3579-
auto *locator =
3580-
cs.getConstraintLocator(typeRepr, LocatorPathElt::ContextualType());
3581-
wrapperType = cs.replaceInferableTypesWithTypeVars(rawWrapperType,
3582-
locator);
3574+
auto *typeExpr = wrapperAttributes[i]->getTypeExpr();
3575+
auto *locator = cs.getConstraintLocator(typeExpr);
3576+
auto wrapperType = cs.replaceInferableTypesWithTypeVars(rawWrapperType, locator);
3577+
cs.setType(typeExpr, wrapperType);
3578+
3579+
if (!wrappedValueType) {
3580+
// Equate the outermost wrapper type to the initializer type.
3581+
if (initializerType)
3582+
cs.addConstraint(ConstraintKind::Equal, wrapperType, initializerType, locator);
3583+
} else {
3584+
// The former wrappedValue type must be equal to the current wrapper type
35833585
cs.addConstraint(ConstraintKind::Equal, wrapperType, wrappedValueType,
3584-
locator);
3585-
cs.setContextualType(typeRepr, TypeLoc::withoutLoc(wrappedValueType),
3586+
cs.getConstraintLocator(locator, LocatorPathElt::ContextualType()));
3587+
cs.setContextualType(typeExpr, TypeLoc::withoutLoc(wrappedValueType),
35863588
CTP_ComposedPropertyWrapper);
35873589
}
35883590

@@ -3888,19 +3890,12 @@ bool ConstraintSystem::generateConstraints(
38883890

38893891
case SolutionApplicationTarget::Kind::uninitializedWrappedVar: {
38903892
auto *wrappedVar = target.getAsUninitializedWrappedVar();
3891-
auto *outermostWrapper = wrappedVar->getAttachedPropertyWrappers().front();
3892-
auto *typeExpr = outermostWrapper->getTypeExpr();
3893-
auto backingType = replaceInferableTypesWithTypeVars(
3894-
outermostWrapper->getType(),getConstraintLocator(typeExpr));
3895-
3896-
setType(typeExpr, backingType);
3897-
38983893
auto propertyType = getVarType(wrappedVar);
38993894
if (propertyType->hasError())
39003895
return true;
39013896

39023897
return generateWrappedPropertyTypeConstraints(
3903-
*this, backingType, wrappedVar, propertyType);
3898+
*this, /*initializerType=*/Type(), wrappedVar, propertyType);
39043899
}
39053900
}
39063901
}

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)