Skip to content

Commit 1ed5794

Browse files
authored
Merge pull request #29322 from xedin/delay-closure-constraint-generation-is-some-cases
[ConstraintSystem] Delay closure body constraint generation in a coup…
2 parents 3322f6d + 2b8c002 commit 1ed5794

File tree

3 files changed

+21
-5
lines changed

3 files changed

+21
-5
lines changed

lib/Sema/CSBindings.cpp

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,8 @@ bool ConstraintSystem::PotentialBindings::isViable(
228228
return true;
229229
}
230230

231-
bool ConstraintSystem::PotentialBindings::favoredOverDisjunction() const {
231+
bool ConstraintSystem::PotentialBindings::favoredOverDisjunction(
232+
Constraint *disjunction) const {
232233
if (IsHole || FullyBound)
233234
return false;
234235

@@ -238,8 +239,15 @@ bool ConstraintSystem::PotentialBindings::favoredOverDisjunction() const {
238239
// but we still want to resolve closure body early (instead of
239240
// attempting any disjunction) to gain additional contextual
240241
// 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+
}
243251

244252
return !InvolvesTypeVariables;
245253
}
@@ -559,6 +567,14 @@ ConstraintSystem::getPotentialBindings(TypeVariableType *typeVar) const {
559567
// FIXME: Recurse into these constraints to see whether this
560568
// type variable is fully bound by any of them.
561569
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+
562578
break;
563579

564580
case ConstraintKind::ConformsTo:

lib/Sema/CSStep.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -330,7 +330,7 @@ StepResult ComponentStep::take(bool prevFailed) {
330330
auto bestBindings = CS.determineBestBindings();
331331

332332
if (bestBindings &&
333-
(!disjunction || bestBindings->favoredOverDisjunction())) {
333+
(!disjunction || bestBindings->favoredOverDisjunction(disjunction))) {
334334
// Produce a type variable step.
335335
return suspend(
336336
llvm::make_unique<TypeVariableStep>(CS, *bestBindings, Solutions));

lib/Sema/ConstraintSystem.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3817,7 +3817,7 @@ class ConstraintSystem {
38173817

38183818
/// Check if this binding is favored over a disjunction e.g.
38193819
/// if it has only concrete types or would resolve a closure.
3820-
bool favoredOverDisjunction() const;
3820+
bool favoredOverDisjunction(Constraint *disjunction) const;
38213821

38223822
void dump(llvm::raw_ostream &out,
38233823
unsigned indent = 0) const LLVM_ATTRIBUTE_USED {

0 commit comments

Comments
 (0)