@@ -741,7 +741,7 @@ BindingSet::BindingScore BindingSet::formBindingScore(const BindingSet &b) {
741
741
return std::make_tuple (b.isHole (), numNonDefaultableBindings == 0 ,
742
742
b.isDelayed (), b.isSubtypeOfExistentialType (),
743
743
b.involvesTypeVariables (),
744
- static_cast <unsigned char >(b.getLiteralKind ()),
744
+ static_cast <unsigned char >(b.getLiteralForScore ()),
745
745
-numNonDefaultableBindings);
746
746
}
747
747
@@ -1577,18 +1577,26 @@ void PotentialBindings::retract(Constraint *constraint) {
1577
1577
EquivalentTo.remove_if (hasMatchingSource);
1578
1578
}
1579
1579
1580
- LiteralBindingKind BindingSet::getLiteralKind () const {
1581
- LiteralBindingKind kind = LiteralBindingKind::None;
1582
-
1580
+ void BindingSet::forEachLiteralRequirement (
1581
+ llvm::function_ref<void (KnownProtocolKind)> callback) const {
1583
1582
for (const auto &literal : Literals) {
1584
1583
auto *protocol = literal.first ;
1585
1584
const auto &info = literal.second ;
1586
1585
1587
1586
// Only uncovered defaultable literal protocols participate.
1588
1587
if (!info.viableAsBinding ())
1589
1588
continue ;
1589
+
1590
+ if (auto protocolKind = protocol->getKnownProtocolKind ())
1591
+ callback (*protocolKind);
1592
+ }
1593
+ }
1590
1594
1591
- switch (*protocol->getKnownProtocolKind ()) {
1595
+ LiteralBindingKind BindingSet::getLiteralForScore () const {
1596
+ LiteralBindingKind kind = LiteralBindingKind::None;
1597
+
1598
+ forEachLiteralRequirement ([&](KnownProtocolKind protocolKind) {
1599
+ switch (protocolKind) {
1592
1600
case KnownProtocolKind::ExpressibleByDictionaryLiteral:
1593
1601
case KnownProtocolKind::ExpressibleByArrayLiteral:
1594
1602
case KnownProtocolKind::ExpressibleByStringInterpolation:
@@ -1604,8 +1612,7 @@ LiteralBindingKind BindingSet::getLiteralKind() const {
1604
1612
kind = LiteralBindingKind::Atom;
1605
1613
break ;
1606
1614
}
1607
- }
1608
-
1615
+ });
1609
1616
return kind;
1610
1617
}
1611
1618
@@ -1615,6 +1622,39 @@ unsigned BindingSet::getNumViableLiteralBindings() const {
1615
1622
});
1616
1623
}
1617
1624
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
+
1618
1658
void BindingSet::dump (TypeVariableType *typeVar, llvm::raw_ostream &out,
1619
1659
unsigned indent) const {
1620
1660
out.indent (indent);
@@ -1639,17 +1679,39 @@ void BindingSet::dump(llvm::raw_ostream &out, unsigned indent) const {
1639
1679
attributes.push_back (" delayed" );
1640
1680
if (isSubtypeOfExistentialType ())
1641
1681
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
- }
1648
1682
if (!attributes.empty ()) {
1649
1683
out << " [attributes: " ;
1650
1684
interleave (attributes, out, " , " );
1651
- out << " ] " ;
1652
1685
}
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
+
1653
1715
if (involvesTypeVariables ()) {
1654
1716
out << " [involves_type_vars: " ;
1655
1717
interleave (AdjacentVars,
0 commit comments