Skip to content

Commit 5eee63e

Browse files
authored
Merge pull request #33551 from DougGregor/weak-self-capture-iuo
[Constraint solver] Disable pattern type "optimization" involving weak types
2 parents 21c9c39 + 471f1ee commit 5eee63e

File tree

2 files changed

+27
-19
lines changed

2 files changed

+27
-19
lines changed

lib/Sema/CSGen.cpp

Lines changed: 10 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2189,6 +2189,12 @@ namespace {
21892189

21902190
Type varType;
21912191

2192+
// Determine whether optionality will be required.
2193+
auto ROK = ReferenceOwnership::Strong;
2194+
if (auto *OA = var->getAttrs().getAttribute<ReferenceOwnershipAttr>())
2195+
ROK = OA->get();
2196+
auto optionality = optionalityOf(ROK);
2197+
21922198
// If we have a type from an initializer expression, and that
21932199
// expression does not produce an InOut type, use it. This
21942200
// will avoid exponential typecheck behavior in the case of
@@ -2197,18 +2203,17 @@ namespace {
21972203
// FIXME: This should be handled in the solver, not here.
21982204
//
21992205
// Otherwise, create a new type variable.
2200-
bool assumedInitializerType = false;
22012206
if (!var->hasNonPatternBindingInit() &&
2202-
!var->hasAttachedPropertyWrapper()) {
2207+
!var->hasAttachedPropertyWrapper() &&
2208+
optionality != ReferenceOwnershipOptionality::Required) {
22032209
if (auto boundExpr = locator.trySimplifyToExpr()) {
22042210
if (!boundExpr->isSemanticallyInOutExpr()) {
22052211
varType = CS.getType(boundExpr)->getRValueType();
2206-
assumedInitializerType = true;
22072212
}
22082213
}
22092214
}
22102215

2211-
if (!assumedInitializerType)
2216+
if (!varType)
22122217
varType = CS.createTypeVariable(CS.getConstraintLocator(locator),
22132218
TVO_CanBindToNoEscape);
22142219

@@ -2226,22 +2231,8 @@ namespace {
22262231

22272232
// If there is an externally-imposed type.
22282233

2229-
auto ROK = ReferenceOwnership::Strong;
2230-
if (auto *OA = var->getAttrs().getAttribute<ReferenceOwnershipAttr>())
2231-
ROK = OA->get();
2232-
switch (optionalityOf(ROK)) {
2234+
switch (optionality) {
22332235
case ReferenceOwnershipOptionality::Required:
2234-
if (assumedInitializerType) {
2235-
// Already Optional<T>
2236-
if (varType->getOptionalObjectType())
2237-
break;
2238-
2239-
// Create a fresh type variable to handle overloaded expressions.
2240-
if (varType->is<TypeVariableType>())
2241-
varType = CS.createTypeVariable(CS.getConstraintLocator(locator),
2242-
TVO_CanBindToNoEscape);
2243-
}
2244-
22452236
varType = TypeChecker::getOptionalType(var->getLoc(), varType);
22462237
assert(!varType->hasError());
22472238

test/expr/closure/single_expr.swift

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,3 +104,20 @@ missionCritical(storage: { haltAndCatchFire() })
104104
enum E { }
105105
func takesAnotherUninhabitedType(e: () -> E) {}
106106
takesAnotherUninhabitedType { haltAndCatchFire() }
107+
108+
// Weak capture bug caught by rdar://problem/67351438
109+
class Y {
110+
var toggle: Bool = false
111+
112+
func doSomething(animated: Bool, completionHandler: (Int, Int) -> Void) { }
113+
}
114+
115+
class X {
116+
private(set) var someY: Y!
117+
118+
func doSomething() {
119+
someY?.doSomething(animated: true, completionHandler: { [weak someY] _, _ in
120+
someY?.toggle = true
121+
})
122+
}
123+
}

0 commit comments

Comments
 (0)