Skip to content

Commit 77ee3da

Browse files
committed
Sema: Collect LiteralRequirements in PotentialBindings::infer()
1 parent 88f347a commit 77ee3da

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
GRAPH_NODE_CHANGE(RetractedDefault)

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) {
@@ -2088,10 +2093,13 @@ void PotentialBindings::infer(ConstraintSystem &CS,
20882093
case ConstraintKind::PackElementOf:
20892094
case ConstraintKind::SameShape:
20902095
case ConstraintKind::MaterializePackExpansion:
2091-
case ConstraintKind::LiteralConformsTo:
20922096
// Constraints from which we can't do anything.
20932097
break;
20942098

2099+
case ConstraintKind::LiteralConformsTo:
2100+
inferFromLiteral(CS, TypeVar, constraint);
2101+
break;
2102+
20952103
case ConstraintKind::Defaultable:
20962104
case ConstraintKind::FallbackType:
20972105
Defaults.push_back(constraint);
@@ -2219,6 +2227,20 @@ void PotentialBindings::retract(ConstraintSystem &CS,
22192227
}),
22202228
Bindings.end());
22212229

2230+
Literals.erase(
2231+
llvm::remove_if(Literals,
2232+
[&](const LiteralRequirement &literal) {
2233+
if (literal.getSource() == constraint) {
2234+
if (recordingChanges) {
2235+
CS.recordChange(SolverTrail::Change::RetractedLiteral(
2236+
TypeVar, constraint));
2237+
}
2238+
return true;
2239+
}
2240+
return false;
2241+
}),
2242+
Literals.end());
2243+
22222244
#define CALLBACK(ChangeKind) \
22232245
[&](Constraint *other) { \
22242246
if (other == constraint) { \

lib/Sema/CSTrail.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -548,6 +548,12 @@ void SolverTrail::Change::undo(ConstraintSystem &cs) const {
548548
.Defaults.push_back(TheConstraint.Constraint);
549549
break;
550550

551+
case ChangeKind::RetractedLiteral:
552+
cg[TheConstraint.TypeVar].getPotentialBindings()
553+
.inferFromLiteral(cs, TheConstraint.TypeVar,
554+
TheConstraint.Constraint);
555+
break;
556+
551557
case ChangeKind::RetractedAdjacentVar:
552558
cg[BindingRelation.TypeVar].getPotentialBindings()
553559
.AdjacentVars.emplace_back(BindingRelation.OtherTypeVar,

0 commit comments

Comments
 (0)