Skip to content

Commit 2e800f4

Browse files
committed
[Constraint system] Centralize the handling of "unsolved" returns in matchTypes.
1 parent 11b30a2 commit 2e800f4

File tree

2 files changed

+38
-50
lines changed

2 files changed

+38
-50
lines changed

lib/Sema/CSSimplify.cpp

Lines changed: 37 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1186,6 +1186,31 @@ ConstraintSystem::matchTypes(Type type1, Type type2, TypeMatchKind kind,
11861186
if (kind != TypeMatchKind::ConformsTo && desugar1->isEqual(desugar2))
11871187
return SolutionKind::Solved;
11881188

1189+
// Local function that should be used to produce the return value whenever
1190+
// this function was unable to resolve the constraint. It should be used
1191+
// within \c matchTypes() as
1192+
//
1193+
// return formUnsolvedResult();
1194+
//
1195+
// along any unsolved path. No other returns should produce
1196+
// SolutionKind::Unsolved or inspect TMF_GenerateConstraints.
1197+
auto formUnsolvedResult = [&] {
1198+
// If we're supposed to generate constraints (i.e., this is a
1199+
// newly-generated constraint), do so now.
1200+
if (flags & TMF_GenerateConstraints) {
1201+
// Add a new constraint between these types. We consider the current
1202+
// type-matching problem to the "solved" by this addition, because
1203+
// this new constraint will be solved at a later point.
1204+
// Obviously, this must not happen at the top level, or the
1205+
// algorithm would not terminate.
1206+
addConstraint(getConstraintKind(kind), type1, type2,
1207+
getConstraintLocator(locator));
1208+
return SolutionKind::Solved;
1209+
}
1210+
1211+
return SolutionKind::Unsolved;
1212+
};
1213+
11891214
// If either (or both) types are type variables, unify the type variables.
11901215
if (typeVar1 || typeVar2) {
11911216
switch (kind) {
@@ -1204,24 +1229,8 @@ ConstraintSystem::matchTypes(Type type1, Type type2, TypeMatchKind kind,
12041229
// If exactly one of the type variables can bind to an lvalue, we
12051230
// can't merge these two type variables.
12061231
if (rep1->getImpl().canBindToLValue()
1207-
!= rep2->getImpl().canBindToLValue()) {
1208-
if (flags & TMF_GenerateConstraints) {
1209-
if (kind == TypeMatchKind::BindToPointerType) {
1210-
increaseScore(ScoreKind::SK_ScalarPointerConversion);
1211-
}
1212-
1213-
// Add a new constraint between these types. We consider the current
1214-
// type-matching problem to the "solved" by this addition, because
1215-
// this new constraint will be solved at a later point.
1216-
// Obviously, this must not happen at the top level, or the
1217-
// algorithm would not terminate.
1218-
addConstraint(getConstraintKind(kind), rep1, rep2,
1219-
getConstraintLocator(locator));
1220-
return SolutionKind::Solved;
1221-
}
1222-
1223-
return SolutionKind::Unsolved;
1224-
}
1232+
!= rep2->getImpl().canBindToLValue())
1233+
return formUnsolvedResult();
12251234

12261235
// Merge the equivalence classes corresponding to these two variables.
12271236
mergeEquivalenceClasses(rep1, rep2);
@@ -1254,8 +1263,7 @@ ConstraintSystem::matchTypes(Type type1, Type type2, TypeMatchKind kind,
12541263

12551264
// A constraint that binds any pointer to a void pointer is
12561265
// ineffective, since any pointer can be converted to a void pointer.
1257-
if (kind == TypeMatchKind::BindToPointerType && desugar2->isVoid() &&
1258-
(flags & TMF_GenerateConstraints)) {
1266+
if (kind == TypeMatchKind::BindToPointerType && desugar2->isVoid()) {
12591267
// Bind type1 to Void only as a last resort.
12601268
addConstraint(ConstraintKind::Defaultable, typeVar1, type2,
12611269
getConstraintLocator(locator));
@@ -1309,7 +1317,8 @@ ConstraintSystem::matchTypes(Type type1, Type type2, TypeMatchKind kind,
13091317
return SolutionKind::Solved;
13101318
}
13111319
}
1312-
return SolutionKind::Unsolved;
1320+
1321+
return formUnsolvedResult();
13131322
}
13141323

13151324
case TypeMatchKind::ArgumentTupleConversion:
@@ -1331,22 +1340,13 @@ ConstraintSystem::matchTypes(Type type1, Type type2, TypeMatchKind kind,
13311340
case TypeMatchKind::ArgumentConversion:
13321341
case TypeMatchKind::OperatorArgumentTupleConversion:
13331342
case TypeMatchKind::OperatorArgumentConversion:
1334-
if (flags & TMF_GenerateConstraints) {
1335-
// Add a new constraint between these types. We consider the current
1336-
// type-matching problem to the "solved" by this addition, because
1337-
// this new constraint will be solved at a later point.
1338-
// Obviously, this must not happen at the top level, or the algorithm
1339-
// would not terminate.
1340-
addConstraint(getConstraintKind(kind), type1, type2,
1341-
getConstraintLocator(locator));
1342-
return SolutionKind::Solved;
1343-
}
1344-
13451343
// We couldn't solve this constraint. If only one of the types is a type
13461344
// variable, perhaps we can do something with it below.
1347-
if (typeVar1 && typeVar2)
1348-
return typeVar1 == typeVar2 ? SolutionKind::Solved
1349-
: SolutionKind::Unsolved;
1345+
if (typeVar1 && typeVar2) {
1346+
if (typeVar1 == typeVar2) return SolutionKind::Solved;
1347+
1348+
return formUnsolvedResult();
1349+
}
13501350

13511351
break;
13521352
}
@@ -1363,18 +1363,7 @@ ConstraintSystem::matchTypes(Type type1, Type type2, TypeMatchKind kind,
13631363
return ::matchCallArguments(*this, kind, type1, type2, locator);
13641364
}
13651365

1366-
if (flags & TMF_GenerateConstraints) {
1367-
// Add a new constraint between these types. We consider the current
1368-
// type-matching problem to the "solved" by this addition, because
1369-
// this new constraint will be solved at a later point.
1370-
// Obviously, this must not happen at the top level, or the algorithm
1371-
// would not terminate.
1372-
addConstraint(getConstraintKind(kind), type1, type2,
1373-
getConstraintLocator(locator));
1374-
return SolutionKind::Solved;
1375-
}
1376-
1377-
return SolutionKind::Unsolved;
1366+
return formUnsolvedResult();
13781367
}
13791368

13801369
// Decompose parallel structure.
@@ -2075,8 +2064,7 @@ ConstraintSystem::matchTypes(Type type1, Type type2, TypeMatchKind kind,
20752064

20762065
if (conversionsOrFixes.empty()) {
20772066
// If one of the types is a type variable, we leave this unsolved.
2078-
if (typeVar1 || typeVar2)
2079-
return SolutionKind::Unsolved;
2067+
if (typeVar1 || typeVar2) return formUnsolvedResult();
20802068

20812069
return SolutionKind::Error;
20822070
}

lib/Sema/ConstraintGraph.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -731,7 +731,7 @@ static bool isStrictInoutSubtypeConstraint(Constraint *constraint) {
731731
if (!iot)
732732
return false;
733733

734-
return iot->getObjectType()->getAs<TypeVariableType>() == nullptr;
734+
return !iot->getObjectType()->isTypeVariableOrMember();
735735
}
736736

737737
bool ConstraintGraph::contractEdges() {

0 commit comments

Comments
 (0)