@@ -2191,38 +2191,54 @@ namespace {
2191
2191
}
2192
2192
}
2193
2193
2194
- if (!varType)
2194
+ if (!varType) {
2195
2195
varType = CS.createTypeVariable (CS.getConstraintLocator (locator),
2196
2196
TVO_CanBindToNoEscape);
2197
2197
2198
+ // If this is either a `weak` declaration or capture e.g.
2199
+ // `weak var ...` or `[weak self]`. Let's wrap type variable
2200
+ // into an optional.
2201
+ if (optionality == ReferenceOwnershipOptionality::Required)
2202
+ varType = TypeChecker::getOptionalType (var->getLoc (), varType);
2203
+ }
2204
+
2198
2205
// When we are supposed to bind pattern variables, create a fresh
2199
2206
// type variable and a one-way constraint to assign it to either the
2200
2207
// deduced type or the externally-imposed type.
2201
2208
Type oneWayVarType;
2202
2209
if (bindPatternVarsOneWay) {
2203
2210
oneWayVarType = CS.createTypeVariable (
2204
2211
CS.getConstraintLocator (locator), TVO_CanBindToNoEscape);
2205
- CS.addConstraint (
2206
- ConstraintKind::OneWayEqual, oneWayVarType,
2207
- externalPatternType ? externalPatternType : varType, locator);
2208
- }
2209
-
2210
- // If there is an externally-imposed type.
2211
2212
2212
- switch (optionality) {
2213
- case ReferenceOwnershipOptionality::Required:
2214
- varType = TypeChecker::getOptionalType (var->getLoc (), varType);
2215
- assert (!varType->hasError ());
2213
+ // If there is an externally-imposed pattern type and the
2214
+ // binding/capture is marked as `weak`, let's make sure
2215
+ // that the imposed type is optional.
2216
+ //
2217
+ // Note that there is no need to check `varType` since
2218
+ // it's only "externally" bound if this pattern isn't marked
2219
+ // as `weak`.
2220
+ if (externalPatternType &&
2221
+ optionality == ReferenceOwnershipOptionality::Required) {
2222
+ // If the type is not yet known, let's add a constraint
2223
+ // to make sure that it can only be bound to an optional type.
2224
+ if (externalPatternType->isTypeVariableOrMember ()) {
2225
+ auto objectTy = CS.createTypeVariable (
2226
+ CS.getConstraintLocator (locator.withPathElement (
2227
+ ConstraintLocator::OptionalPayload)),
2228
+ TVO_CanBindToLValue | TVO_CanBindToNoEscape);
2216
2229
2217
- if (oneWayVarType) {
2218
- oneWayVarType =
2219
- TypeChecker::getOptionalType (var->getLoc (), oneWayVarType);
2230
+ CS.addConstraint (ConstraintKind::OptionalObject,
2231
+ externalPatternType, objectTy, locator);
2232
+ } else if (!externalPatternType->getOptionalObjectType ()) {
2233
+ // TODO(diagnostics): A tailored fix to indiciate that `weak`
2234
+ // should have an optional type.
2235
+ return Type ();
2236
+ }
2220
2237
}
2221
- break ;
2222
2238
2223
- case ReferenceOwnershipOptionality::Allowed:
2224
- case ReferenceOwnershipOptionality::Disallowed:
2225
- break ;
2239
+ CS. addConstraint (ConstraintKind::OneWayEqual, oneWayVarType,
2240
+ externalPatternType ? externalPatternType : varType,
2241
+ locator) ;
2226
2242
}
2227
2243
2228
2244
// If we have a type to ascribe to the variable, do so now.
0 commit comments