@@ -741,7 +741,7 @@ BindingSet::BindingScore BindingSet::formBindingScore(const BindingSet &b) {
741741 return std::make_tuple (b.isHole (), numNonDefaultableBindings == 0 ,
742742 b.isDelayed (), b.isSubtypeOfExistentialType (),
743743 b.involvesTypeVariables (),
744- static_cast <unsigned char >(b.getLiteralKind ()),
744+ static_cast <unsigned char >(b.getLiteralForScore ()),
745745 -numNonDefaultableBindings);
746746}
747747
@@ -1577,18 +1577,26 @@ void PotentialBindings::retract(Constraint *constraint) {
15771577 EquivalentTo.remove_if (hasMatchingSource);
15781578}
15791579
1580- LiteralBindingKind BindingSet::getLiteralKind () const {
1581- LiteralBindingKind kind = LiteralBindingKind::None;
1582-
1580+ void BindingSet::forEachLiteralRequirement (
1581+ llvm::function_ref<void (KnownProtocolKind)> callback) const {
15831582 for (const auto &literal : Literals) {
15841583 auto *protocol = literal.first ;
15851584 const auto &info = literal.second ;
15861585
15871586 // Only uncovered defaultable literal protocols participate.
15881587 if (!info.viableAsBinding ())
15891588 continue ;
1589+
1590+ if (auto protocolKind = protocol->getKnownProtocolKind ())
1591+ callback (*protocolKind);
1592+ }
1593+ }
15901594
1591- switch (*protocol->getKnownProtocolKind ()) {
1595+ LiteralBindingKind BindingSet::getLiteralForScore () const {
1596+ LiteralBindingKind kind = LiteralBindingKind::None;
1597+
1598+ forEachLiteralRequirement ([&](KnownProtocolKind protocolKind) {
1599+ switch (protocolKind) {
15921600 case KnownProtocolKind::ExpressibleByDictionaryLiteral:
15931601 case KnownProtocolKind::ExpressibleByArrayLiteral:
15941602 case KnownProtocolKind::ExpressibleByStringInterpolation:
@@ -1604,8 +1612,7 @@ LiteralBindingKind BindingSet::getLiteralKind() const {
16041612 kind = LiteralBindingKind::Atom;
16051613 break ;
16061614 }
1607- }
1608-
1615+ });
16091616 return kind;
16101617}
16111618
@@ -1615,6 +1622,39 @@ unsigned BindingSet::getNumViableLiteralBindings() const {
16151622 });
16161623}
16171624
1625+ // / Return string for atomic literal kinds (integer, string, & boolean) for
1626+ // / printing in debug output.
1627+ static std::string getAtomLiteralAsString (ExprKind EK) {
1628+ #define ENTRY (Kind, String ) \
1629+ case ExprKind::Kind: \
1630+ return String
1631+ switch (EK) {
1632+ ENTRY (IntegerLiteral, " integer" );
1633+ ENTRY (StringLiteral, " string" );
1634+ ENTRY (BooleanLiteral, " boolean" );
1635+ ENTRY (NilLiteral, " nil" );
1636+ default :
1637+ return " " ;
1638+ }
1639+ #undef ENTRY
1640+ }
1641+
1642+ // / Return string for collection literal kinds (interpolated string, array,
1643+ // / dictionary) for printing in debug output.
1644+ static std::string getCollectionLiteralAsString (KnownProtocolKind KPK) {
1645+ #define ENTRY (Kind, String ) \
1646+ case KnownProtocolKind::Kind: \
1647+ return String
1648+ switch (KPK) {
1649+ ENTRY (ExpressibleByDictionaryLiteral, " dictionary" );
1650+ ENTRY (ExpressibleByArrayLiteral, " array" );
1651+ ENTRY (ExpressibleByStringInterpolation, " interpolated string" );
1652+ default :
1653+ return " " ;
1654+ }
1655+ #undef ENTRY
1656+ }
1657+
16181658void BindingSet::dump (TypeVariableType *typeVar, llvm::raw_ostream &out,
16191659 unsigned indent) const {
16201660 out.indent (indent);
@@ -1639,17 +1679,39 @@ void BindingSet::dump(llvm::raw_ostream &out, unsigned indent) const {
16391679 attributes.push_back (" delayed" );
16401680 if (isSubtypeOfExistentialType ())
16411681 attributes.push_back (" subtype_of_existential" );
1642- auto literalKind = getLiteralKind ();
1643- if (literalKind != LiteralBindingKind::None) {
1644- auto literalAttrStr = (" [literal: " + getLiteralBindingKind (literalKind)
1645- + " ]" ).str ();
1646- attributes.push_back (literalAttrStr);
1647- }
16481682 if (!attributes.empty ()) {
16491683 out << " [attributes: " ;
16501684 interleave (attributes, out, " , " );
1651- out << " ] " ;
16521685 }
1686+
1687+ auto literalKind = getLiteralForScore ();
1688+ if (literalKind != LiteralBindingKind::None) {
1689+ out << " , [literal: " ;
1690+ switch (literalKind) {
1691+ case LiteralBindingKind::Atom: {
1692+ if (auto atomKind = TypeVar->getImpl ().getAtomicLiteralKind ()) {
1693+ out << getAtomLiteralAsString (*atomKind);
1694+ }
1695+ break ;
1696+ }
1697+ case LiteralBindingKind::Collection: {
1698+ std::vector<std::string> collectionLiterals;
1699+ forEachLiteralRequirement ([&](KnownProtocolKind protocolKind) {
1700+ collectionLiterals.push_back (
1701+ getCollectionLiteralAsString (protocolKind));
1702+ });
1703+ interleave (collectionLiterals, out, " , " );
1704+ break ;
1705+ }
1706+ case LiteralBindingKind::Float:
1707+ case LiteralBindingKind::None:
1708+ out << getLiteralBindingKind (literalKind).str ();
1709+ break ;
1710+ }
1711+ out << " ]" ;
1712+ }
1713+ out << " ] " ;
1714+
16531715 if (involvesTypeVariables ()) {
16541716 out << " [involves_type_vars: " ;
16551717 interleave (AdjacentVars,
0 commit comments