mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Runtime checking for associated types conforming to invertible protocols
Emit metadata for runtime checks of conformances of associated types to invertible protocols, e.g., `T.Assoc: Copyable`. This allows us to correctly handle, e.g., dynamic casting involving conditional conformances that have such constraints. The model we use here is to emit an invertible-protocol constraint that leaves only the specific bit clear in the invertible protocol set.
This commit is contained in:
@@ -1349,6 +1349,10 @@ bool swift::_swift_class_isSubclass(const Metadata *subclass,
|
||||
return isSubclass(subclass, superclass);
|
||||
}
|
||||
|
||||
static std::optional<TypeLookupError>
|
||||
checkInvertibleRequirements(const Metadata *type,
|
||||
InvertibleProtocolSet ignored);
|
||||
|
||||
static std::optional<TypeLookupError>
|
||||
checkGenericRequirement(
|
||||
const GenericRequirementDescriptor &req,
|
||||
@@ -1445,8 +1449,10 @@ checkGenericRequirement(
|
||||
}
|
||||
case GenericRequirementKind::InvertedProtocols: {
|
||||
uint16_t index = req.getInvertedProtocolsGenericParamIndex();
|
||||
if (index == 0xFFFF)
|
||||
return TYPE_LOOKUP_ERROR_FMT("unable to suppress protocols");
|
||||
if (index == 0xFFFF) {
|
||||
return checkInvertibleRequirements(subjectType,
|
||||
req.getInvertedProtocols());
|
||||
}
|
||||
|
||||
// Expand the suppression set so we can record these protocols.
|
||||
if (index >= suppressed.size()) {
|
||||
@@ -1613,8 +1619,18 @@ checkGenericPackRequirement(
|
||||
|
||||
case GenericRequirementKind::InvertedProtocols: {
|
||||
uint16_t index = req.getInvertedProtocolsGenericParamIndex();
|
||||
if (index == 0xFFFF)
|
||||
return TYPE_LOOKUP_ERROR_FMT("unable to suppress protocols");
|
||||
if (index == 0xFFFF) {
|
||||
// Check that each pack element meets the invertible requirements.
|
||||
for (size_t i = 0, e = subjectType.getNumElements(); i < e; ++i) {
|
||||
const Metadata *elt = subjectType.getElements()[i];
|
||||
|
||||
if (auto error = checkInvertibleRequirements(
|
||||
elt, req.getInvertedProtocols()))
|
||||
return error;
|
||||
}
|
||||
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
// Expand the suppression set so we can record these protocols.
|
||||
if (index >= suppressed.size()) {
|
||||
@@ -1632,10 +1648,6 @@ checkGenericPackRequirement(
|
||||
(unsigned)req.getKind());
|
||||
}
|
||||
|
||||
static std::optional<TypeLookupError>
|
||||
checkInvertibleRequirements(const Metadata *type,
|
||||
InvertibleProtocolSet ignored);
|
||||
|
||||
static std::optional<TypeLookupError>
|
||||
checkInvertibleRequirementsStructural(const Metadata *type,
|
||||
InvertibleProtocolSet ignored) {
|
||||
|
||||
Reference in New Issue
Block a user