mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
[SE-0470] Prohibit isolated conformances in dynamic casts marked as such
Certain dynamic casts cannot work safely with isolated conformances, regardless of what executor the code runs on. For such cases, reject all attempts to conform to the type.
This commit is contained in:
@@ -614,12 +614,19 @@ bool swift::_conformsToProtocolInContext(
|
||||
const OpaqueValue *value,
|
||||
const Metadata *type,
|
||||
ProtocolDescriptorRef protocol,
|
||||
const WitnessTable **conformance) {
|
||||
const WitnessTable **conformance,
|
||||
bool prohibitIsolatedConformances) {
|
||||
|
||||
ConformanceExecutionContext context;
|
||||
if (!_conformsToProtocol(value, type, protocol, conformance, &context))
|
||||
return false;
|
||||
|
||||
// If we aren't allowed to use isolated conformances and we ended up with
|
||||
// one, fail.
|
||||
if (prohibitIsolatedConformances &&
|
||||
context.globalActorIsolationType)
|
||||
return false;
|
||||
|
||||
if (!swift_isInConformanceExecutionContext(type, &context))
|
||||
return false;
|
||||
|
||||
@@ -631,7 +638,8 @@ bool swift::_conformsToProtocolInContext(
|
||||
static bool _conformsToProtocols(const OpaqueValue *value,
|
||||
const Metadata *type,
|
||||
const ExistentialTypeMetadata *existentialType,
|
||||
const WitnessTable **conformances) {
|
||||
const WitnessTable **conformances,
|
||||
bool prohibitIsolatedConformances) {
|
||||
if (auto *superclass = existentialType->getSuperclassConstraint()) {
|
||||
if (!swift_dynamicCastMetatype(type, superclass))
|
||||
return false;
|
||||
@@ -644,7 +652,7 @@ static bool _conformsToProtocols(const OpaqueValue *value,
|
||||
|
||||
for (auto protocol : existentialType->getProtocols()) {
|
||||
if (!_conformsToProtocolInContext(
|
||||
value, type, protocol, conformances))
|
||||
value, type, protocol, conformances, prohibitIsolatedConformances))
|
||||
return false;
|
||||
if (conformances != nullptr && protocol.needsWitnessTable()) {
|
||||
assert(*conformances != nullptr);
|
||||
@@ -1050,9 +1058,10 @@ swift_dynamicCastMetatypeImpl(const Metadata *sourceType,
|
||||
}
|
||||
|
||||
static const Metadata *
|
||||
swift_dynamicCastMetatypeUnconditionalImpl(const Metadata *sourceType,
|
||||
const Metadata *targetType,
|
||||
const char *file, unsigned line, unsigned column) {
|
||||
swift_dynamicCastMetatypeUnconditionalImpl(
|
||||
const Metadata *sourceType,
|
||||
const Metadata *targetType,
|
||||
const char *file, unsigned line, unsigned column) {
|
||||
auto origSourceType = sourceType;
|
||||
|
||||
// Identical types always succeed
|
||||
@@ -1138,7 +1147,8 @@ swift_dynamicCastMetatypeUnconditionalImpl(const Metadata *sourceType,
|
||||
|
||||
case MetadataKind::Existential: {
|
||||
auto targetTypeAsExistential = static_cast<const ExistentialTypeMetadata *>(targetType);
|
||||
if (_conformsToProtocols(nullptr, sourceType, targetTypeAsExistential, nullptr))
|
||||
if (_conformsToProtocols(nullptr, sourceType, targetTypeAsExistential,
|
||||
nullptr, /*prohibitIsolatedConformances=*/false))
|
||||
return origSourceType;
|
||||
swift_dynamicCastFailure(sourceType, targetType);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user