Skip to content

Commit 37c3d70

Browse files
committed
Sema: Collect LiteralRequirements in PotentialBindings::infer()
1 parent ab97d03 commit 37c3d70

File tree

4 files changed

+55
-18
lines changed

4 files changed

+55
-18
lines changed

include/swift/Sema/CSBindings.h

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,10 @@ struct LiteralRequirement {
179179

180180
bool isDirectRequirement() const { return IsDirectRequirement; }
181181

182+
void setDirectRequirement(bool isDirectRequirement) {
183+
IsDirectRequirement = isDirectRequirement;
184+
}
185+
182186
bool hasDefaultType() const { return bool(DefaultType); }
183187

184188
Type getDefaultType() const {
@@ -248,6 +252,10 @@ struct PotentialBindings {
248252
/// The set of protocol conformance requirements imposed on this type variable.
249253
llvm::SmallVector<Constraint *, 4> Protocols;
250254

255+
/// The set of unique literal protocol requirements placed on this
256+
/// type variable.
257+
llvm::SmallVector<LiteralRequirement, 2> Literals;
258+
251259
/// The set of fallback constraints imposed on this type variable.
252260
llvm::SmallVector<Constraint *, 2> Defaults;
253261

@@ -270,7 +278,10 @@ struct PotentialBindings {
270278
return Protocols;
271279
}
272280

273-
private:
281+
void inferFromLiteral(ConstraintSystem &CS,
282+
TypeVariableType *TypeVar,
283+
Constraint *literal);
284+
274285
/// Attempt to infer a new binding and other useful information
275286
/// (i.e. whether bindings should be delayed) from the given
276287
/// relational constraint.
@@ -279,7 +290,6 @@ struct PotentialBindings {
279290
TypeVariableType *TypeVar,
280291
Constraint *constraint);
281292

282-
public:
283293
void infer(ConstraintSystem &CS,
284294
TypeVariableType *TypeVar,
285295
Constraint *constraint);
@@ -621,8 +631,6 @@ class BindingSet {
621631
/// checking.
622632
void addBinding(PotentialBinding binding, bool isTransitive);
623633

624-
void addLiteralRequirement(Constraint *literal);
625-
626634
void addDefault(Constraint *constraint);
627635

628636
StringRef getLiteralBindingKind(LiteralBindingKind K) const {

include/swift/Sema/CSTrail.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ GRAPH_NODE_CHANGE(AddedConstraint)
7676
GRAPH_NODE_CHANGE(RemovedConstraint)
7777
GRAPH_NODE_CHANGE(InferredBindings)
7878
GRAPH_NODE_CHANGE(RetractedBindings)
79+
GRAPH_NODE_CHANGE(RetractedLiteral)
7980
GRAPH_NODE_CHANGE(RetractedDelayedBy)
8081
GRAPH_NODE_CHANGE(RetractedProtocol)
8182

lib/Sema/CSBindings.cpp

Lines changed: 36 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -55,16 +55,8 @@ BindingSet::BindingSet(ConstraintSystem &CS, TypeVariableType *TypeVar,
5555
for (const auto &binding : info.Bindings)
5656
addBinding(binding, /*isTransitive=*/false);
5757

58-
for (auto *constraint : info.Constraints) {
59-
switch (constraint->getKind()) {
60-
case ConstraintKind::LiteralConformsTo:
61-
addLiteralRequirement(constraint);
62-
break;
63-
64-
default:
65-
break;
66-
}
67-
}
58+
for (const auto &literal : info.Literals)
59+
Literals.push_back(literal);
6860

6961
for (auto *constraint : info.Defaults) {
7062
// Do these in a separate pass.
@@ -653,8 +645,19 @@ void BindingSet::inferTransitiveSupertypeBindings() {
653645
// If one of the literal arguments doesn't propagate its
654646
// `ExpressibleByStringLiteral` conformance, we'd end up picking
655647
// `T` with only one type `Any?` which is incorrect.
656-
for (const auto &literal : bindings.Literals)
657-
addLiteralRequirement(literal.getSource());
648+
for (auto literal : bindings.Literals) {
649+
auto *protocol = literal.getProtocol();
650+
651+
bool found = llvm::any_of(Literals,
652+
[&](const auto &literal) -> bool {
653+
return literal.getProtocol() == protocol;
654+
});
655+
if (found)
656+
continue;
657+
658+
literal.setDirectRequirement(false);
659+
Literals.push_back(literal);
660+
}
658661

659662
// Infer transitive defaults.
660663
for (auto *def : bindings.Defaults) {
@@ -1055,7 +1058,9 @@ void BindingSet::coalesceIntegerAndFloatLiteralRequirements() {
10551058
}
10561059
}
10571060

1058-
void BindingSet::addLiteralRequirement(Constraint *constraint) {
1061+
void PotentialBindings::inferFromLiteral(ConstraintSystem &CS,
1062+
TypeVariableType *TypeVar,
1063+
Constraint *constraint) {
10591064
auto *protocol = constraint->getProtocol();
10601065

10611066
for (const auto &literal : Literals) {
@@ -2083,10 +2088,13 @@ void PotentialBindings::infer(ConstraintSystem &CS,
20832088
case ConstraintKind::PackElementOf:
20842089
case ConstraintKind::SameShape:
20852090
case ConstraintKind::MaterializePackExpansion:
2086-
case ConstraintKind::LiteralConformsTo:
20872091
// Constraints from which we can't do anything.
20882092
break;
20892093

2094+
case ConstraintKind::LiteralConformsTo:
2095+
inferFromLiteral(CS, TypeVar, constraint);
2096+
break;
2097+
20902098
case ConstraintKind::Defaultable:
20912099
case ConstraintKind::FallbackType:
20922100
Defaults.push_back(constraint);
@@ -2214,6 +2222,20 @@ void PotentialBindings::retract(ConstraintSystem &CS,
22142222
}),
22152223
Bindings.end());
22162224

2225+
Literals.erase(
2226+
llvm::remove_if(Literals,
2227+
[&](const LiteralRequirement &literal) {
2228+
if (literal.getSource() == constraint) {
2229+
if (recordingChanges) {
2230+
CS.recordChange(SolverTrail::Change::RetractedLiteral(
2231+
TypeVar, constraint));
2232+
}
2233+
return true;
2234+
}
2235+
return false;
2236+
}),
2237+
Literals.end());
2238+
22172239
#define CALLBACK(ChangeKind) \
22182240
[&](Constraint *other) { \
22192241
if (other == constraint) { \

lib/Sema/CSTrail.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -543,6 +543,12 @@ void SolverTrail::Change::undo(ConstraintSystem &cs) const {
543543
.Protocols.push_back(TheConstraint.Constraint);
544544
break;
545545

546+
case ChangeKind::RetractedLiteral:
547+
cg[TheConstraint.TypeVar].getPotentialBindings()
548+
.inferFromLiteral(cs, TheConstraint.TypeVar,
549+
TheConstraint.Constraint);
550+
break;
551+
546552
case ChangeKind::RetractedAdjacentVar:
547553
cg[BindingRelation.TypeVar].getPotentialBindings()
548554
.AdjacentVars.emplace_back(BindingRelation.OtherTypeVar,

0 commit comments

Comments
 (0)