@@ -1632,16 +1632,96 @@ checkGenericPackRequirement(
1632
1632
(unsigned )req.getKind ());
1633
1633
}
1634
1634
1635
+ static std::optional<TypeLookupError>
1636
+ checkSuppressibleRequirements (const Metadata *type,
1637
+ SuppressibleProtocolSet ignored);
1638
+
1635
1639
static std::optional<TypeLookupError>
1636
1640
checkSuppressibleRequirementsStructural (const Metadata *type,
1637
1641
SuppressibleProtocolSet ignored) {
1638
- // FIXME: Implement me!
1642
+ switch (type->getKind ()) {
1643
+ case MetadataKind::Class:
1644
+ case MetadataKind::Struct:
1645
+ case MetadataKind::Enum:
1646
+ case MetadataKind::Optional:
1647
+ case MetadataKind::ForeignClass:
1648
+ case MetadataKind::ForeignReferenceType:
1649
+ case MetadataKind::ObjCClassWrapper:
1650
+ // All handled via context descriptor in the caller.
1651
+ return std::nullopt;
1652
+
1653
+ case MetadataKind::HeapLocalVariable:
1654
+ case MetadataKind::Opaque:
1655
+ case MetadataKind::HeapGenericLocalVariable:
1656
+ case MetadataKind::ErrorObject:
1657
+ case MetadataKind::Task:
1658
+ case MetadataKind::Job:
1659
+ // Not part of the user-visible type system; assumed to handle all
1660
+ // suppressible requirements.
1661
+ return std::nullopt;
1662
+
1663
+ case MetadataKind::Tuple: {
1664
+ // Check every element type in the tuple.
1665
+ auto tupleMetadata = cast<TupleTypeMetadata>(type);
1666
+ for (unsigned i = 0 , n = tupleMetadata->NumElements ; i != n; ++i) {
1667
+ if (auto error =
1668
+ checkSuppressibleRequirements (&*tupleMetadata->getElement (i).Type ,
1669
+ ignored))
1670
+ return error;
1671
+ }
1672
+ return std::nullopt;
1673
+ }
1674
+
1675
+ case MetadataKind::Function: {
1676
+ // FIXME: Implement me
1677
+ return std::nullopt;
1678
+ }
1679
+
1680
+ case MetadataKind::ExtendedExistential: {
1681
+ auto existential = cast<ExtendedExistentialTypeMetadata>(type);
1682
+ auto &shape = *existential->Shape ;
1683
+ llvm::ArrayRef<GenericRequirementDescriptor> reqs (
1684
+ shape.getReqSigRequirements (), shape.getNumReqSigRequirements ());
1685
+ // Look for any suppressed protocol requirements. If the existential
1686
+ // has suppressed a protocol that is not ignored, then the existential
1687
+ // does not meet the specified requirements.
1688
+ for (const auto & req : reqs) {
1689
+ if (req.getKind () != GenericRequirementKind::SuppressedProtocols)
1690
+ continue ;
1691
+
1692
+ auto suppressed = req.getSuppressedProtocols ();
1693
+ auto missing = suppressed - ignored;
1694
+ if (!missing.empty ()) {
1695
+ return TYPE_LOOKUP_ERROR_FMT (
1696
+ " existential type missing suppresible protocols %x" ,
1697
+ missing.rawBits ());
1698
+ }
1699
+ }
1700
+
1701
+ return std::nullopt;
1702
+ }
1703
+
1704
+ case MetadataKind::Metatype:
1705
+ case MetadataKind::ExistentialMetatype:
1706
+ // Metatypes themselves can't have suppressible protocols.
1707
+ return std::nullopt;
1708
+
1709
+ case MetadataKind::Existential:
1710
+ // The existential representation has no room for specifying any
1711
+ // suppressed requirements, so it always succeeds.
1712
+ return std::nullopt;
1713
+
1714
+ case MetadataKind::LastEnumerated:
1715
+ break ;
1716
+ }
1717
+
1718
+ // Just accept any unknown types.
1639
1719
return std::nullopt;
1640
1720
}
1641
1721
1642
1722
// / Check that the given `type` meets all suppressible protocol requirements
1643
1723
// / that haven't been explicitly suppressed by `ignored`.
1644
- static std::optional<TypeLookupError>
1724
+ std::optional<TypeLookupError>
1645
1725
checkSuppressibleRequirements (const Metadata *type,
1646
1726
SuppressibleProtocolSet ignored) {
1647
1727
auto contextDescriptor = type->getTypeContextDescriptor ();
@@ -1763,32 +1843,47 @@ std::optional<TypeLookupError> swift::_checkGenericRequirements(
1763
1843
if (index < allSuppressed.size ())
1764
1844
suppressed = allSuppressed[index];
1765
1845
1846
+ MetadataOrPack metadataOrPack (substGenericParamOrdinal (index));
1766
1847
switch (genericParams[index].getKind ()) {
1767
- case GenericParamKind::Type:
1768
- break ;
1848
+ case GenericParamKind::Type: {
1849
+ if (!metadataOrPack || metadataOrPack.isMetadataPack ()) {
1850
+ return TYPE_LOOKUP_ERROR_FMT (
1851
+ " unexpected pack for generic parameter %u" , index);
1852
+ }
1769
1853
1770
- case GenericParamKind::TypePack:
1771
- // FIXME: variadic generics
1772
- continue ;
1854
+ auto metadata = metadataOrPack. getMetadata ();
1855
+ if ( auto error = checkSuppressibleRequirements (metadata, suppressed))
1856
+ return error ;
1773
1857
1774
- default :
1775
- return TYPE_LOOKUP_ERROR_FMT (" unknown generic parameter kind %u" ,
1776
- index);
1858
+ break ;
1777
1859
}
1778
1860
1779
- MetadataOrPack metadataOrPack ( substGenericParamOrdinal (index));
1780
- if (!metadataOrPack)
1781
- return TYPE_LOOKUP_ERROR_FMT ( " unable to find generic argument %u " ,
1782
- index) ;
1861
+ case GenericParamKind::TypePack: {
1862
+ // NULL can be used to indicate an empty pack.
1863
+ if (!metadataOrPack)
1864
+ break ;
1783
1865
1784
- if (metadataOrPack.isMetadataPack ()) {
1785
- // FIXME: variadic generics
1786
- continue ;
1866
+ if (metadataOrPack.isMetadata ()) {
1867
+ return TYPE_LOOKUP_ERROR_FMT (
1868
+ " unexpected metadata for generic pack parameter %u" , index);
1869
+ }
1870
+
1871
+ auto pack = metadataOrPack.getMetadataPack ();
1872
+ if (pack.getElements () != 0 ) {
1873
+ llvm::ArrayRef<const Metadata *> elements (
1874
+ pack.getElements (), pack.getNumElements ());
1875
+ for (auto element : elements) {
1876
+ if (auto error = checkSuppressibleRequirements (element, suppressed))
1877
+ return error;
1878
+ }
1879
+ }
1880
+ break ;
1787
1881
}
1788
1882
1789
- auto metadata = metadataOrPack.getMetadata ();
1790
- if (auto error = checkSuppressibleRequirements (metadata, suppressed))
1791
- return error;
1883
+ default :
1884
+ return TYPE_LOOKUP_ERROR_FMT (" unknown generic parameter kind %u" ,
1885
+ index);
1886
+ }
1792
1887
}
1793
1888
1794
1889
// Success!
0 commit comments