@@ -86,9 +86,12 @@ bool BindingSet::forGenericParameter() const {
8686}
8787
8888bool 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
9497bool 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
10341035void 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
10581059void 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
10771079bool 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
23252323void 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
23642359unsigned 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>" ;
0 commit comments