Skip to content

Commit 021349f

Browse files
authored
Merge pull request swiftlang#39162 from xedin/dont-increase-weak-let-optionality
[CSGen] Don't increase optionality of `weak var` patterns
2 parents 3c610db + b1a79df commit 021349f

File tree

2 files changed

+50
-18
lines changed

2 files changed

+50
-18
lines changed

lib/Sema/CSGen.cpp

Lines changed: 34 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2191,38 +2191,54 @@ namespace {
21912191
}
21922192
}
21932193

2194-
if (!varType)
2194+
if (!varType) {
21952195
varType = CS.createTypeVariable(CS.getConstraintLocator(locator),
21962196
TVO_CanBindToNoEscape);
21972197

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+
21982205
// When we are supposed to bind pattern variables, create a fresh
21992206
// type variable and a one-way constraint to assign it to either the
22002207
// deduced type or the externally-imposed type.
22012208
Type oneWayVarType;
22022209
if (bindPatternVarsOneWay) {
22032210
oneWayVarType = CS.createTypeVariable(
22042211
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.
22112212

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);
22162229

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+
}
22202237
}
2221-
break;
22222238

2223-
case ReferenceOwnershipOptionality::Allowed:
2224-
case ReferenceOwnershipOptionality::Disallowed:
2225-
break;
2239+
CS.addConstraint(ConstraintKind::OneWayEqual, oneWayVarType,
2240+
externalPatternType ? externalPatternType : varType,
2241+
locator);
22262242
}
22272243

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

test/Constraints/result_builder.swift

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -788,3 +788,19 @@ let ts1 = MyTupleStruct {
788788

789789
// CHECK: MyTupleStruct<(Int, String, Optional<String>), (Double, String)>(first: (Function), second: (3.14159, "blah"))
790790
print(ts1)
791+
792+
// Make sure that `weakV` is `Test?` and not `Test??`
793+
func test_weak_optionality_stays_the_same() {
794+
class Test {
795+
func fn() -> Int { 42 }
796+
}
797+
798+
tuplify(true) { c in
799+
weak var weakV: Test? = Test()
800+
801+
0
802+
if let v = weakV {
803+
v.fn()
804+
}
805+
}
806+
}

0 commit comments

Comments
 (0)