Re-enable contractions for parameter binding constraints between identical type variables.

In these cases, we should just go ahead and remove the redundant constraints:
- They don't help us derive a solution for the system
- Not doing so might leave "dangling" constraints that will make the system unsolvable
This commit is contained in:
Joe Pamer
2016-01-22 16:58:57 -08:00
parent 59a2e2aff8
commit 50749dfcd0

View File

@@ -766,12 +766,14 @@ bool ConstraintGraph::contractEdges() {
if (!(tyvar1 && tyvar2))
continue;
auto isParamBindingConstraint = kind == ConstraintKind::BindParam;
// We need to take special care not to directly contract parameter
// binding constraints if there is an inout subtype constraint on the
// type variable. The constraint solver depends on multiple constraints
// being present in this case, so it can generate the appropriate lvalue
// wrapper for the argument type.
if (kind == ConstraintKind::BindParam) {
if (isParamBindingConstraint) {
auto node = tyvar1->getImpl().getGraphNode();
auto hasDependentConstraint = false;
@@ -780,13 +782,6 @@ bool ConstraintGraph::contractEdges() {
hasDependentConstraint = true;
break;
}
// TODO: Temporarily inhibit contraction for chained param binding
// constraints. (E.g., "$0 == $0")
if (t1Constraint != constraint &&
t1Constraint->getKind() == ConstraintKind::BindParam) {
hasDependentConstraint = true;
break;
}
}
if (hasDependentConstraint)
@@ -796,11 +791,10 @@ bool ConstraintGraph::contractEdges() {
auto rep1 = CS.getRepresentative(tyvar1);
auto rep2 = CS.getRepresentative(tyvar2);
if (rep1 != rep2 &&
((rep1->getImpl().canBindToLValue() ==
if (((rep1->getImpl().canBindToLValue() ==
rep2->getImpl().canBindToLValue()) ||
// Allow l-value contractions when binding parameter types.
constraint->getKind() == ConstraintKind::BindParam)) {
isParamBindingConstraint)) {
if (CS.TC.getLangOpts().DebugConstraintSolver) {
auto &log = CS.getASTContext().TypeCheckerDebug->getStream();
if (CS.solverState)
@@ -813,7 +807,8 @@ bool ConstraintGraph::contractEdges() {
// Merge the edges and remove the constraint.
removeEdge(constraint);
CS.mergeEquivalenceClasses(rep1, rep2, /*updateWorkList*/ false);
if (rep1 != rep2)
CS.mergeEquivalenceClasses(rep1, rep2, /*updateWorkList*/ false);
didContractEdges = true;
}
}