Skip to content

Commit de17f25

Browse files
committed
Sema: BindingSet::Literals can just be a vector and not a map
1 parent a68039e commit de17f25

File tree

5 files changed

+42
-49
lines changed

5 files changed

+42
-49
lines changed

include/swift/Sema/CSBindings.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -382,7 +382,7 @@ class BindingSet {
382382
/// Note that ordering is important when it comes to bindings, we'd
383383
/// like to add any "direct" default types first to attempt them
384384
/// before transitive ones.
385-
llvm::SmallMapVector<ProtocolDecl *, LiteralRequirement, 2> Literals;
385+
llvm::SmallVector<LiteralRequirement, 2> Literals;
386386

387387
llvm::SmallVector<Constraint *, 2> Defaults;
388388

@@ -465,7 +465,7 @@ class BindingSet {
465465
// Literal requirements always result in a subtype/supertype
466466
// relationship to a concrete type.
467467
if (llvm::any_of(Literals, [](const auto &literal) {
468-
return literal.second.viableAsBinding();
468+
return literal.viableAsBinding();
469469
}))
470470
return false;
471471

lib/Sema/CSBindings.cpp

Lines changed: 35 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -86,9 +86,12 @@ bool BindingSet::forGenericParameter() const {
8686
}
8787

8888
bool BindingSet::canBeNil() const {
89-
auto &ctx = CS.getASTContext();
90-
return Literals.count(
91-
ctx.getProtocol(KnownProtocolKind::ExpressibleByNilLiteral));
89+
for (const auto &literal : Literals) {
90+
if (literal.getProtocol()->isSpecificProtocol(
91+
KnownProtocolKind::ExpressibleByNilLiteral))
92+
return true;
93+
}
94+
return false;
9295
}
9396

9497
bool BindingSet::isDirectHole() const {
@@ -652,7 +655,7 @@ void BindingSet::inferTransitiveSupertypeBindings() {
652655
// `ExpressibleByStringLiteral` conformance, we'd end up picking
653656
// `T` with only one type `Any?` which is incorrect.
654657
for (const auto &literal : bindings.Literals)
655-
addLiteralRequirement(literal.second.getSource());
658+
addLiteralRequirement(literal.getSource());
656659

657660
// Infer transitive defaults.
658661
for (auto *def : bindings.Defaults) {
@@ -1002,9 +1005,7 @@ void BindingSet::determineLiteralCoverage() {
10021005

10031006
bool allowsNil = canBeNil();
10041007

1005-
for (auto &entry : Literals) {
1006-
auto &literal = entry.second;
1007-
1008+
for (auto &literal : Literals) {
10081009
if (!literal.viableAsBinding())
10091010
continue;
10101011

@@ -1032,34 +1033,36 @@ void BindingSet::determineLiteralCoverage() {
10321033
}
10331034

10341035
void BindingSet::coalesceIntegerAndFloatLiteralRequirements() {
1035-
for (const auto &pair : Literals) {
1036-
auto *protocol = pair.first;
1036+
decltype(Literals)::iterator intLiteral = Literals.end();
1037+
decltype(Literals)::iterator floatLiteral = Literals.end();
1038+
1039+
for (auto iter = Literals.begin(); iter != Literals.end(); ++iter) {
1040+
auto *protocol = iter->getProtocol();
10371041

10381042
if (protocol->isSpecificProtocol(
10391043
KnownProtocolKind::ExpressibleByIntegerLiteral)) {
1040-
auto *floatLiteral = CS.getASTContext().getProtocol(
1041-
KnownProtocolKind::ExpressibleByFloatLiteral);
1042-
if (Literals.count(floatLiteral)) {
1043-
Literals.erase(protocol);
1044-
return;
1045-
}
1044+
intLiteral = iter;
10461045
}
10471046

10481047
if (protocol->isSpecificProtocol(
10491048
KnownProtocolKind::ExpressibleByFloatLiteral)) {
1050-
auto *intLiteral = CS.getASTContext().getProtocol(
1051-
KnownProtocolKind::ExpressibleByIntegerLiteral);
1052-
Literals.erase(intLiteral);
1053-
return;
1049+
floatLiteral = iter;
10541050
}
10551051
}
1052+
1053+
if (intLiteral != Literals.end() &&
1054+
floatLiteral != Literals.end()) {
1055+
Literals.erase(intLiteral);
1056+
}
10561057
}
10571058

10581059
void BindingSet::addLiteralRequirement(Constraint *constraint) {
10591060
auto *protocol = constraint->getProtocol();
10601061

1061-
if (Literals.count(protocol) > 0)
1062-
return;
1062+
for (const auto &literal : Literals) {
1063+
if (literal.getProtocol() == protocol)
1064+
return;
1065+
}
10631066

10641067
bool isDirect = isDirectRequirement(CS, TypeVar, constraint);
10651068

@@ -1070,8 +1073,7 @@ void BindingSet::addLiteralRequirement(Constraint *constraint) {
10701073
defaultType = TypeChecker::getDefaultType(protocol, CS.DC);
10711074
}
10721075

1073-
LiteralRequirement literal(protocol, constraint, defaultType, isDirect);
1074-
Literals.insert({protocol, std::move(literal)});
1076+
Literals.emplace_back(protocol, constraint, defaultType, isDirect);
10751077
}
10761078

10771079
bool BindingSet::operator==(const BindingSet &other) {
@@ -1081,7 +1083,7 @@ bool BindingSet::operator==(const BindingSet &other) {
10811083
if (Bindings.size() != other.Bindings.size())
10821084
return false;
10831085

1084-
for (auto i : indices(Bindings)) {
1086+
for (unsigned i : indices(Bindings)) {
10851087
const auto &x = Bindings[i];
10861088
const auto &y = other.Bindings[i];
10871089

@@ -1093,13 +1095,9 @@ bool BindingSet::operator==(const BindingSet &other) {
10931095
if (Literals.size() != other.Literals.size())
10941096
return false;
10951097

1096-
for (auto pair : Literals) {
1097-
auto found = other.Literals.find(pair.first);
1098-
if (found == other.Literals.end())
1099-
return false;
1100-
1101-
const auto &x = pair.second;
1102-
const auto &y = found->second;
1098+
for (unsigned i : indices(Literals)) {
1099+
auto &x = Literals[i];
1100+
auto &y = other.Literals[i];
11031101

11041102
if (x.Source != y.Source ||
11051103
x.DefaultType.getPointer() != y.DefaultType.getPointer() ||
@@ -2319,15 +2317,12 @@ void PotentialBindings::dump(ConstraintSystem &cs, TypeVariableType *typeVar,
23192317

23202318
void BindingSet::forEachLiteralRequirement(
23212319
llvm::function_ref<void(KnownProtocolKind)> callback) const {
2322-
for (const auto &literal : Literals) {
2323-
auto *protocol = literal.first;
2324-
const auto &info = literal.second;
2325-
2320+
for (const auto &info : Literals) {
23262321
// Only uncovered defaultable literal protocols participate.
23272322
if (!info.viableAsBinding())
23282323
continue;
23292324

2330-
if (auto protocolKind = protocol->getKnownProtocolKind())
2325+
if (auto protocolKind = info.getProtocol()->getKnownProtocolKind())
23312326
callback(*protocolKind);
23322327
}
23332328
}
@@ -2358,7 +2353,7 @@ LiteralBindingKind BindingSet::getLiteralForScore() const {
23582353

23592354
unsigned BindingSet::getNumViableLiteralBindings() const {
23602355
return llvm::count_if(Literals, [&](const auto &literal) {
2361-
return literal.second.viableAsBinding();
2356+
return literal.viableAsBinding();
23622357
});
23632358
}
23642359

@@ -2496,10 +2491,10 @@ void BindingSet::dump(llvm::raw_ostream &out, unsigned indent) const {
24962491
}
24972492
for (const auto &literal : Literals) {
24982493
potentialBindings.push_back(PrintableBinding::literalDefaultType(
2499-
literal.second.hasDefaultType()
2500-
? literal.second.getDefaultType()
2494+
literal.hasDefaultType()
2495+
? literal.getDefaultType()
25012496
: Type(),
2502-
literal.second.viableAsBinding()));
2497+
literal.viableAsBinding()));
25032498
}
25042499
if (potentialBindings.empty()) {
25052500
out << "<none>";

lib/Sema/CSOptimizer.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1048,9 +1048,9 @@ static void determineBestChoicesInContext(
10481048
}
10491049

10501050
for (const auto &literal : bindingSet.Literals) {
1051-
if (literal.second.hasDefaultType()) {
1051+
if (literal.hasDefaultType()) {
10521052
// Add primary default type
1053-
auto type = restoreOptionality(literal.second.getDefaultType(),
1053+
auto type = restoreOptionality(literal.getDefaultType(),
10541054
optionals.size());
10551055
types.push_back({type,
10561056
/*fromLiteral=*/true});

lib/Sema/CSSolver.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2566,8 +2566,8 @@ void DisjunctionChoice::propagateConversionInfo(ConstraintSystem &cs) const {
25662566
conversionType = bindings.Bindings[0].BindingType;
25672567
} else {
25682568
for (const auto &literal : bindings.Literals) {
2569-
if (literal.second.viableAsBinding()) {
2570-
conversionType = literal.second.getDefaultType();
2569+
if (literal.viableAsBinding()) {
2570+
conversionType = literal.getDefaultType();
25712571
break;
25722572
}
25732573
}

lib/Sema/ConstraintSystem.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5397,9 +5397,7 @@ TypeVarBindingProducer::TypeVarBindingProducer(const BindingSet &bindings)
53975397
}
53985398

53995399
// Infer defaults based on "uncovered" literal protocol requirements.
5400-
for (const auto &info : bindings.Literals) {
5401-
const auto &literal = info.second;
5402-
5400+
for (const auto &literal : bindings.Literals) {
54035401
if (!literal.viableAsBinding())
54045402
continue;
54055403

0 commit comments

Comments
 (0)