Skip to content

Commit 38d25e9

Browse files
committed
[CSBindings] Refactor handling of disjunction and member constraints
Use `DelayedBy` in more places: - If type variable is associated with a disjunction constraint let's mark it as been delayed by it (until the disjunction is actually attempted); - Type variable is "delayed" by presence of member constraint (of any kind) only if it stands for a member type. Such type variable would be resolved once the member constraint is simplified.
1 parent 9df8375 commit 38d25e9

File tree

1 file changed

+21
-20
lines changed

1 file changed

+21
-20
lines changed

lib/Sema/CSBindings.cpp

Lines changed: 21 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -883,7 +883,6 @@ ConstraintSystem::getPotentialBindingForRelationalConstraint(
883883
// of bindings for them until closure's body is opened.
884884
if (auto *typeVar = first->getAs<TypeVariableType>()) {
885885
if (typeVar->getImpl().isClosureType()) {
886-
result.InvolvesTypeVariables = true;
887886
result.DelayedBy.push_back(constraint);
888887
return None;
889888
}
@@ -1140,17 +1139,14 @@ bool ConstraintSystem::PotentialBindings::infer(
11401139
break;
11411140

11421141
case ConstraintKind::Disjunction:
1143-
// FIXME: Recurse into these constraints to see whether this
1144-
// type variable is fully bound by any of them.
1145-
InvolvesTypeVariables = true;
1146-
11471142
// If there is additional context available via disjunction
11481143
// associated with closure literal (e.g. coercion to some other
11491144
// type) let's delay resolving the closure until the disjunction
11501145
// is attempted.
11511146
if (TypeVar->getImpl().isClosureType())
11521147
return true;
11531148

1149+
DelayedBy.push_back(constraint);
11541150
break;
11551151

11561152
case ConstraintKind::ConformsTo:
@@ -1188,25 +1184,30 @@ bool ConstraintSystem::PotentialBindings::infer(
11881184

11891185
case ConstraintKind::ValueMember:
11901186
case ConstraintKind::UnresolvedValueMember:
1191-
case ConstraintKind::ValueWitness:
1192-
// If our type variable shows up in the base type, there's
1193-
// nothing to do.
1194-
// FIXME: Can we avoid simplification here?
1195-
if (ConstraintSystem::typeVarOccursInType(
1196-
TypeVar, cs.simplifyType(constraint->getFirstType()),
1197-
&InvolvesTypeVariables)) {
1198-
return false;
1187+
case ConstraintKind::ValueWitness: {
1188+
// If current type variable represents a member type of some reference,
1189+
// it would be bound once member is resolved either to a actual member
1190+
// type or to a hole if member couldn't be found.
1191+
auto memberTy = constraint->getSecondType()->castTo<TypeVariableType>();
1192+
1193+
if (memberTy->getImpl().hasRepresentativeOrFixed()) {
1194+
if (auto type = memberTy->getImpl().getFixedType(/*record=*/nullptr)) {
1195+
// It's possible that member has been bound to some other type variable
1196+
// instead of merged with it because it's wrapped in an l-value type.
1197+
if (type->getWithoutSpecifierType()->isEqual(TypeVar)) {
1198+
DelayedBy.push_back(constraint);
1199+
break;
1200+
}
1201+
} else {
1202+
memberTy = memberTy->getImpl().getRepresentative(/*record=*/nullptr);
1203+
}
11991204
}
12001205

1201-
// If the type variable is in the list of member type
1202-
// variables, it is fully bound.
1203-
// FIXME: Can we avoid simplification here?
1204-
if (ConstraintSystem::typeVarOccursInType(
1205-
TypeVar, cs.simplifyType(constraint->getSecondType()),
1206-
&InvolvesTypeVariables)) {
1206+
if (memberTy == TypeVar)
12071207
DelayedBy.push_back(constraint);
1208-
}
1208+
12091209
break;
1210+
}
12101211

12111212
case ConstraintKind::OneWayEqual:
12121213
case ConstraintKind::OneWayBindParam: {

0 commit comments

Comments
 (0)