Skip to content

Commit 74fa1e7

Browse files
committed
Sema: BindingSet::Literals can just be a vector and not a map
1 parent 6c1593a commit 74fa1e7

File tree

6 files changed

+46
-53
lines changed

6 files changed

+46
-53
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() ||
@@ -2324,15 +2322,12 @@ void PotentialBindings::dump(ConstraintSystem &cs, TypeVariableType *typeVar,
23242322

23252323
void BindingSet::forEachLiteralRequirement(
23262324
llvm::function_ref<void(KnownProtocolKind)> callback) const {
2327-
for (const auto &literal : Literals) {
2328-
auto *protocol = literal.first;
2329-
const auto &info = literal.second;
2330-
2325+
for (const auto &info : Literals) {
23312326
// Only uncovered defaultable literal protocols participate.
23322327
if (!info.viableAsBinding())
23332328
continue;
23342329

2335-
if (auto protocolKind = protocol->getKnownProtocolKind())
2330+
if (auto protocolKind = info.getProtocol()->getKnownProtocolKind())
23362331
callback(*protocolKind);
23372332
}
23382333
}
@@ -2363,7 +2358,7 @@ LiteralBindingKind BindingSet::getLiteralForScore() const {
23632358

23642359
unsigned BindingSet::getNumViableLiteralBindings() const {
23652360
return llvm::count_if(Literals, [&](const auto &literal) {
2366-
return literal.second.viableAsBinding();
2361+
return literal.viableAsBinding();
23672362
});
23682363
}
23692364

@@ -2501,10 +2496,10 @@ void BindingSet::dump(llvm::raw_ostream &out, unsigned indent) const {
25012496
}
25022497
for (const auto &literal : Literals) {
25032498
potentialBindings.push_back(PrintableBinding::literalDefaultType(
2504-
literal.second.hasDefaultType()
2505-
? literal.second.getDefaultType()
2499+
literal.hasDefaultType()
2500+
? literal.getDefaultType()
25062501
: Type(),
2507-
literal.second.viableAsBinding()));
2502+
literal.viableAsBinding()));
25082503
}
25092504
if (potentialBindings.empty()) {
25102505
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

unittests/Sema/BindingInferenceTests.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ TEST_F(SemaTest, TestIntLiteralBindingInference) {
4242

4343
ASSERT_EQ(bindings.Literals.size(), (unsigned)1);
4444

45-
const auto &literal = bindings.Literals.front().second;
45+
const auto &literal = bindings.Literals.front();
4646

4747
ASSERT_TRUE(literal.hasDefaultType());
4848
ASSERT_TRUE(literal.getDefaultType()->isEqual(intTy));
@@ -65,7 +65,7 @@ TEST_F(SemaTest, TestIntLiteralBindingInference) {
6565

6666
ASSERT_TRUE(bindings.Bindings[0].BindingType->isEqual(intTy));
6767

68-
const auto &literal = bindings.Literals.front().second;
68+
const auto &literal = bindings.Literals.front();
6969
ASSERT_TRUE(literal.isCovered());
7070
ASSERT_TRUE(literal.isDirectRequirement());
7171
ASSERT_TRUE(literal.getDefaultType()->isEqual(intTy));
@@ -99,7 +99,7 @@ TEST_F(SemaTest, TestIntLiteralBindingInference) {
9999

100100
ASSERT_TRUE(bindings.Bindings[0].BindingType->isEqual(floatTy));
101101

102-
const auto &literal = bindings.Literals.front().second;
102+
const auto &literal = bindings.Literals.front();
103103
ASSERT_TRUE(literal.isCovered());
104104
ASSERT_TRUE(literal.isDirectRequirement());
105105
ASSERT_FALSE(literal.getDefaultType()->isEqual(floatTy));
@@ -140,7 +140,7 @@ TEST_F(SemaTest, TestIntLiteralBindingInference) {
140140
// Inferred literal requirement through `$T_float` as well.
141141
ASSERT_EQ(bindings.Literals.size(), (unsigned)1);
142142

143-
const auto &literal = bindings.Literals.front().second;
143+
const auto &literal = bindings.Literals.front();
144144

145145
ASSERT_TRUE(literal.isCovered());
146146
ASSERT_FALSE(literal.isDirectRequirement());

0 commit comments

Comments
 (0)