Skip to content

Commit c0afe3f

Browse files
committed
Sema: Don't create new ConstraintGraphNode during active undo
This messes up the bookkeeping for the trail.
1 parent 4ef30a4 commit c0afe3f

File tree

4 files changed

+27
-22
lines changed

4 files changed

+27
-22
lines changed

Diff for: include/swift/Sema/CSTrail.h

+2
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,8 @@ class SolverTrail {
133133
SolverTrail(const SolverTrail &) = delete;
134134
SolverTrail &operator=(const SolverTrail &) = delete;
135135

136+
bool isUndoActive() const { return UndoActive; }
137+
136138
void recordChange(Change change);
137139

138140
void dumpActiveScopeChanges(llvm::raw_ostream &out,

Diff for: include/swift/Sema/ConstraintSystem.h

+9-5
Original file line numberDiff line numberDiff line change
@@ -521,7 +521,7 @@ class TypeVariableType::Implementation {
521521
impl = &nextTV->getImpl();
522522
}
523523

524-
if (impl == this || !trail)
524+
if (impl == this || !trail || trail->isUndoActive())
525525
return result;
526526

527527
// Perform path compression.
@@ -2659,10 +2659,6 @@ class ConstraintSystem {
26592659
favoredConstraints.push_back(constraint);
26602660
}
26612661

2662-
void recordChange(SolverTrail::Change change) {
2663-
Trail.recordChange(change);
2664-
}
2665-
26662662
private:
26672663
/// The list of constraints that have been retired along the
26682664
/// current path, this list is used in LIFO fashion when
@@ -2798,6 +2794,14 @@ class ConstraintSystem {
27982794
/// we're exploring.
27992795
SolverState *solverState = nullptr;
28002796

2797+
bool isRecordingChanges() const {
2798+
return solverState && !solverState->Trail.isUndoActive();
2799+
}
2800+
2801+
void recordChange(SolverTrail::Change change) {
2802+
solverState->Trail.recordChange(change);
2803+
}
2804+
28012805
/// Form a locator that can be used to retrieve argument information cached in
28022806
/// the constraint system for the callee described by the anchor of the
28032807
/// passed locator.

Diff for: lib/Sema/CSTrail.cpp

+1-3
Original file line numberDiff line numberDiff line change
@@ -194,9 +194,7 @@ void SolverTrail::Change::dump(llvm::raw_ostream &out,
194194
}
195195

196196
void SolverTrail::recordChange(Change change) {
197-
if (UndoActive)
198-
return;
199-
197+
ASSERT(!UndoActive);
200198
Changes.push_back(change);
201199
}
202200

Diff for: lib/Sema/ConstraintGraph.cpp

+15-14
Original file line numberDiff line numberDiff line change
@@ -79,9 +79,12 @@ ConstraintGraph::lookupNode(TypeVariableType *typeVar) {
7979
// Record this type variable.
8080
TypeVariables.push_back(typeVar);
8181

82-
// Record the change, if there are active scopes.
82+
// Record the change, if there are active scopes. Note that we specifically
83+
// check CS.solverState and not CS.isRecordingChanges(), because we want
84+
// recordChange() to assert if there's an active undo. It is not valid to
85+
// create new nodes during an undo.
8386
if (CS.solverState)
84-
CS.solverState->recordChange(SolverTrail::Change::addedTypeVariable(typeVar));
87+
CS.recordChange(SolverTrail::Change::addedTypeVariable(typeVar));
8588

8689
// If this type variable is not the representative of its equivalence class,
8790
// add it to its representative's set of equivalences.
@@ -475,8 +478,8 @@ void ConstraintGraph::addConstraint(Constraint *constraint) {
475478
}
476479

477480
// Record the change, if there are active scopes.
478-
if (CS.solverState)
479-
CS.solverState->recordChange(SolverTrail::Change::addedConstraint(constraint));
481+
if (CS.isRecordingChanges())
482+
CS.recordChange(SolverTrail::Change::addedConstraint(constraint));
480483
}
481484

482485
void ConstraintGraph::removeConstraint(Constraint *constraint) {
@@ -501,8 +504,8 @@ void ConstraintGraph::removeConstraint(Constraint *constraint) {
501504
}
502505

503506
// Record the change, if there are active scopes.
504-
if (CS.solverState)
505-
CS.solverState->recordChange(SolverTrail::Change::removedConstraint(constraint));
507+
if (CS.isRecordingChanges())
508+
CS.recordChange(SolverTrail::Change::removedConstraint(constraint));
506509
}
507510

508511
void ConstraintGraph::mergeNodes(TypeVariableType *typeVar1,
@@ -520,8 +523,8 @@ void ConstraintGraph::mergeNodes(TypeVariableType *typeVar1,
520523
auto typeVarNonRep = typeVar1 == typeVarRep? typeVar2 : typeVar1;
521524

522525
// Record the change, if there are active scopes.
523-
if (CS.solverState) {
524-
CS.solverState->recordChange(
526+
if (CS.isRecordingChanges()) {
527+
CS.recordChange(
525528
SolverTrail::Change::extendedEquivalenceClass(
526529
typeVarRep,
527530
repNode.getEquivalenceClass().size()));
@@ -536,12 +539,6 @@ void ConstraintGraph::bindTypeVariable(TypeVariableType *typeVar, Type fixed) {
536539
assert(!fixed->is<TypeVariableType>() &&
537540
"Cannot bind to type variable; merge equivalence classes instead");
538541

539-
// Record the change, if there are active scopes.
540-
if (CS.solverState) {
541-
CS.solverState->recordChange(
542-
SolverTrail::Change::boundTypeVariable(typeVar, fixed));
543-
}
544-
545542
auto &node = (*this)[typeVar];
546543

547544
llvm::SmallPtrSet<TypeVariableType *, 4> referencedVars;
@@ -556,6 +553,10 @@ void ConstraintGraph::bindTypeVariable(TypeVariableType *typeVar, Type fixed) {
556553
otherNode.addReferencedBy(typeVar);
557554
node.addReferencedVar(otherTypeVar);
558555
}
556+
557+
// Record the change, if there are active scopes.
558+
if (CS.isRecordingChanges())
559+
CS.recordChange(SolverTrail::Change::boundTypeVariable(typeVar, fixed));
559560
}
560561

561562
void ConstraintGraph::unbindTypeVariable(TypeVariableType *typeVar, Type fixed) {

0 commit comments

Comments
 (0)