@@ -1632,16 +1632,96 @@ checkGenericPackRequirement(
16321632 (unsigned )req.getKind ());
16331633}
16341634
1635+ static std::optional<TypeLookupError>
1636+ checkSuppressibleRequirements (const Metadata *type,
1637+ SuppressibleProtocolSet ignored);
1638+
16351639static std::optional<TypeLookupError>
16361640checkSuppressibleRequirementsStructural (const Metadata *type,
16371641 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.
16391719 return std::nullopt ;
16401720}
16411721
16421722// / Check that the given `type` meets all suppressible protocol requirements
16431723// / that haven't been explicitly suppressed by `ignored`.
1644- static std::optional<TypeLookupError>
1724+ std::optional<TypeLookupError>
16451725checkSuppressibleRequirements (const Metadata *type,
16461726 SuppressibleProtocolSet ignored) {
16471727 auto contextDescriptor = type->getTypeContextDescriptor ();
@@ -1763,32 +1843,47 @@ std::optional<TypeLookupError> swift::_checkGenericRequirements(
17631843 if (index < allSuppressed.size ())
17641844 suppressed = allSuppressed[index];
17651845
1846+ MetadataOrPack metadataOrPack (substGenericParamOrdinal (index));
17661847 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+ }
17691853
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 ;
17731857
1774- default :
1775- return TYPE_LOOKUP_ERROR_FMT (" unknown generic parameter kind %u" ,
1776- index);
1858+ break ;
17771859 }
17781860
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 ;
17831865
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 ;
17871881 }
17881882
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+ }
17921887 }
17931888
17941889 // Success!
0 commit comments