Skip to content

Commit 106ab41

Browse files
authored
Merge pull request #76742 from slavapestov/cstrail-part-1
Sema: Continue unwinding SolverScope
2 parents 62993ff + 31edb86 commit 106ab41

File tree

7 files changed

+217
-180
lines changed

7 files changed

+217
-180
lines changed

include/swift/Sema/CSBindings.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,9 @@ struct PotentialBindings {
223223

224224
TypeVariableType *TypeVar;
225225

226+
/// The set of all constraints that have been added via infer().
227+
llvm::SmallPtrSet<Constraint *, 2> Constraints;
228+
226229
/// The set of potential bindings.
227230
llvm::SmallVector<PotentialBinding, 4> Bindings;
228231

include/swift/Sema/CSTrail.h

Lines changed: 32 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -37,18 +37,20 @@ class SolverTrail {
3737

3838
/// The kind of change made to the graph.
3939
enum class ChangeKind {
40-
/// Added a type variable to the constraint graph.
40+
/// Added a new vertex to the constraint graph.
4141
AddedTypeVariable,
4242
/// Added a new constraint to the constraint graph.
4343
AddedConstraint,
4444
/// Removed an existing constraint from the constraint graph.
4545
RemovedConstraint,
4646
/// Extended the equivalence class of a type variable in the constraint graph.
4747
ExtendedEquivalenceClass,
48-
/// Added a fixed binding for a type variable in the constraint graph.
49-
BoundTypeVariable,
50-
/// Introduced a type variable's fixed type to inference.
51-
IntroducedToInference,
48+
/// Added a new edge in the constraint graph.
49+
RelatedTypeVariables,
50+
/// Inferred potential bindings from a constraint.
51+
InferredBindings,
52+
/// Retracted potential bindings from a constraint.
53+
RetractedBindings,
5254
/// Set the fixed type or parent and flags for a type variable.
5355
UpdatedTypeVariable,
5456
};
@@ -64,7 +66,14 @@ class SolverTrail {
6466

6567
union {
6668
TypeVariableType *TypeVar;
67-
Constraint *TheConstraint;
69+
70+
struct {
71+
/// The type variable we're adding or removing a constraint from.
72+
TypeVariableType *TypeVar;
73+
74+
/// The constraint.
75+
Constraint *Constraint;
76+
} TheConstraint;
6877

6978
struct {
7079
/// The type variable whose equivalence class was extended.
@@ -75,12 +84,12 @@ class SolverTrail {
7584
} EquivClass;
7685

7786
struct {
78-
/// The type variable being bound to a fixed type.
87+
/// The first type variable.
7988
TypeVariableType *TypeVar;
8089

81-
/// The fixed type to which the type variable was bound.
82-
TypeBase *FixedType;
83-
} Binding;
90+
/// The second type variable.
91+
TypeVariableType *OtherTypeVar;
92+
} Relation;
8493

8594
struct {
8695
/// The type variable being updated.
@@ -100,20 +109,27 @@ class SolverTrail {
100109
static Change addedTypeVariable(TypeVariableType *typeVar);
101110

102111
/// Create a change that added a constraint.
103-
static Change addedConstraint(Constraint *constraint);
112+
static Change addedConstraint(TypeVariableType *typeVar, Constraint *constraint);
104113

105114
/// Create a change that removed a constraint.
106-
static Change removedConstraint(Constraint *constraint);
115+
static Change removedConstraint(TypeVariableType *typeVar, Constraint *constraint);
107116

108117
/// Create a change that extended an equivalence class.
109118
static Change extendedEquivalenceClass(TypeVariableType *typeVar,
110119
unsigned prevSize);
111120

112-
/// Create a change that bound a type variable to a fixed type.
113-
static Change boundTypeVariable(TypeVariableType *typeVar, Type fixed);
121+
/// Create a change that updated the references/referenced by sets of
122+
/// a type variable pair.
123+
static Change relatedTypeVariables(TypeVariableType *typeVar,
124+
TypeVariableType *otherTypeVar);
125+
126+
/// Create a change that inferred bindings from a constraint.
127+
static Change inferredBindings(TypeVariableType *typeVar,
128+
Constraint *constraint);
114129

115-
/// Create a change that introduced a type variable to inference.
116-
static Change introducedToInference(TypeVariableType *typeVar, Type fixed);
130+
/// Create a change that retracted bindings from a constraint.
131+
static Change retractedBindings(TypeVariableType *typeVar,
132+
Constraint *constraint);
117133

118134
/// Create a change that updated a type variable.
119135
static Change updatedTypeVariable(

include/swift/Sema/ConstraintGraph.h

Lines changed: 23 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -153,13 +153,6 @@ class ConstraintGraphNode {
153153
/// type variable has been bound to a valid type and solver can make progress.
154154
void introduceToInference(Type fixedType);
155155

156-
/// Opposite of \c introduceToInference(Type)
157-
void retractFromInference(Type fixedType);
158-
159-
/// Drop all previously collected bindings and re-infer based on the
160-
/// current set constraints associated with this equivalence class.
161-
void resetBindingSet();
162-
163156
/// Notify all of the type variables that have this one (or any member of
164157
/// its equivalence class) referenced in their fixed type.
165158
///
@@ -259,9 +252,15 @@ class ConstraintGraph {
259252
/// Add a new constraint to the graph.
260253
void addConstraint(Constraint *constraint);
261254

255+
/// Primitive form for SolverTrail::Change::undo().
256+
void addConstraint(TypeVariableType *typeVar, Constraint *constraint);
257+
262258
/// Remove a constraint from the graph.
263259
void removeConstraint(Constraint *constraint);
264260

261+
/// Primitive form for SolverTrail::Change::undo().
262+
void removeConstraint(TypeVariableType *typeVar, Constraint *constraint);
263+
265264
/// Merge the two nodes for the two given type variables.
266265
///
267266
/// The type variables must actually have been merged already; this
@@ -416,25 +415,29 @@ class ConstraintGraph {
416415
private:
417416
/// Remove the node corresponding to the given type variable.
418417
///
419-
/// This operation assumes that the any constraints that refer to
420-
/// this type variable have been or will be removed before other
421-
/// graph queries are performed.
418+
/// This operation assumes that the any constraints that refer to this type
419+
/// variable have been or will be removed before other graph queries are
420+
/// performed.
422421
///
423-
/// Note that this change is not recorded and cannot be undone. Use with
424-
/// caution.
422+
/// Note that this it only meant to be called by SolverTrail::Change::undo().
425423
void removeNode(TypeVariableType *typeVar);
426424

427-
/// Unbind the given type variable from the given fixed type.
425+
/// Remove an edge from the constraint graph.
426+
///
427+
///
428+
/// Note that this it only meant to be called by SolverTrail::Change::undo().
429+
void unrelateTypeVariables(TypeVariableType *typeVar,
430+
TypeVariableType *otherTypeVar);
431+
432+
/// Infer bindings from the given constraint.
428433
///
429-
/// Note that this change is not recorded and cannot be undone. Use with
430-
/// caution.
431-
void unbindTypeVariable(TypeVariableType *typeVar, Type fixedType);
434+
/// Note that this it only meant to be called by SolverTrail::Change::undo().
435+
void inferBindings(TypeVariableType *typeVar, Constraint *constraint);
432436

433-
/// Retract the given type variable from inference.
437+
/// Retract bindings from the given constraint.
434438
///
435-
/// Note that this change is not recorded and cannot be undone. Use with
436-
/// caution.
437-
void retractFromInference(TypeVariableType *typeVar, Type fixedType);
439+
/// Note that this it only meant to be called by SolverTrail::Change::undo().
440+
void retractBindings(TypeVariableType *typeVar, Constraint *constraint);
438441

439442
/// Perform edge contraction on the constraint graph, merging equivalence
440443
/// classes until a fixed point is reached.

lib/Sema/CSBindings.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1769,6 +1769,13 @@ PotentialBindings::inferFromRelational(Constraint *constraint) {
17691769
/// representative type variable, along with flags indicating whether
17701770
/// those types should be opened.
17711771
void PotentialBindings::infer(Constraint *constraint) {
1772+
if (!Constraints.insert(constraint).second)
1773+
return;
1774+
1775+
// Record the change, if there are active scopes.
1776+
if (CS.isRecordingChanges())
1777+
CS.recordChange(SolverTrail::Change::inferredBindings(TypeVar, constraint));
1778+
17721779
switch (constraint->getKind()) {
17731780
case ConstraintKind::Bind:
17741781
case ConstraintKind::Equal:
@@ -1937,6 +1944,13 @@ void PotentialBindings::infer(Constraint *constraint) {
19371944
}
19381945

19391946
void PotentialBindings::retract(Constraint *constraint) {
1947+
if (!Constraints.erase(constraint))
1948+
return;
1949+
1950+
// Record the change, if there are active scopes.
1951+
if (CS.isRecordingChanges())
1952+
CS.recordChange(SolverTrail::Change::retractedBindings(TypeVar, constraint));
1953+
19401954
Bindings.erase(
19411955
llvm::remove_if(Bindings,
19421956
[&constraint](const PotentialBinding &binding) {

lib/Sema/CSTrail.cpp

Lines changed: 67 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -50,18 +50,22 @@ SolverTrail::Change::addedTypeVariable(TypeVariableType *typeVar) {
5050
}
5151

5252
SolverTrail::Change
53-
SolverTrail::Change::addedConstraint(Constraint *constraint) {
53+
SolverTrail::Change::addedConstraint(TypeVariableType *typeVar,
54+
Constraint *constraint) {
5455
Change result;
5556
result.Kind = ChangeKind::AddedConstraint;
56-
result.TheConstraint = constraint;
57+
result.TheConstraint.TypeVar = typeVar;
58+
result.TheConstraint.Constraint = constraint;
5759
return result;
5860
}
5961

6062
SolverTrail::Change
61-
SolverTrail::Change::removedConstraint(Constraint *constraint) {
63+
SolverTrail::Change::removedConstraint(TypeVariableType *typeVar,
64+
Constraint *constraint) {
6265
Change result;
6366
result.Kind = ChangeKind::RemovedConstraint;
64-
result.TheConstraint = constraint;
67+
result.TheConstraint.TypeVar = typeVar;
68+
result.TheConstraint.Constraint = constraint;
6569
return result;
6670
}
6771

@@ -76,22 +80,32 @@ SolverTrail::Change::extendedEquivalenceClass(TypeVariableType *typeVar,
7680
}
7781

7882
SolverTrail::Change
79-
SolverTrail::Change::boundTypeVariable(TypeVariableType *typeVar,
80-
Type fixed) {
83+
SolverTrail::Change::relatedTypeVariables(TypeVariableType *typeVar,
84+
TypeVariableType *otherTypeVar) {
8185
Change result;
82-
result.Kind = ChangeKind::BoundTypeVariable;
83-
result.Binding.TypeVar = typeVar;
84-
result.Binding.FixedType = fixed.getPointer();
86+
result.Kind = ChangeKind::RelatedTypeVariables;
87+
result.Relation.TypeVar = typeVar;
88+
result.Relation.OtherTypeVar = otherTypeVar;
8589
return result;
8690
}
8791

8892
SolverTrail::Change
89-
SolverTrail::Change::introducedToInference(TypeVariableType *typeVar,
90-
Type fixed) {
93+
SolverTrail::Change::inferredBindings(TypeVariableType *typeVar,
94+
Constraint *constraint) {
9195
Change result;
92-
result.Kind = ChangeKind::IntroducedToInference;
93-
result.Binding.TypeVar = typeVar;
94-
result.Binding.FixedType = fixed.getPointer();
96+
result.Kind = ChangeKind::InferredBindings;
97+
result.TheConstraint.TypeVar = typeVar;
98+
result.TheConstraint.Constraint = constraint;
99+
return result;
100+
}
101+
102+
SolverTrail::Change
103+
SolverTrail::Change::retractedBindings(TypeVariableType *typeVar,
104+
Constraint *constraint) {
105+
Change result;
106+
result.Kind = ChangeKind::RetractedBindings;
107+
result.TheConstraint.TypeVar = typeVar;
108+
result.TheConstraint.Constraint = constraint;
95109
return result;
96110
}
97111

@@ -117,11 +131,11 @@ void SolverTrail::Change::undo(ConstraintSystem &cs) const {
117131
break;
118132

119133
case ChangeKind::AddedConstraint:
120-
cg.removeConstraint(TheConstraint);
134+
cg.removeConstraint(TheConstraint.TypeVar, TheConstraint.Constraint);
121135
break;
122136

123137
case ChangeKind::RemovedConstraint:
124-
cg.addConstraint(TheConstraint);
138+
cg.addConstraint(TheConstraint.TypeVar, TheConstraint.Constraint);
125139
break;
126140

127141
case ChangeKind::ExtendedEquivalenceClass: {
@@ -130,12 +144,16 @@ void SolverTrail::Change::undo(ConstraintSystem &cs) const {
130144
break;
131145
}
132146

133-
case ChangeKind::BoundTypeVariable:
134-
cg.unbindTypeVariable(Binding.TypeVar, Binding.FixedType);
147+
case ChangeKind::RelatedTypeVariables:
148+
cg.unrelateTypeVariables(Relation.TypeVar, Relation.OtherTypeVar);
135149
break;
136150

137-
case ChangeKind::IntroducedToInference:
138-
cg.retractFromInference(Binding.TypeVar, Binding.FixedType);
151+
case ChangeKind::InferredBindings:
152+
cg.retractBindings(TheConstraint.TypeVar, TheConstraint.Constraint);
153+
break;
154+
155+
case ChangeKind::RetractedBindings:
156+
cg.inferBindings(TheConstraint.TypeVar, TheConstraint.Constraint);
139157
break;
140158

141159
case ChangeKind::UpdatedTypeVariable:
@@ -162,13 +180,19 @@ void SolverTrail::Change::dump(llvm::raw_ostream &out,
162180

163181
case ChangeKind::AddedConstraint:
164182
out << "(added constraint ";
165-
TheConstraint->print(out, &cs.getASTContext().SourceMgr, indent + 2);
183+
TheConstraint.Constraint->print(out, &cs.getASTContext().SourceMgr,
184+
indent + 2);
185+
out << " to type variable ";
186+
TheConstraint.TypeVar->print(out, PO);
166187
out << ")\n";
167188
break;
168189

169190
case ChangeKind::RemovedConstraint:
170191
out << "(removed constraint ";
171-
TheConstraint->print(out, &cs.getASTContext().SourceMgr, indent + 2);
192+
TheConstraint.Constraint->print(out, &cs.getASTContext().SourceMgr,
193+
indent + 2);
194+
out << " from type variable ";
195+
TheConstraint.TypeVar->print(out, PO);
172196
out << ")\n";
173197
break;
174198

@@ -179,20 +203,30 @@ void SolverTrail::Change::dump(llvm::raw_ostream &out,
179203
break;
180204
}
181205

182-
case ChangeKind::BoundTypeVariable:
183-
out << "(bound type variable ";
184-
Binding.TypeVar->print(out, PO);
185-
out << " to fixed type ";
186-
Binding.FixedType->print(out, PO);
206+
case ChangeKind::RelatedTypeVariables:
207+
out << "(related type variable ";
208+
Relation.TypeVar->print(out, PO);
209+
out << " with ";
210+
Relation.OtherTypeVar->print(out, PO);
187211
out << ")\n";
188212
break;
189213

190-
case ChangeKind::IntroducedToInference:
191-
out << "(introduced type variable ";
192-
Binding.TypeVar->print(out, PO);
193-
out << " with fixed type ";
194-
Binding.FixedType->print(out, PO);
195-
out << " to inference)\n";
214+
case ChangeKind::InferredBindings:
215+
out << "(inferred bindings from ";
216+
TheConstraint.Constraint->print(out, &cs.getASTContext().SourceMgr,
217+
indent + 2);
218+
out << " for type variable ";
219+
TheConstraint.TypeVar->print(out, PO);
220+
out << ")\n";
221+
break;
222+
223+
case ChangeKind::RetractedBindings:
224+
out << "(retracted bindings from ";
225+
TheConstraint.Constraint->print(out, &cs.getASTContext().SourceMgr,
226+
indent + 2);
227+
out << " for type variable ";
228+
TheConstraint.TypeVar->print(out, PO);
229+
out << ")\n";
196230
break;
197231

198232
case ChangeKind::UpdatedTypeVariable:

0 commit comments

Comments
 (0)