Skip to content

Commit 4937d0a

Browse files
authored
Merge pull request #79134 from slavapestov/smaller-potential-bindings
Sema: More accurate undo() of PotentialBindings::retract()
2 parents fdec23c + 8a3300b commit 4937d0a

File tree

10 files changed

+276
-155
lines changed

10 files changed

+276
-155
lines changed

include/swift/Sema/CSBindings.h

Lines changed: 19 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -71,15 +71,12 @@ enum class LiteralBindingKind : uint8_t {
7171
/// along with information that can be used to construct related
7272
/// bindings, e.g., the supertypes of a given type.
7373
struct PotentialBinding {
74-
friend class BindingSet;
75-
7674
/// The type to which the type variable can be bound.
7775
Type BindingType;
7876

7977
/// The kind of bindings permitted.
8078
AllowedBindingKind Kind;
8179

82-
protected:
8380
/// The source of the type information.
8481
///
8582
/// Determines whether this binding represents a "hole" in
@@ -91,7 +88,6 @@ struct PotentialBinding {
9188
PointerUnion<Constraint *, ConstraintLocator *> source)
9289
: BindingType(type), Kind(kind), BindingSource(source) {}
9390

94-
public:
9591
PotentialBinding(Type type, AllowedBindingKind kind, Constraint *source)
9692
: PotentialBinding(
9793
type, kind,
@@ -219,25 +215,11 @@ struct LiteralRequirement {
219215

220216
struct PotentialBindings {
221217
/// The set of all constraints that have been added via infer().
222-
llvm::SmallPtrSet<Constraint *, 2> Constraints;
218+
llvm::SmallSetVector<Constraint *, 2> Constraints;
223219

224220
/// The set of potential bindings.
225221
llvm::SmallVector<PotentialBinding, 4> Bindings;
226222

227-
/// The set of protocol requirements placed on this type variable.
228-
llvm::SmallVector<Constraint *, 4> Protocols;
229-
230-
/// The set of unique literal protocol requirements placed on this
231-
/// type variable or inferred transitively through subtype chains.
232-
///
233-
/// Note that ordering is important when it comes to bindings, we'd
234-
/// like to add any "direct" default types first to attempt them
235-
/// before transitive ones.
236-
llvm::SmallPtrSet<Constraint *, 2> Literals;
237-
238-
/// The set of constraints which would be used to infer default types.
239-
llvm::SmallPtrSet<Constraint *, 2> Defaults;
240-
241223
/// The set of constraints which delay attempting this type variable.
242224
llvm::TinyPtrVector<Constraint *> DelayedBy;
243225

@@ -247,22 +229,17 @@ struct PotentialBindings {
247229
/// bindings (contained in the binding type e.g. `Foo<$T0>`), or
248230
/// reachable through subtype/conversion relationship e.g.
249231
/// `$T0 subtype of $T1` or `$T0 arg conversion $T1`.
250-
llvm::SmallDenseSet<std::pair<TypeVariableType *, Constraint *>, 2>
251-
AdjacentVars;
252-
253-
ASTNode AssociatedCodeCompletionToken = ASTNode();
232+
llvm::SmallVector<std::pair<TypeVariableType *, Constraint *>, 2> AdjacentVars;
254233

255234
/// A set of all not-yet-resolved type variables this type variable
256235
/// is a subtype of, supertype of or is equivalent to. This is used
257236
/// to determine ordering inside of a chain of subtypes to help infer
258237
/// transitive bindings and protocol requirements.
259-
llvm::SmallSetVector<std::pair<TypeVariableType *, Constraint *>, 4> SubtypeOf;
260-
llvm::SmallSetVector<std::pair<TypeVariableType *, Constraint *>, 4> SupertypeOf;
261-
llvm::SmallSetVector<std::pair<TypeVariableType *, Constraint *>, 4> EquivalentTo;
262-
263-
void addDefault(Constraint *constraint);
238+
llvm::SmallVector<std::pair<TypeVariableType *, Constraint *>, 4> SubtypeOf;
239+
llvm::SmallVector<std::pair<TypeVariableType *, Constraint *>, 4> SupertypeOf;
240+
llvm::SmallVector<std::pair<TypeVariableType *, Constraint *>, 4> EquivalentTo;
264241

265-
void addLiteral(Constraint *constraint);
242+
ASTNode AssociatedCodeCompletionToken = ASTNode();
266243

267244
/// Add a potential binding to the list of bindings,
268245
/// coalescing supertype bounds when we are able to compute the meet.
@@ -385,28 +362,26 @@ class BindingSet {
385362

386363
public:
387364
swift::SmallSetVector<PotentialBinding, 4> Bindings;
365+
366+
/// The set of protocol conformance requirements placed on this type variable.
367+
llvm::SmallVector<Constraint *, 4> Protocols;
368+
369+
/// The set of unique literal protocol requirements placed on this
370+
/// type variable or inferred transitively through subtype chains.
371+
///
372+
/// Note that ordering is important when it comes to bindings, we'd
373+
/// like to add any "direct" default types first to attempt them
374+
/// before transitive ones.
388375
llvm::SmallMapVector<ProtocolDecl *, LiteralRequirement, 2> Literals;
376+
389377
llvm::SmallDenseMap<CanType, Constraint *, 2> Defaults;
390378

391379
/// The set of transitive protocol requirements inferred through
392380
/// subtype/conversion/equivalence relations with other type variables.
393381
std::optional<llvm::SmallPtrSet<Constraint *, 4>> TransitiveProtocols;
394382

395383
BindingSet(ConstraintSystem &CS, TypeVariableType *TypeVar,
396-
const PotentialBindings &info)
397-
: CS(CS), TypeVar(TypeVar), Info(info) {
398-
for (const auto &binding : info.Bindings)
399-
addBinding(binding, /*isTransitive=*/false);
400-
401-
for (auto *literal : info.Literals)
402-
addLiteralRequirement(literal);
403-
404-
for (auto *constraint : info.Defaults)
405-
addDefault(constraint);
406-
407-
for (auto &entry : info.AdjacentVars)
408-
AdjacentVars.insert(entry.first);
409-
}
384+
const PotentialBindings &info);
410385

411386
ConstraintSystem &getConstraintSystem() const { return CS; }
412387

@@ -512,7 +487,7 @@ class BindingSet {
512487
}
513488

514489
ArrayRef<Constraint *> getConformanceRequirements() const {
515-
return Info.Protocols;
490+
return Protocols;
516491
}
517492

518493
unsigned getNumViableLiteralBindings() const;

include/swift/Sema/CSTrail.def

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,10 @@
3838
#define GRAPH_NODE_CHANGE(Name) CHANGE(Name)
3939
#endif
4040

41+
#ifndef BINDING_RELATION_CHANGE
42+
#define BINDING_RELATION_CHANGE(Name) CHANGE(Name)
43+
#endif
44+
4145
#ifndef SCORE_CHANGE
4246
#define SCORE_CHANGE(Name) CHANGE(Name)
4347
#endif
@@ -73,6 +77,12 @@ GRAPH_NODE_CHANGE(AddedConstraint)
7377
GRAPH_NODE_CHANGE(RemovedConstraint)
7478
GRAPH_NODE_CHANGE(InferredBindings)
7579
GRAPH_NODE_CHANGE(RetractedBindings)
80+
GRAPH_NODE_CHANGE(RetractedDelayedBy)
81+
82+
BINDING_RELATION_CHANGE(RetractedAdjacentVar)
83+
BINDING_RELATION_CHANGE(RetractedSubtypeOf)
84+
BINDING_RELATION_CHANGE(RetractedSupertypeOf)
85+
BINDING_RELATION_CHANGE(RetractedEquivalentTo)
7686

7787
SCORE_CHANGE(IncreasedScore)
7888
SCORE_CHANGE(DecreasedScore)
@@ -96,14 +106,16 @@ CHANGE(RecordedPotentialThrowSite)
96106
CHANGE(RecordedIsolatedParam)
97107
CHANGE(RecordedKeyPath)
98108
CHANGE(RetiredConstraint)
109+
CHANGE(RetractedBinding)
99110

100-
LAST_CHANGE(RetiredConstraint)
111+
LAST_CHANGE(RetractedBinding)
101112

102113
#undef LOCATOR_CHANGE
103114
#undef EXPR_CHANGE
104115
#undef CLOSURE_CHANGE
105116
#undef CONSTRAINT_CHANGE
106117
#undef GRAPH_NODE_CHANGE
118+
#undef BINDING_RELATION_CHANGE
107119
#undef SCORE_CHANGE
108120
#undef LAST_CHANGE
109121
#undef CHANGE

include/swift/Sema/CSTrail.h

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,10 @@ namespace constraints {
3838
class Constraint;
3939
struct SyntacticElementTargetKey;
4040

41+
namespace inference {
42+
struct PotentialBinding;
43+
}
44+
4145
class SolverTrail {
4246
public:
4347

@@ -89,6 +93,12 @@ class SolverTrail {
8993
TypeVariableType *OtherTypeVar;
9094
} Relation;
9195

96+
struct {
97+
TypeVariableType *TypeVar;
98+
TypeVariableType *OtherTypeVar;
99+
Constraint *Constraint;
100+
} BindingRelation;
101+
92102
struct {
93103
/// The type variable being updated.
94104
TypeVariableType *TypeVar;
@@ -128,6 +138,15 @@ class SolverTrail {
128138
Constraint *Constraint;
129139
} Retiree;
130140

141+
struct {
142+
TypeVariableType *TypeVar;
143+
144+
/// These two fields together with 'Options' above store the contents
145+
/// of a PotentialBinding.
146+
Type BindingType;
147+
PointerUnion<Constraint *, ConstraintLocator *> BindingSource;
148+
} Binding;
149+
131150
ConstraintFix *TheFix;
132151
ConstraintLocator *TheLocator;
133152
PackExpansionType *TheExpansion;
@@ -155,6 +174,9 @@ class SolverTrail {
155174
#define SCORE_CHANGE(Name) static Change Name(ScoreKind kind, unsigned value);
156175
#define GRAPH_NODE_CHANGE(Name) static Change Name(TypeVariableType *typeVar, \
157176
Constraint *constraint);
177+
#define BINDING_RELATION_CHANGE(Name) static Change Name(TypeVariableType *typeVar, \
178+
TypeVariableType *otherTypeVar, \
179+
Constraint *constraint);
158180
#include "swift/Sema/CSTrail.def"
159181

160182
/// Create a change that added a type variable.
@@ -226,6 +248,11 @@ class SolverTrail {
226248
static Change RetiredConstraint(llvm::ilist<Constraint>::iterator where,
227249
Constraint *constraint);
228250

251+
/// Create a change that removed a binding from a type variable's potential
252+
/// bindings.
253+
static Change RetractedBinding(TypeVariableType *typeVar,
254+
inference::PotentialBinding binding);
255+
229256
/// Undo this change, reverting the constraint graph to the state it
230257
/// had prior to this change.
231258
///

include/swift/Sema/ConstraintGraph.h

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -448,11 +448,6 @@ class ConstraintGraph {
448448
void unrelateTypeVariables(TypeVariableType *typeVar,
449449
TypeVariableType *otherTypeVar);
450450

451-
/// Infer bindings from the given constraint.
452-
///
453-
/// Note that this it only meant to be called by SolverTrail::Change::undo().
454-
void inferBindings(TypeVariableType *typeVar, Constraint *constraint);
455-
456451
/// Retract bindings from the given constraint.
457452
///
458453
/// Note that this it only meant to be called by SolverTrail::Change::undo().

0 commit comments

Comments
 (0)