@@ -228,7 +228,8 @@ bool ConstraintSystem::PotentialBindings::isViable(
228
228
return true ;
229
229
}
230
230
231
- bool ConstraintSystem::PotentialBindings::favoredOverDisjunction () const {
231
+ bool ConstraintSystem::PotentialBindings::favoredOverDisjunction (
232
+ Constraint *disjunction) const {
232
233
if (IsHole || FullyBound)
233
234
return false ;
234
235
@@ -238,8 +239,15 @@ bool ConstraintSystem::PotentialBindings::favoredOverDisjunction() const {
238
239
// but we still want to resolve closure body early (instead of
239
240
// attempting any disjunction) to gain additional contextual
240
241
// information.
241
- if (TypeVar->getImpl ().isClosureType ())
242
- return true ;
242
+ if (TypeVar->getImpl ().isClosureType ()) {
243
+ auto boundType = disjunction->getNestedConstraints ()[0 ]->getFirstType ();
244
+ // If disjunction is attempting to bind a type variable, let's
245
+ // favor closure because it would add additional context, otherwise
246
+ // if it's something like a collection (where it has to pick
247
+ // between a conversion and bridging conversion) or concrete
248
+ // type let's prefer the disjunction.
249
+ return boundType->is <TypeVariableType>();
250
+ }
243
251
244
252
return !InvolvesTypeVariables;
245
253
}
@@ -559,6 +567,14 @@ ConstraintSystem::getPotentialBindings(TypeVariableType *typeVar) const {
559
567
// FIXME: Recurse into these constraints to see whether this
560
568
// type variable is fully bound by any of them.
561
569
result.InvolvesTypeVariables = true ;
570
+
571
+ // If there is additional context available via disjunction
572
+ // associated with closure literal (e.g. coercion to some other
573
+ // type) let's delay resolving the closure until the disjunction
574
+ // is attempted.
575
+ if (typeVar->getImpl ().isClosureType ())
576
+ return {typeVar};
577
+
562
578
break ;
563
579
564
580
case ConstraintKind::ConformsTo:
0 commit comments