Skip to content

Commit d01de31

Browse files
committed
Sema: Fix another type variable leak with closures
When we type check a closure expression with inferred parameter types, we assign type variables to them. If type checking fails, we end up in FailureDiagnosis::diagnoseClosureExpr(). If there was no contextual type, we would skip the code path which nukes type variables in the closure's ParamDecls before proceeding to type check the body. Type checking of the body creates a new constraint system which would pick up the outer constraint system's type variables and blow up. Fixes <rdar://problem/39489003>.
1 parent 11b1d46 commit d01de31

File tree

2 files changed

+33
-12
lines changed

2 files changed

+33
-12
lines changed

lib/Sema/CSDiag.cpp

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6532,18 +6532,18 @@ bool FailureDiagnosis::diagnoseClosureExpr(
65326532
}
65336533

65346534
expectedResultType = fnType->getResult();
6535-
} else {
6536-
// Defend against type variables from our constraint system leaking into
6537-
// recursive constraints systems formed when checking the body of the
6538-
// closure. These typevars come into them when the body does name
6539-
// lookups against the parameter decls.
6540-
//
6541-
// Handle this by rewriting the arguments to UnresolvedType().
6542-
for (auto VD : *CE->getParameters()) {
6543-
if (VD->getType()->hasTypeVariable() || VD->getType()->hasError()) {
6544-
VD->setType(CS.getASTContext().TheUnresolvedType);
6545-
VD->setInterfaceType(VD->getType()->getInOutObjectType());
6546-
}
6535+
}
6536+
6537+
// Defend against type variables from our constraint system leaking into
6538+
// recursive constraints systems formed when checking the body of the
6539+
// closure. These typevars come into them when the body does name
6540+
// lookups against the parameter decls.
6541+
//
6542+
// Handle this by rewriting the arguments to UnresolvedType().
6543+
for (auto VD : *CE->getParameters()) {
6544+
if (VD->getType()->hasTypeVariable() || VD->getType()->hasError()) {
6545+
VD->setType(CS.getASTContext().TheUnresolvedType);
6546+
VD->setInterfaceType(VD->getType()->getInOutObjectType());
65476547
}
65486548
}
65496549

test/Constraints/closures.swift

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -690,3 +690,24 @@ func rdar37790062() {
690690
_ = S({ bzz(C1()) }, { bar() }) // expected-warning {{result of call to 'bzz' is unused}}
691691
_ = S({ faz(C2()) }, { bar() }) // expected-warning {{result of call to 'faz' is unused}}
692692
}
693+
694+
// <rdar://problem/39489003>
695+
typealias KeyedItem<K, T> = (key: K, value: T)
696+
697+
protocol Node {
698+
associatedtype T
699+
associatedtype E
700+
associatedtype K
701+
var item: E {get set}
702+
var children: [(key: K, value: T)] {get set}
703+
}
704+
705+
extension Node {
706+
func getChild(for key:K)->(key: K, value: T) {
707+
return children.first(where: { (item:KeyedItem) -> Bool in
708+
return item.key == key
709+
// expected-error@-1 {{binary operator '==' cannot be applied to operands of type '_' and 'Self.K'}}
710+
// expected-note@-2 {{overloads for '==' exist with these partially matching parameter lists:}}
711+
})
712+
}
713+
}

0 commit comments

Comments
 (0)