Sema: Rework change recording in PotentialBindings::retract()

Instead of making an undo() do an infer(), let's record fine-grained
changes about what was retracted, and directly re-insert the same
elements into the data structures.
This commit is contained in:
Slava Pestov
2025-02-04 17:53:26 -05:00
parent b09c6733d3
commit cda3cda132
8 changed files with 191 additions and 27 deletions

View File

@@ -90,6 +90,18 @@ SolverTrail::~SolverTrail() {
result.TheConstraint.Constraint = constraint; \
return result; \
}
#define BINDING_RELATION_CHANGE(Name) \
SolverTrail::Change \
SolverTrail::Change::Name(TypeVariableType *typeVar, \
TypeVariableType *otherTypeVar, \
Constraint *constraint) { \
Change result; \
result.Kind = ChangeKind::Name; \
result.BindingRelation.TypeVar = typeVar; \
result.BindingRelation.OtherTypeVar = otherTypeVar; \
result.BindingRelation.Constraint = constraint; \
return result; \
}
#define SCORE_CHANGE(Name) \
SolverTrail::Change \
SolverTrail::Change::Name(ScoreKind kind, unsigned value) { \
@@ -306,6 +318,19 @@ SolverTrail::Change::RetiredConstraint(ConstraintList::iterator where,
return result;
}
SolverTrail::Change
SolverTrail::Change::RetractedBinding(TypeVariableType *typeVar,
inference::PotentialBinding binding) {
Change result;
result.Kind = ChangeKind::RetractedBinding;
result.Binding.TypeVar = typeVar;
result.Binding.BindingType = binding.BindingType;
result.Binding.BindingSource = binding.BindingSource;
result.Options = unsigned(binding.Kind);
return result;
}
SyntacticElementTargetKey
SolverTrail::Change::getSyntacticElementTargetKey() const {
ASSERT(Kind == ChangeKind::RecordedTarget);
@@ -359,11 +384,9 @@ void SolverTrail::Change::undo(ConstraintSystem &cs) const {
cg.addConstraint(TheConstraint.TypeVar, TheConstraint.Constraint);
break;
case ChangeKind::ExtendedEquivalenceClass: {
auto &node = cg[EquivClass.TypeVar];
node.truncateEquivalenceClass(EquivClass.PrevSize);
case ChangeKind::ExtendedEquivalenceClass:
cg[EquivClass.TypeVar].truncateEquivalenceClass(EquivClass.PrevSize);
break;
}
case ChangeKind::RelatedTypeVariables:
cg.unrelateTypeVariables(Relation.TypeVar, Relation.OtherTypeVar);
@@ -373,9 +396,12 @@ void SolverTrail::Change::undo(ConstraintSystem &cs) const {
cg.retractBindings(TheConstraint.TypeVar, TheConstraint.Constraint);
break;
case ChangeKind::RetractedBindings:
cg.inferBindings(TheConstraint.TypeVar, TheConstraint.Constraint);
case ChangeKind::RetractedBindings: {
auto &bindings = cg[TheConstraint.TypeVar].getPotentialBindings();
bool inserted = bindings.Constraints.insert(TheConstraint.Constraint);
ASSERT(inserted);
break;
}
case ChangeKind::UpdatedTypeVariable:
Update.TypeVar->getImpl().setRawOptions(Options);
@@ -494,6 +520,45 @@ void SolverTrail::Change::undo(ConstraintSystem &cs) const {
cs.InactiveConstraints.insert(Retiree.Where,
Retiree.Constraint);
break;
case ChangeKind::RetractedDelayedBy:
cg[TheConstraint.TypeVar].getPotentialBindings()
.DelayedBy.push_back(TheConstraint.Constraint);
break;
case ChangeKind::RetractedAdjacentVar:
cg[BindingRelation.TypeVar].getPotentialBindings()
.AdjacentVars.emplace_back(BindingRelation.OtherTypeVar,
BindingRelation.Constraint);
break;
case ChangeKind::RetractedSubtypeOf:
cg[BindingRelation.TypeVar].getPotentialBindings()
.SubtypeOf.emplace_back(BindingRelation.OtherTypeVar,
BindingRelation.Constraint);
break;
case ChangeKind::RetractedSupertypeOf:
cg[BindingRelation.TypeVar].getPotentialBindings()
.SupertypeOf.emplace_back(BindingRelation.OtherTypeVar,
BindingRelation.Constraint);
break;
case ChangeKind::RetractedEquivalentTo:
cg[BindingRelation.TypeVar].getPotentialBindings()
.EquivalentTo.emplace_back(BindingRelation.OtherTypeVar,
BindingRelation.Constraint);
break;
case ChangeKind::RetractedBinding: {
PotentialBinding binding(Binding.BindingType,
AllowedBindingKind(Options),
Binding.BindingSource);
auto &bindings = cg[BindingRelation.TypeVar].getPotentialBindings();
bindings.Bindings.push_back(binding);
break;
}
}
}
@@ -541,6 +606,17 @@ void SolverTrail::Change::dump(llvm::raw_ostream &out,
TheConstraint.TypeVar->print(out, PO); \
out << ")\n"; \
break;
#define BINDING_RELATION_CHANGE(Name) \
case ChangeKind::Name: \
out << "(" << #Name << " "; \
BindingRelation.Constraint->print(out, &cs.getASTContext().SourceMgr, \
indent + 2); \
out << " on type variable "; \
BindingRelation.TypeVar->print(out, PO); \
out << " and "; \
BindingRelation.OtherTypeVar->print(out, PO); \
out << ")\n"; \
break;
#define SCORE_CHANGE(Name) \
case ChangeKind::Name: \
out << "(" << #Name << " "; \
@@ -692,6 +768,14 @@ void SolverTrail::Change::dump(llvm::raw_ostream &out,
indent + 2);
out << ")\n";
break;
case ChangeKind::RetractedBinding:
out << "(RetractedBinding ";
Binding.TypeVar->print(out, PO);
out << " with type ";
Binding.BindingType->print(out, PO);
out << " and kind " << Options << ")\n";
break;
}
}