Skip to content

Commit 3b91772

Browse files
committed
[Property Wrappers] Always anchor the equality constraint between
the property type and wrapped value type at the wrapped VarDecl.
1 parent 751609c commit 3b91772

File tree

2 files changed

+28
-28
lines changed

2 files changed

+28
-28
lines changed

lib/Sema/CSGen.cpp

Lines changed: 18 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -3907,8 +3907,9 @@ static Expr *generateConstraintsFor(ConstraintSystem &cs, Expr *expr,
39073907
/// initializes the underlying storage variable.
39083908
/// \param wrappedVar The property that has a property wrapper.
39093909
/// \returns the type of the property.
3910-
static Type generateWrappedPropertyTypeConstraints(
3911-
ConstraintSystem &cs, Type initializerType, VarDecl *wrappedVar) {
3910+
static bool generateWrappedPropertyTypeConstraints(
3911+
ConstraintSystem &cs, Type initializerType, VarDecl *wrappedVar,
3912+
Type propertyType) {
39123913
auto dc = wrappedVar->getInnermostDeclContext();
39133914

39143915
Type wrapperType = LValueType::get(initializerType);
@@ -3922,7 +3923,7 @@ static Type generateWrappedPropertyTypeConstraints(
39223923
Type rawWrapperType = wrappedVar->getAttachedPropertyWrapperType(i);
39233924
auto wrapperInfo = wrappedVar->getAttachedPropertyWrapperTypeInfo(i);
39243925
if (rawWrapperType->hasError() || !wrapperInfo)
3925-
return Type();
3926+
return true;
39263927

39273928
// The former wrappedValue type must be equal to the current wrapper type
39283929
if (wrappedValueType) {
@@ -3940,12 +3941,12 @@ static Type generateWrappedPropertyTypeConstraints(
39403941
dc->getParentModule(), wrapperInfo.valueVar);
39413942
}
39423943

3943-
// Set up an equality constraint to drop the lvalue-ness of the value
3944-
// type we produced.
3945-
auto locator = cs.getConstraintLocator(wrappedVar);
3946-
Type propertyType = cs.createTypeVariable(locator, 0);
3947-
cs.addConstraint(ConstraintKind::Equal, propertyType, wrappedValueType, locator);
3948-
return propertyType;
3944+
// The property type must be equal to the wrapped value type
3945+
cs.addConstraint(ConstraintKind::Equal, propertyType, wrappedValueType,
3946+
cs.getConstraintLocator(wrappedVar, LocatorPathElt::ContextualType()));
3947+
cs.setContextualType(wrappedVar, TypeLoc::withoutLoc(wrappedValueType),
3948+
CTP_WrappedProperty);
3949+
return false;
39493950
}
39503951

39513952
/// Generate additional constraints for the pattern of an initialization.
@@ -3962,17 +3963,11 @@ static bool generateInitPatternConstraints(
39623963
if (!patternType)
39633964
return true;
39643965

3965-
if (auto wrappedVar = target.getInitializationWrappedVar()) {
3966-
Type propertyType = generateWrappedPropertyTypeConstraints(
3967-
cs, cs.getType(target.getAsExpr()), wrappedVar);
3968-
if (!propertyType)
3969-
return true;
3966+
if (auto wrappedVar = target.getInitializationWrappedVar())
3967+
return generateWrappedPropertyTypeConstraints(
3968+
cs, cs.getType(target.getAsExpr()), wrappedVar, patternType);
39703969

3971-
// Add an equal constraint between the pattern type and the
3972-
// property wrapper's "value" type.
3973-
cs.addConstraint(ConstraintKind::Equal, patternType,
3974-
propertyType, locator, /*isFavored*/ true);
3975-
} else if (!patternType->is<OpaqueTypeArchetypeType>()) {
3970+
if (!patternType->is<OpaqueTypeArchetypeType>()) {
39763971
// Add a conversion constraint between the types.
39773972
cs.addConstraint(ConstraintKind::Conversion, cs.getType(target.getAsExpr()),
39783973
patternType, locator, /*isFavored*/true);
@@ -4216,17 +4211,12 @@ bool ConstraintSystem::generateConstraints(
42164211
getConstraintLocator(typeRepr));
42174212
setType(typeRepr, backingType);
42184213

4219-
auto wrappedValueType =
4220-
generateWrappedPropertyTypeConstraints(*this, backingType, wrappedVar);
4221-
Type propertyType = wrappedVar->getType();
4222-
if (!wrappedValueType || propertyType->hasError())
4214+
auto propertyType = wrappedVar->getType();
4215+
if (propertyType->hasError())
42234216
return true;
42244217

4225-
addConstraint(ConstraintKind::Equal, propertyType, wrappedValueType,
4226-
getConstraintLocator(wrappedVar, LocatorPathElt::ContextualType()));
4227-
setContextualType(wrappedVar, TypeLoc::withoutLoc(wrappedValueType),
4228-
CTP_WrappedProperty);
4229-
return false;
4218+
return generateWrappedPropertyTypeConstraints(
4219+
*this, backingType, wrappedVar, propertyType);
42304220
}
42314221
}
42324222
}

test/decl/var/property_wrappers.swift

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2021,3 +2021,13 @@ public struct NonVisibleImplicitInit {
20212021
return false
20222022
}
20232023
}
2024+
2025+
@propertyWrapper
2026+
struct OptionalWrapper<T> {
2027+
init() {}
2028+
var wrappedValue: T? { nil }
2029+
}
2030+
2031+
struct UseOptionalWrapper {
2032+
@OptionalWrapper var p: Int?? // Okay
2033+
}

0 commit comments

Comments
 (0)