Skip to content

Commit b1a79df

Browse files
committed
[CSGen] Refactor weak declaration/capture optionality enforcement
- Make sure that `varType` is wrapped into an optional type for `weak` declarations. - Verify that `externalPatternType` is an optional type when one-way constraints are requested.
1 parent e8a89cc commit b1a79df

File tree

1 file changed

+33
-22
lines changed

1 file changed

+33
-22
lines changed

lib/Sema/CSGen.cpp

Lines changed: 33 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2189,43 +2189,54 @@ namespace {
21892189
}
21902190
}
21912191

2192-
if (!varType)
2192+
if (!varType) {
21932193
varType = CS.createTypeVariable(CS.getConstraintLocator(locator),
21942194
TVO_CanBindToNoEscape);
21952195

2196+
// If this is either a `weak` declaration or capture e.g.
2197+
// `weak var ...` or `[weak self]`. Let's wrap type variable
2198+
// into an optional.
2199+
if (optionality == ReferenceOwnershipOptionality::Required)
2200+
varType = TypeChecker::getOptionalType(var->getLoc(), varType);
2201+
}
2202+
21962203
// When we are supposed to bind pattern variables, create a fresh
21972204
// type variable and a one-way constraint to assign it to either the
21982205
// deduced type or the externally-imposed type.
21992206
Type oneWayVarType;
22002207
if (bindPatternVarsOneWay) {
22012208
oneWayVarType = CS.createTypeVariable(
22022209
CS.getConstraintLocator(locator), TVO_CanBindToNoEscape);
2203-
CS.addConstraint(
2204-
ConstraintKind::OneWayEqual, oneWayVarType,
2205-
externalPatternType ? externalPatternType : varType, locator);
2206-
}
2207-
2208-
// If there is an externally-imposed type.
22092210

2210-
switch (optionality) {
2211-
case ReferenceOwnershipOptionality::Required:
2212-
// If the externally-imposed type is already optional,
2213-
// let's not add optionality to the pattern.
2214-
if (!externalPatternType ||
2215-
!externalPatternType->getOptionalObjectType()) {
2216-
varType = TypeChecker::getOptionalType(var->getLoc(), varType);
2217-
assert(!varType->hasError());
2211+
// If there is an externally-imposed pattern type and the
2212+
// binding/capture is marked as `weak`, let's make sure
2213+
// that the imposed type is optional.
2214+
//
2215+
// Note that there is no need to check `varType` since
2216+
// it's only "externally" bound if this pattern isn't marked
2217+
// as `weak`.
2218+
if (externalPatternType &&
2219+
optionality == ReferenceOwnershipOptionality::Required) {
2220+
// If the type is not yet known, let's add a constraint
2221+
// to make sure that it can only be bound to an optional type.
2222+
if (externalPatternType->isTypeVariableOrMember()) {
2223+
auto objectTy = CS.createTypeVariable(
2224+
CS.getConstraintLocator(locator.withPathElement(
2225+
ConstraintLocator::OptionalPayload)),
2226+
TVO_CanBindToLValue | TVO_CanBindToNoEscape);
22182227

2219-
if (oneWayVarType) {
2220-
oneWayVarType =
2221-
TypeChecker::getOptionalType(var->getLoc(), oneWayVarType);
2228+
CS.addConstraint(ConstraintKind::OptionalObject,
2229+
externalPatternType, objectTy, locator);
2230+
} else if (!externalPatternType->getOptionalObjectType()) {
2231+
// TODO(diagnostics): A tailored fix to indiciate that `weak`
2232+
// should have an optional type.
2233+
return Type();
22222234
}
22232235
}
2224-
break;
22252236

2226-
case ReferenceOwnershipOptionality::Allowed:
2227-
case ReferenceOwnershipOptionality::Disallowed:
2228-
break;
2237+
CS.addConstraint(ConstraintKind::OneWayEqual, oneWayVarType,
2238+
externalPatternType ? externalPatternType : varType,
2239+
locator);
22292240
}
22302241

22312242
// If we have a type to ascribe to the variable, do so now.

0 commit comments

Comments
 (0)