21
21
#include " TypeCheckType.h"
22
22
#include " swift/AST/GenericEnvironment.h"
23
23
#include " swift/AST/ParameterList.h"
24
- #include " swift/AST/TypeVisitor.h"
25
24
#include " swift/Basic/Statistic.h"
26
25
#include " llvm/ADT/SetVector.h"
27
26
#include " llvm/ADT/SmallString.h"
@@ -1569,320 +1568,6 @@ Type ConstraintSystem::getEffectiveOverloadType(const OverloadChoice &overload,
1569
1568
return type;
1570
1569
}
1571
1570
1572
- namespace {
1573
- // / Type visitor that extracts the common type between two types, when
1574
- // / possible.
1575
- class CommonTypeVisitor : public TypeVisitor <CommonTypeVisitor, Type, Type> {
1576
- // / Perform a "leaf" match for types, which does not consider the children.
1577
- Type handleLeafMatch (Type type1, Type type2) {
1578
- if (type1->isEqual (type2))
1579
- return type1;
1580
-
1581
- return handleMismatch (type1, type2);
1582
- }
1583
-
1584
- // / Handle a mismatch between two types.
1585
- Type handleMismatch (Type type1, Type type2) {
1586
- return Type ();
1587
- }
1588
-
1589
- public:
1590
- Type visitTupleType (TupleType *tuple1, Type type2) {
1591
- if (tuple1->isEqual (type2))
1592
- return Type (tuple1);
1593
-
1594
- auto tuple2 = type2->getAs <TupleType>();
1595
- if (!tuple2) {
1596
- return handleMismatch (Type (tuple1), type2);
1597
- }
1598
-
1599
- // Check for structural similarity between the two tuple types.
1600
- auto elements1 = tuple1->getElements ();
1601
- auto elements2 = tuple2->getElements ();
1602
- if (elements1.size () != elements2.size ()) {
1603
- return handleMismatch (Type (tuple1), type2);
1604
- }
1605
-
1606
- for (unsigned i : indices (elements1)) {
1607
- const auto &elt1 = elements1[i];
1608
- const auto &elt2 = elements2[i];
1609
- if (elt1.getName () != elt2.getName () ||
1610
- elt1.getParameterFlags () != elt2.getParameterFlags ()) {
1611
- return handleMismatch (Type (tuple1), type2);
1612
- }
1613
- }
1614
-
1615
- // Recurse on the element types.
1616
- SmallVector<TupleTypeElt, 4 > newElements;
1617
- newElements.reserve (elements1.size ());
1618
- for (unsigned i : indices (elements1)) {
1619
- const auto &elt1 = elements1[i];
1620
- const auto &elt2 = elements2[i];
1621
- Type elementType = visit (elt1.getRawType (), elt2.getRawType ());
1622
- if (!elementType) {
1623
- return handleMismatch (Type (tuple1), type2);
1624
- }
1625
-
1626
- newElements.push_back (elt1.getWithType (elementType));
1627
- }
1628
- return TupleType::get (newElements, tuple1->getASTContext ());
1629
- }
1630
-
1631
- Type visitReferenceStorageType (ReferenceStorageType *refStorage1,
1632
- Type type2) {
1633
- if (refStorage1->isEqual (type2))
1634
- return Type (refStorage1);
1635
-
1636
- auto refStorage2 = type2->getAs <ReferenceStorageType>();
1637
- if (!refStorage2 ||
1638
- refStorage1->getOwnership () != refStorage2->getOwnership ()) {
1639
- return handleMismatch (Type (refStorage1), type2);
1640
- }
1641
-
1642
- Type newReferentType = visit (refStorage1->getReferentType (),
1643
- refStorage2->getReferentType ());
1644
- if (!newReferentType) {
1645
- return handleMismatch (Type (refStorage1), type2);
1646
- }
1647
-
1648
- return ReferenceStorageType::get (newReferentType,
1649
- refStorage1->getOwnership (),
1650
- refStorage1->getASTContext ());
1651
- }
1652
-
1653
- Type visitAnyMetatypeType (AnyMetatypeType *metatype1, Type type2) {
1654
- if (metatype1->isEqual (type2))
1655
- return Type (metatype1);
1656
-
1657
-
1658
- auto metatype2 = type2->getAs <AnyMetatypeType>();
1659
- if (!metatype2) {
1660
- return handleMismatch (Type (metatype1), type2);
1661
- }
1662
-
1663
- if (metatype1->getKind () != metatype2->getKind () ||
1664
- metatype1->hasRepresentation () != metatype2->hasRepresentation () ||
1665
- (metatype1->hasRepresentation () &&
1666
- metatype2->getRepresentation () != metatype2->getRepresentation ())) {
1667
- return handleMismatch (Type (metatype1), type2);
1668
- }
1669
-
1670
- Type newInstanceType = visit (metatype1->getInstanceType (),
1671
- metatype2->getInstanceType ());
1672
- if (!newInstanceType) {
1673
- return handleMismatch (Type (metatype1), type2);
1674
- }
1675
-
1676
- Optional<MetatypeRepresentation> representation;
1677
- if (metatype1->hasRepresentation ())
1678
- representation = metatype1->getRepresentation ();
1679
-
1680
- if (metatype1->getKind () == TypeKind::Metatype)
1681
- return MetatypeType::get (newInstanceType, representation);
1682
-
1683
- assert (metatype1->getKind () == TypeKind::ExistentialMetatype);
1684
- return ExistentialMetatypeType::get (newInstanceType, representation);
1685
- }
1686
-
1687
- Type visitFunctionType (FunctionType *function1, Type type2) {
1688
- if (function1->isEqual (type2))
1689
- return Type (function1);
1690
-
1691
- auto function2 = type2->getAs <FunctionType>();
1692
- if (!function2 ||
1693
- function1->getExtInfo () != function2->getExtInfo () ||
1694
- function1->getNumParams () != function2->getNumParams ()) {
1695
- return handleMismatch (Type (function1), type2);
1696
- }
1697
-
1698
- // Check for a structural match between the parameters.
1699
- auto params1 = function1->getParams ();
1700
- auto params2 = function2->getParams ();
1701
- for (unsigned i : indices (params1)) {
1702
- const auto ¶m1 = params1[i];
1703
- const auto ¶m2 = params2[i];
1704
- if (param1.getLabel () != param2.getLabel () ||
1705
- param1.getParameterFlags () != param2.getParameterFlags ()) {
1706
- return handleMismatch (Type (function1), type2);
1707
- }
1708
- }
1709
-
1710
- Type newResultType = visit (function1->getResult (), function2->getResult ());
1711
- if (!newResultType) {
1712
- return handleMismatch (Type (function1), type2);
1713
- }
1714
-
1715
- SmallVector<AnyFunctionType::Param, 4 > newParams;
1716
- newParams.reserve (params1.size ());
1717
- for (unsigned i : indices (params1)) {
1718
- const auto ¶m1 = params1[i];
1719
- const auto ¶m2 = params2[i];
1720
- Type newParamType = visit (param1.getPlainType (), param2.getPlainType ());
1721
- if (!newParamType) {
1722
- return handleMismatch (Type (function1), type2);
1723
- }
1724
-
1725
- newParams.push_back (AnyFunctionType::Param (newParamType,
1726
- param1.getLabel (),
1727
- param1.getParameterFlags ()));
1728
- }
1729
-
1730
- return FunctionType::get (newParams, newResultType, function1->getExtInfo ());
1731
- }
1732
-
1733
- Type visitGenericFunctionType (GenericFunctionType *function1, Type type2) {
1734
- llvm_unreachable (" Caller should have eliminated these" );
1735
- }
1736
-
1737
- Type visitLValueType (LValueType *lvalue1, Type type2) {
1738
- if (lvalue1->isEqual (type2))
1739
- return Type (lvalue1);
1740
-
1741
- auto lvalue2 = type2->getAs <LValueType>();
1742
- if (!lvalue2) {
1743
- return handleMismatch (Type (lvalue1), type2);
1744
- }
1745
-
1746
- Type newObjectType =
1747
- visit (lvalue1->getObjectType (), lvalue2->getObjectType ());
1748
- if (!newObjectType) {
1749
- return handleMismatch (Type (lvalue1), type2);
1750
- }
1751
-
1752
- return LValueType::get (newObjectType);
1753
- }
1754
-
1755
- Type visitInOutType (InOutType *inout1, Type type2) {
1756
- if (inout1->isEqual (type2))
1757
- return Type (inout1);
1758
-
1759
- auto inout2 = type2->getAs <InOutType>();
1760
- if (!inout2) {
1761
- return handleMismatch (Type (inout1), type2);
1762
- }
1763
-
1764
- Type newObjectType =
1765
- visit (inout1->getObjectType (), inout2->getObjectType ());
1766
- if (!newObjectType) {
1767
- return handleMismatch (Type (inout1), type2);
1768
- }
1769
-
1770
- return LValueType::get (newObjectType);
1771
- }
1772
-
1773
- Type visitSugarType (SugarType *sugar1, Type type2) {
1774
- if (sugar1->isEqual (type2))
1775
- return Type (sugar1);
1776
-
1777
- // FIXME: Reconstitute sugar.
1778
- return visit (Type (sugar1->getSinglyDesugaredType ()), type2);
1779
- }
1780
-
1781
- #define FAILURE_CASE (Class ) \
1782
- Type visit##Class##Type(Class##Type *type1, Type type2) { \
1783
- return Type (); \
1784
- }
1785
-
1786
- #define LEAF_CASE (Class ) \
1787
- Type visit##Class##Type(Class##Type *type1, Type type2) { \
1788
- return handleLeafMatch (Type (type1), type2); \
1789
- }
1790
-
1791
- FAILURE_CASE (Error)
1792
- FAILURE_CASE (Unresolved)
1793
- LEAF_CASE (Builtin)
1794
- LEAF_CASE (Nominal) // FIXME: We can do a more specific match here.
1795
- LEAF_CASE (BoundGeneric) // FIXME: We can do a more specific match here.
1796
- FAILURE_CASE (UnboundGeneric)
1797
- LEAF_CASE (Module)
1798
- LEAF_CASE (DynamicSelf) // FIXME: Can we do better here?
1799
- LEAF_CASE (Substitutable)
1800
- LEAF_CASE (DependentMember)
1801
- LEAF_CASE (SILFunction)
1802
- LEAF_CASE (SILBlockStorage)
1803
- LEAF_CASE (SILBox)
1804
- LEAF_CASE (SILToken)
1805
- LEAF_CASE (ProtocolComposition)
1806
- LEAF_CASE (TypeVariable) // FIXME: Could do better here when we create vars
1807
-
1808
- #undef LEAF_CASE
1809
- #undef FAILURE_CASE
1810
- };
1811
-
1812
- }
1813
-
1814
- Type ConstraintSystem::findCommonOverloadType (
1815
- ArrayRef<OverloadChoice> choices,
1816
- ArrayRef<OverloadChoice> outerAlternatives,
1817
- ConstraintLocator *locator) {
1818
- // Local function to consider this new overload choice, updating the
1819
- // "common type". Returns true if this overload cannot be integrated into
1820
- // the common type, at which point there is no "common type".
1821
- Type commonType;
1822
- auto considerOverload = [&](const OverloadChoice &overload) -> bool {
1823
- // If we can't even get a type for the overload, there's nothing more to
1824
- // do.
1825
- Type overloadType =
1826
- getEffectiveOverloadType (overload, /* allowMembers=*/ false , /* FIXME:*/ DC);
1827
- if (!overloadType) {
1828
- return true ;
1829
- }
1830
-
1831
- // If this is the first overload, record it's type as the common type.
1832
- if (!commonType) {
1833
- commonType = overloadType;
1834
- return false ;
1835
- }
1836
-
1837
- // Find the common type between the current common type and the new
1838
- // overload's type.
1839
- commonType = CommonTypeVisitor ().visit (commonType, overloadType);
1840
- if (!commonType) {
1841
- return true ;
1842
- }
1843
-
1844
- return false ;
1845
- };
1846
-
1847
- // Consider all of the choices and outer alternatives.
1848
- for (const auto &choice : choices) {
1849
- if (considerOverload (choice))
1850
- return Type ();
1851
- }
1852
- for (const auto &choice : outerAlternatives) {
1853
- if (considerOverload (choice))
1854
- return Type ();
1855
- }
1856
-
1857
- assert (commonType && " We can't get here without having a common type" );
1858
-
1859
- // If our common type contains any generic parameters, open them up into
1860
- // type variables.
1861
- if (commonType->hasTypeParameter ()) {
1862
- llvm::SmallDenseMap<const GenericTypeParamType *, TypeVariableType *>
1863
- openedGenericParams;
1864
- commonType = commonType.transformRec ([&](TypeBase *type) -> Optional<Type> {
1865
- if (auto genericParam = dyn_cast<GenericTypeParamType>(type)) {
1866
- auto canGenericParam = GenericTypeParamType::get (
1867
- genericParam->getDepth (),
1868
- genericParam->getIndex (),
1869
- type->getASTContext ());
1870
- auto knownTypeVar = openedGenericParams.find (canGenericParam);
1871
- if (knownTypeVar != openedGenericParams.end ())
1872
- return Type (knownTypeVar->second );
1873
-
1874
- auto typeVar = createTypeVariable (locator);
1875
- openedGenericParams[canGenericParam] = typeVar;
1876
- return Type (typeVar);
1877
- }
1878
-
1879
- return None;
1880
- });
1881
- }
1882
-
1883
- return commonType;
1884
- }
1885
-
1886
1571
void ConstraintSystem::addOverloadSet (Type boundType,
1887
1572
ArrayRef<OverloadChoice> choices,
1888
1573
DeclContext *useDC,
@@ -1897,13 +1582,6 @@ void ConstraintSystem::addOverloadSet(Type boundType,
1897
1582
return ;
1898
1583
}
1899
1584
1900
- // If we can compute a common type for the overload set, bind that type.
1901
- if (Type commonType = findCommonOverloadType (choices, outerAlternatives,
1902
- locator)) {
1903
- addConstraint (ConstraintKind::Bind, boundType, commonType, locator);
1904
- boundType = commonType;
1905
- }
1906
-
1907
1585
tryOptimizeGenericDisjunction (*this , choices, favoredChoice);
1908
1586
1909
1587
SmallVector<OverloadChoice, 4 > scratchChoices;
0 commit comments