Skip to content

Commit f3588c9

Browse files
committed
Sema: Fix ordering of constraint graph updates vs fixed type assignment
1 parent a0d12a2 commit f3588c9

File tree

3 files changed

+46
-6
lines changed

3 files changed

+46
-6
lines changed

include/swift/Sema/ConstraintGraph.h

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -137,10 +137,12 @@ class ConstraintGraphNode {
137137
/// gets removed for a constraint graph.
138138
void retractFromInference(Constraint *constraint);
139139

140+
/// Perform graph updates that must be undone after we bind a fixed type
141+
/// to a type variable.
142+
void retractFromInference(Type fixedType);
140143

141-
/// Similar to \c introduceToInference(Constraint *, ...) this method is going
142-
/// to notify inference that this type variable has been bound to a concrete
143-
/// type.
144+
/// Perform graph updates that must be undone before we bind a fixed type
145+
/// to a type variable.
144146
///
145147
/// The reason why this can't simplify be a part of \c bindTypeVariable
146148
/// is related to the fact that it's sometimes expensive to re-compute
@@ -268,7 +270,12 @@ class ConstraintGraph {
268270
/// Bind the given type variable to the given fixed type.
269271
void bindTypeVariable(TypeVariableType *typeVar, Type fixedType);
270272

271-
/// Introduce the type variable's fixed type to inference.
273+
/// Perform graph updates that must be undone after we bind a fixed type
274+
/// to a type variable.
275+
void retractFromInference(TypeVariableType *typeVar, Type fixedType);
276+
277+
/// Perform graph updates that must be undone before we bind a fixed type
278+
/// to a type variable.
272279
void introduceToInference(TypeVariableType *typeVar, Type fixedType);
273280

274281
/// Describes which constraints \c gatherConstraints should gather.

lib/Sema/ConstraintGraph.cpp

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -352,6 +352,36 @@ void ConstraintGraphNode::retractFromInference(Constraint *constraint) {
352352
}
353353
}
354354

355+
void ConstraintGraphNode::retractFromInference(Type fixedType) {
356+
// Notify all of the type variables that reference this one.
357+
//
358+
// Since this type variable has been replaced with a fixed type
359+
// all of the concrete types that reference it are going to change,
360+
// which means that all of the not-yet-attempted bindings should
361+
// change as well.
362+
notifyReferencingVars(
363+
[&](ConstraintGraphNode &node, Constraint *constraint) {
364+
node.retractFromInference(constraint);
365+
});
366+
367+
if (!fixedType->hasTypeVariable())
368+
return;
369+
370+
SmallPtrSet<TypeVariableType *, 4> referencedVars;
371+
fixedType->getTypeVariables(referencedVars);
372+
373+
for (auto *referencedVar : referencedVars) {
374+
auto &node = CG[referencedVar];
375+
376+
// Newly referred vars need to re-introduce all constraints associated
377+
// with this type variable since they are now going to be used in
378+
// all of the constraints that reference bound type variable.
379+
for (auto *constraint : getConstraints()) {
380+
if (isUsefulForReferencedVars(constraint))
381+
node.retractFromInference(constraint);
382+
}
383+
}
384+
}
355385

356386
void ConstraintGraphNode::introduceToInference(Type fixedType) {
357387
// Notify all of the type variables that reference this one.
@@ -362,7 +392,6 @@ void ConstraintGraphNode::introduceToInference(Type fixedType) {
362392
// change as well.
363393
notifyReferencingVars(
364394
[&](ConstraintGraphNode &node, Constraint *constraint) {
365-
node.retractFromInference(constraint);
366395
node.introduceToInference(constraint);
367396
});
368397

@@ -380,7 +409,6 @@ void ConstraintGraphNode::introduceToInference(Type fixedType) {
380409
// all of the constraints that reference bound type variable.
381410
for (auto *constraint : getConstraints()) {
382411
if (isUsefulForReferencedVars(constraint)) {
383-
node.retractFromInference(constraint);
384412
node.introduceToInference(constraint);
385413
}
386414
}
@@ -548,6 +576,10 @@ void ConstraintGraph::bindTypeVariable(TypeVariableType *typeVar, Type fixed) {
548576
}
549577
}
550578

579+
void ConstraintGraph::retractFromInference(TypeVariableType *typeVar, Type fixed) {
580+
(*this)[typeVar].retractFromInference(fixed);
581+
}
582+
551583
void ConstraintGraph::introduceToInference(TypeVariableType *typeVar, Type fixed) {
552584
(*this)[typeVar].introduceToInference(fixed);
553585
}

lib/Sema/ConstraintSystem.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,7 @@ void ConstraintSystem::assignFixedType(TypeVariableType *typeVar, Type type,
203203
assert(!type->hasError() &&
204204
"Should not be assigning a type involving ErrorType!");
205205

206+
CG.retractFromInference(typeVar, type);
206207
typeVar->getImpl().assignFixedType(type, getTrail());
207208

208209
if (!updateState)

0 commit comments

Comments
 (0)