@@ -2189,43 +2189,54 @@ namespace {
2189
2189
}
2190
2190
}
2191
2191
2192
- if (!varType)
2192
+ if (!varType) {
2193
2193
varType = CS.createTypeVariable (CS.getConstraintLocator (locator),
2194
2194
TVO_CanBindToNoEscape);
2195
2195
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
+
2196
2203
// When we are supposed to bind pattern variables, create a fresh
2197
2204
// type variable and a one-way constraint to assign it to either the
2198
2205
// deduced type or the externally-imposed type.
2199
2206
Type oneWayVarType;
2200
2207
if (bindPatternVarsOneWay) {
2201
2208
oneWayVarType = CS.createTypeVariable (
2202
2209
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.
2209
2210
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);
2218
2227
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 ();
2222
2234
}
2223
2235
}
2224
- break ;
2225
2236
2226
- case ReferenceOwnershipOptionality::Allowed:
2227
- case ReferenceOwnershipOptionality::Disallowed:
2228
- break ;
2237
+ CS. addConstraint (ConstraintKind::OneWayEqual, oneWayVarType,
2238
+ externalPatternType ? externalPatternType : varType,
2239
+ locator) ;
2229
2240
}
2230
2241
2231
2242
// If we have a type to ascribe to the variable, do so now.
0 commit comments