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:
@@ -87,7 +87,7 @@ typedef DynamicCastResult (tryCastFunctionType)(
|
||||
OpaqueValue *destLocation, const Metadata *destType,
|
||||
OpaqueValue *srcValue, const Metadata *srcType,
|
||||
const Metadata *&destFailureType, const Metadata *&srcFailureType,
|
||||
bool takeOnSuccess, bool mayDeferChecks
|
||||
bool takeOnSuccess, bool mayDeferChecks, bool prohibitIsolatedConformances
|
||||
);
|
||||
|
||||
// Forward-declare the main top-level `tryCast()` function
|
||||
@@ -401,7 +401,7 @@ tryCastUnwrappingObjCSwiftValueSource(
|
||||
OpaqueValue *destLocation, const Metadata *destType,
|
||||
OpaqueValue *srcValue, const Metadata *srcType,
|
||||
const Metadata *&destFailureType, const Metadata *&srcFailureType,
|
||||
bool takeOnSuccess, bool mayDeferChecks)
|
||||
bool takeOnSuccess, bool mayDeferChecks, bool prohibitIsolatedConformances)
|
||||
{
|
||||
id srcObject;
|
||||
memcpy(&srcObject, srcValue, sizeof(id));
|
||||
@@ -422,7 +422,7 @@ tryCastUnwrappingObjCSwiftValueSource(
|
||||
destLocation, destType,
|
||||
const_cast<OpaqueValue *>(srcInnerValue), srcInnerType,
|
||||
destFailureType, srcFailureType,
|
||||
/*takeOnSuccess=*/ false, mayDeferChecks);
|
||||
/*takeOnSuccess=*/ false, mayDeferChecks, prohibitIsolatedConformances);
|
||||
}
|
||||
#else
|
||||
static DynamicCastResult
|
||||
@@ -430,7 +430,7 @@ tryCastUnwrappingSwiftValueSource(
|
||||
OpaqueValue *destLocation, const Metadata *destType,
|
||||
OpaqueValue *srcValue, const Metadata *srcType,
|
||||
const Metadata *&destFailureType, const Metadata *&srcFailureType,
|
||||
bool takeOnSuccess, bool mayDeferChecks)
|
||||
bool takeOnSuccess, bool mayDeferChecks, bool prohibitIsolatedConformances)
|
||||
{
|
||||
assert(srcType->getKind() == MetadataKind::Class);
|
||||
|
||||
@@ -452,7 +452,7 @@ tryCastToSwiftClass(
|
||||
OpaqueValue *destLocation, const Metadata *destType,
|
||||
OpaqueValue *srcValue, const Metadata *srcType,
|
||||
const Metadata *&destFailureType, const Metadata *&srcFailureType,
|
||||
bool takeOnSuccess, bool mayDeferChecks)
|
||||
bool takeOnSuccess, bool mayDeferChecks, bool prohibitIsolatedConformances)
|
||||
{
|
||||
assert(srcType != destType);
|
||||
assert(destType->getKind() == MetadataKind::Class);
|
||||
@@ -496,7 +496,7 @@ tryCastToObjectiveCClass(
|
||||
OpaqueValue *destLocation, const Metadata *destType,
|
||||
OpaqueValue *srcValue, const Metadata *srcType,
|
||||
const Metadata *&destFailureType, const Metadata *&srcFailureType,
|
||||
bool takeOnSuccess, bool mayDeferChecks)
|
||||
bool takeOnSuccess, bool mayDeferChecks, bool prohibitIsolatedConformances)
|
||||
{
|
||||
assert(srcType != destType);
|
||||
assert(destType->getKind() == MetadataKind::ObjCClassWrapper);
|
||||
@@ -546,7 +546,7 @@ tryCastToForeignClass(
|
||||
OpaqueValue *destLocation, const Metadata *destType,
|
||||
OpaqueValue *srcValue, const Metadata *srcType,
|
||||
const Metadata *&destFailureType, const Metadata *&srcFailureType,
|
||||
bool takeOnSuccess, bool mayDeferChecks)
|
||||
bool takeOnSuccess, bool mayDeferChecks, bool prohibitIsolatedConformances)
|
||||
{
|
||||
#if SWIFT_OBJC_INTEROP
|
||||
assert(srcType != destType);
|
||||
@@ -594,7 +594,8 @@ tryCastToForeignClass(
|
||||
static DynamicCastResult tryCastToForeignReferenceType(
|
||||
OpaqueValue *destLocation, const Metadata *destType, OpaqueValue *srcValue,
|
||||
const Metadata *srcType, const Metadata *&destFailureType,
|
||||
const Metadata *&srcFailureType, bool takeOnSuccess, bool mayDeferChecks) {
|
||||
const Metadata *&srcFailureType, bool takeOnSuccess, bool mayDeferChecks,
|
||||
bool prohibitIsolatedConformances) {
|
||||
assert(srcType != destType);
|
||||
assert(destType->getKind() == MetadataKind::ForeignReferenceType);
|
||||
|
||||
@@ -610,7 +611,7 @@ tryCastToEnum(
|
||||
OpaqueValue *destLocation, const Metadata *destType,
|
||||
OpaqueValue *srcValue, const Metadata *srcType,
|
||||
const Metadata *&destFailureType, const Metadata *&srcFailureType,
|
||||
bool takeOnSuccess, bool mayDeferChecks)
|
||||
bool takeOnSuccess, bool mayDeferChecks, bool prohibitIsolatedConformances)
|
||||
{
|
||||
assert(srcType != destType);
|
||||
// Note: Optional is handled elsewhere
|
||||
@@ -783,7 +784,7 @@ tryCastToAnyHashable(
|
||||
OpaqueValue *destLocation, const Metadata *destType,
|
||||
OpaqueValue *srcValue, const Metadata *srcType,
|
||||
const Metadata *&destFailureType, const Metadata *&srcFailureType,
|
||||
bool takeOnSuccess, bool mayDeferChecks)
|
||||
bool takeOnSuccess, bool mayDeferChecks, bool prohibitIsolatedConformances)
|
||||
{
|
||||
assert(srcType != destType);
|
||||
assert(destType->getKind() == MetadataKind::Struct);
|
||||
@@ -859,7 +860,7 @@ tryCastToArray(
|
||||
OpaqueValue *destLocation, const Metadata *destType,
|
||||
OpaqueValue *srcValue, const Metadata *srcType,
|
||||
const Metadata *&destFailureType, const Metadata *&srcFailureType,
|
||||
bool takeOnSuccess, bool mayDeferChecks)
|
||||
bool takeOnSuccess, bool mayDeferChecks, bool prohibitIsolatedConformances)
|
||||
{
|
||||
assert(srcType != destType);
|
||||
assert(destType->getKind() == MetadataKind::Struct);
|
||||
@@ -899,7 +900,7 @@ tryCastToDictionary(
|
||||
OpaqueValue *destLocation, const Metadata *destType,
|
||||
OpaqueValue *srcValue, const Metadata *srcType,
|
||||
const Metadata *&destFailureType, const Metadata *&srcFailureType,
|
||||
bool takeOnSuccess, bool mayDeferChecks)
|
||||
bool takeOnSuccess, bool mayDeferChecks, bool prohibitIsolatedConformances)
|
||||
{
|
||||
assert(srcType != destType);
|
||||
assert(destType->getKind() == MetadataKind::Struct);
|
||||
@@ -940,7 +941,7 @@ tryCastToSet(
|
||||
OpaqueValue *destLocation, const Metadata *destType,
|
||||
OpaqueValue *srcValue, const Metadata *srcType,
|
||||
const Metadata *&destFailureType, const Metadata *&srcFailureType,
|
||||
bool takeOnSuccess, bool mayDeferChecks)
|
||||
bool takeOnSuccess, bool mayDeferChecks, bool prohibitIsolatedConformances)
|
||||
{
|
||||
assert(srcType != destType);
|
||||
assert(destType->getKind() == MetadataKind::Struct);
|
||||
@@ -982,7 +983,7 @@ tryCastToString(
|
||||
OpaqueValue *destLocation, const Metadata *destType,
|
||||
OpaqueValue *srcValue, const Metadata *srcType,
|
||||
const Metadata *&destFailureType, const Metadata *&srcFailureType,
|
||||
bool takeOnSuccess, bool mayDeferChecks)
|
||||
bool takeOnSuccess, bool mayDeferChecks, bool prohibitIsolatedConformances)
|
||||
{
|
||||
assert(srcType != destType);
|
||||
assert(destType->getKind() == MetadataKind::Struct);
|
||||
@@ -1013,7 +1014,7 @@ tryCastToStruct(
|
||||
OpaqueValue *destLocation, const Metadata *destType,
|
||||
OpaqueValue *srcValue, const Metadata *srcType,
|
||||
const Metadata *&destFailureType, const Metadata *&srcFailureType,
|
||||
bool takeOnSuccess, bool mayDeferChecks)
|
||||
bool takeOnSuccess, bool mayDeferChecks, bool prohibitIsolatedConformances)
|
||||
{
|
||||
assert(srcType != destType);
|
||||
assert(destType->getKind() == MetadataKind::Struct);
|
||||
@@ -1036,7 +1037,7 @@ tryCastToOptional(
|
||||
OpaqueValue *destLocation, const Metadata *destType,
|
||||
OpaqueValue *srcValue, const Metadata *srcType,
|
||||
const Metadata *&destFailureType, const Metadata *&srcFailureType,
|
||||
bool takeOnSuccess, bool mayDeferChecks)
|
||||
bool takeOnSuccess, bool mayDeferChecks, bool prohibitIsolatedConformances)
|
||||
{
|
||||
assert(srcType != destType);
|
||||
assert(destType->getKind() == MetadataKind::Optional);
|
||||
@@ -1110,7 +1111,7 @@ tryCastUnwrappingOptionalBoth(
|
||||
OpaqueValue *destLocation, const Metadata *destType,
|
||||
OpaqueValue *srcValue, const Metadata *srcType,
|
||||
const Metadata *&destFailureType, const Metadata *&srcFailureType,
|
||||
bool takeOnSuccess, bool mayDeferChecks)
|
||||
bool takeOnSuccess, bool mayDeferChecks, bool prohibitIsolatedConformances)
|
||||
{
|
||||
assert(destType->getKind() == MetadataKind::Optional);
|
||||
assert(srcType->getKind() == MetadataKind::Optional);
|
||||
@@ -1134,7 +1135,8 @@ tryCastUnwrappingOptionalBoth(
|
||||
auto destInnerLocation = destLocation; // Single-payload enum layout
|
||||
auto subcastResult = tryCast(
|
||||
destInnerLocation, destInnerType, srcValue, srcInnerType,
|
||||
destFailureType, srcFailureType, takeOnSuccess, mayDeferChecks);
|
||||
destFailureType, srcFailureType, takeOnSuccess, mayDeferChecks,
|
||||
prohibitIsolatedConformances);
|
||||
if (isSuccess(subcastResult)) {
|
||||
destInnerType->vw_storeEnumTagSinglePayload(
|
||||
destLocation, /*case*/ 0, /*emptyCases*/ 1);
|
||||
@@ -1153,7 +1155,7 @@ tryCastUnwrappingOptionalDestination(
|
||||
OpaqueValue *destLocation, const Metadata *destType,
|
||||
OpaqueValue *srcValue, const Metadata *srcType,
|
||||
const Metadata *&destFailureType, const Metadata *&srcFailureType,
|
||||
bool takeOnSuccess, bool mayDeferChecks)
|
||||
bool takeOnSuccess, bool mayDeferChecks, bool prohibitIsolatedConformances)
|
||||
{
|
||||
assert(destType->getKind() == MetadataKind::Optional);
|
||||
|
||||
@@ -1162,7 +1164,8 @@ tryCastUnwrappingOptionalDestination(
|
||||
auto destInnerLocation = destLocation; // Single-payload enum layout
|
||||
auto subcastResult = tryCast(
|
||||
destInnerLocation, destInnerType, srcValue, srcType,
|
||||
destFailureType, srcFailureType, takeOnSuccess, mayDeferChecks);
|
||||
destFailureType, srcFailureType, takeOnSuccess, mayDeferChecks,
|
||||
prohibitIsolatedConformances);
|
||||
if (isSuccess(subcastResult)) {
|
||||
destInnerType->vw_storeEnumTagSinglePayload(
|
||||
destLocation, /*case*/ 0, /*emptyCases*/ 1);
|
||||
@@ -1179,7 +1182,7 @@ tryCastUnwrappingOptionalSource(
|
||||
OpaqueValue *destLocation, const Metadata *destType,
|
||||
OpaqueValue *srcValue, const Metadata *srcType,
|
||||
const Metadata *&destFailureType, const Metadata *&srcFailureType,
|
||||
bool takeOnSuccess, bool mayDeferChecks)
|
||||
bool takeOnSuccess, bool mayDeferChecks, bool prohibitIsolatedConformances)
|
||||
{
|
||||
assert(srcType->getKind() == MetadataKind::Optional);
|
||||
|
||||
@@ -1190,7 +1193,8 @@ tryCastUnwrappingOptionalSource(
|
||||
if (nonNil) {
|
||||
// Recurse with unwrapped source
|
||||
return tryCast(destLocation, destType, srcValue, srcInnerType,
|
||||
destFailureType, srcFailureType, takeOnSuccess, mayDeferChecks);
|
||||
destFailureType, srcFailureType, takeOnSuccess, mayDeferChecks,
|
||||
prohibitIsolatedConformances);
|
||||
}
|
||||
return DynamicCastResult::Failure;
|
||||
}
|
||||
@@ -1208,7 +1212,7 @@ tryCastToTuple(
|
||||
OpaqueValue *destLocation, const Metadata *destType,
|
||||
OpaqueValue *srcValue, const Metadata *srcType,
|
||||
const Metadata *&destFailureType, const Metadata *&srcFailureType,
|
||||
bool takeOnSuccess, bool mayDeferChecks)
|
||||
bool takeOnSuccess, bool mayDeferChecks, bool prohibitIsolatedConformances)
|
||||
{
|
||||
assert(srcType != destType);
|
||||
assert(destType->getKind() == MetadataKind::Tuple);
|
||||
@@ -1284,7 +1288,8 @@ tryCastToTuple(
|
||||
auto subcastResult = tryCast(destElt.findIn(destLocation), destElt.Type,
|
||||
srcElt.findIn(srcValue), srcElt.Type,
|
||||
destFailureType, srcFailureType,
|
||||
false, mayDeferChecks);
|
||||
false, mayDeferChecks,
|
||||
prohibitIsolatedConformances);
|
||||
if (subcastResult == DynamicCastResult::Failure) {
|
||||
for (unsigned k = 0; k != j; ++k) {
|
||||
const auto &elt = destTupleType->getElement(k);
|
||||
@@ -1310,7 +1315,7 @@ tryCastToFunction(
|
||||
OpaqueValue *destLocation, const Metadata *destType,
|
||||
OpaqueValue *srcValue, const Metadata *srcType,
|
||||
const Metadata *&destFailureType, const Metadata *&srcFailureType,
|
||||
bool takeOnSuccess, bool mayDeferChecks)
|
||||
bool takeOnSuccess, bool mayDeferChecks, bool prohibitIsolatedConformances)
|
||||
{
|
||||
assert(srcType != destType);
|
||||
assert(destType->getKind() == MetadataKind::Function);
|
||||
@@ -1372,7 +1377,8 @@ tryCastToFunction(
|
||||
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;
|
||||
@@ -1385,7 +1391,7 @@ static bool _conformsToProtocols(const OpaqueValue *value,
|
||||
|
||||
for (auto protocol : existentialType->getProtocols()) {
|
||||
if (!swift::_conformsToProtocolInContext(
|
||||
value, type, protocol, conformances))
|
||||
value, type, protocol, conformances, prohibitIsolatedConformances))
|
||||
return false;
|
||||
if (conformances != nullptr && protocol.needsWitnessTable()) {
|
||||
assert(*conformances != nullptr);
|
||||
@@ -1402,7 +1408,7 @@ tryCastToUnconstrainedOpaqueExistential(
|
||||
OpaqueValue *destLocation, const Metadata *destType,
|
||||
OpaqueValue *srcValue, const Metadata *srcType,
|
||||
const Metadata *&destFailureType, const Metadata *&srcFailureType,
|
||||
bool takeOnSuccess, bool mayDeferChecks)
|
||||
bool takeOnSuccess, bool mayDeferChecks, bool prohibitIsolatedConformances)
|
||||
{
|
||||
assert(srcType != destType);
|
||||
assert(destType->getKind() == MetadataKind::Existential);
|
||||
@@ -1429,7 +1435,7 @@ tryCastToConstrainedOpaqueExistential(
|
||||
OpaqueValue *destLocation, const Metadata *destType,
|
||||
OpaqueValue *srcValue, const Metadata *srcType,
|
||||
const Metadata *&destFailureType, const Metadata *&srcFailureType,
|
||||
bool takeOnSuccess, bool mayDeferChecks)
|
||||
bool takeOnSuccess, bool mayDeferChecks, bool prohibitIsolatedConformances)
|
||||
{
|
||||
assert(srcType != destType);
|
||||
assert(destType->getKind() == MetadataKind::Existential);
|
||||
@@ -1443,10 +1449,12 @@ tryCastToConstrainedOpaqueExistential(
|
||||
// TODO (rdar://17033499) If the source is an existential, we should
|
||||
// be able to compare the protocol constraints more efficiently than this.
|
||||
if (_conformsToProtocols(srcValue, srcType, destExistentialType,
|
||||
destExistential->getWitnessTables())) {
|
||||
destExistential->getWitnessTables(),
|
||||
prohibitIsolatedConformances)) {
|
||||
return tryCastToUnconstrainedOpaqueExistential(
|
||||
destLocation, destType, srcValue, srcType,
|
||||
destFailureType, srcFailureType, takeOnSuccess, mayDeferChecks);
|
||||
destFailureType, srcFailureType, takeOnSuccess, mayDeferChecks,
|
||||
prohibitIsolatedConformances);
|
||||
} else {
|
||||
return DynamicCastResult::Failure;
|
||||
}
|
||||
@@ -1457,7 +1465,7 @@ tryCastToClassExistential(
|
||||
OpaqueValue *destLocation, const Metadata *destType,
|
||||
OpaqueValue *srcValue, const Metadata *srcType,
|
||||
const Metadata *&destFailureType, const Metadata *&srcFailureType,
|
||||
bool takeOnSuccess, bool mayDeferChecks)
|
||||
bool takeOnSuccess, bool mayDeferChecks, bool prohibitIsolatedConformances)
|
||||
{
|
||||
assert(srcType != destType);
|
||||
assert(destType->getKind() == MetadataKind::Existential);
|
||||
@@ -1480,7 +1488,8 @@ tryCastToClassExistential(
|
||||
auto value = reinterpret_cast<OpaqueValue *>(&tmp);
|
||||
auto type = reinterpret_cast<const Metadata *>(tmp);
|
||||
if (_conformsToProtocols(value, type, destExistentialType,
|
||||
destExistentialLocation->getWitnessTables())) {
|
||||
destExistentialLocation->getWitnessTables(),
|
||||
prohibitIsolatedConformances)) {
|
||||
auto object = *(reinterpret_cast<HeapObject **>(value));
|
||||
destExistentialLocation->Value = object;
|
||||
if (takeOnSuccess) {
|
||||
@@ -1529,7 +1538,8 @@ tryCastToClassExistential(
|
||||
}
|
||||
if (_conformsToProtocols(srcValue, srcType,
|
||||
destExistentialType,
|
||||
destExistentialLocation->getWitnessTables())) {
|
||||
destExistentialLocation->getWitnessTables(),
|
||||
prohibitIsolatedConformances)) {
|
||||
destExistentialLocation->Value = srcObject;
|
||||
if (takeOnSuccess) {
|
||||
return DynamicCastResult::SuccessViaTake;
|
||||
@@ -1646,7 +1656,7 @@ tryCastToErrorExistential(
|
||||
OpaqueValue *destLocation, const Metadata *destType,
|
||||
OpaqueValue *srcValue, const Metadata *srcType,
|
||||
const Metadata *&destFailureType, const Metadata *&srcFailureType,
|
||||
bool takeOnSuccess, bool mayDeferChecks)
|
||||
bool takeOnSuccess, bool mayDeferChecks, bool prohibitIsolatedConformances)
|
||||
{
|
||||
assert(srcType != destType);
|
||||
assert(destType->getKind() == MetadataKind::Existential);
|
||||
@@ -1665,7 +1675,8 @@ tryCastToErrorExistential(
|
||||
assert(destExistentialType->NumProtocols == 1);
|
||||
const WitnessTable *errorWitness;
|
||||
if (_conformsToProtocols(
|
||||
srcValue, srcType, destExistentialType, &errorWitness)) {
|
||||
srcValue, srcType, destExistentialType, &errorWitness,
|
||||
prohibitIsolatedConformances)) {
|
||||
#if SWIFT_OBJC_INTEROP
|
||||
// If it already holds an NSError, just use that.
|
||||
if (auto embedded = getErrorEmbeddedNSErrorIndirect(
|
||||
@@ -1697,7 +1708,7 @@ tryCastUnwrappingExistentialSource(
|
||||
OpaqueValue *destLocation, const Metadata *destType,
|
||||
OpaqueValue *srcValue, const Metadata *srcType,
|
||||
const Metadata *&destFailureType, const Metadata *&srcFailureType,
|
||||
bool takeOnSuccess, bool mayDeferChecks)
|
||||
bool takeOnSuccess, bool mayDeferChecks, bool prohibitIsolatedConformances)
|
||||
{
|
||||
assert(srcType != destType);
|
||||
assert(srcType->getKind() == MetadataKind::Existential);
|
||||
@@ -1738,13 +1749,14 @@ tryCastUnwrappingExistentialSource(
|
||||
srcInnerValue, srcInnerType,
|
||||
destFailureType, srcFailureType,
|
||||
takeOnSuccess && (srcInnerValue == srcValue),
|
||||
mayDeferChecks);
|
||||
mayDeferChecks, prohibitIsolatedConformances);
|
||||
}
|
||||
|
||||
static DynamicCastResult tryCastUnwrappingExtendedExistentialSource(
|
||||
OpaqueValue *destLocation, const Metadata *destType, OpaqueValue *srcValue,
|
||||
const Metadata *srcType, const Metadata *&destFailureType,
|
||||
const Metadata *&srcFailureType, bool takeOnSuccess, bool mayDeferChecks) {
|
||||
const Metadata *&srcFailureType, bool takeOnSuccess, bool mayDeferChecks,
|
||||
bool prohibitIsolatedConformances) {
|
||||
assert(srcType != destType);
|
||||
assert(srcType->getKind() == MetadataKind::ExtendedExistential);
|
||||
|
||||
@@ -1784,7 +1796,8 @@ static DynamicCastResult tryCastUnwrappingExtendedExistentialSource(
|
||||
srcFailureType = srcInnerType;
|
||||
return tryCast(destLocation, destType, srcInnerValue, srcInnerType,
|
||||
destFailureType, srcFailureType,
|
||||
takeOnSuccess && (srcInnerValue == srcValue), mayDeferChecks);
|
||||
takeOnSuccess && (srcInnerValue == srcValue), mayDeferChecks,
|
||||
prohibitIsolatedConformances);
|
||||
}
|
||||
|
||||
static DynamicCastResult
|
||||
@@ -1792,7 +1805,7 @@ tryCastUnwrappingExistentialMetatypeSource(
|
||||
OpaqueValue *destLocation, const Metadata *destType,
|
||||
OpaqueValue *srcValue, const Metadata *srcType,
|
||||
const Metadata *&destFailureType, const Metadata *&srcFailureType,
|
||||
bool takeOnSuccess, bool mayDeferChecks)
|
||||
bool takeOnSuccess, bool mayDeferChecks, bool prohibitIsolatedConformances)
|
||||
{
|
||||
assert(srcType != destType);
|
||||
assert(srcType->getKind() == MetadataKind::ExistentialMetatype);
|
||||
@@ -1807,14 +1820,15 @@ tryCastUnwrappingExistentialMetatypeSource(
|
||||
srcInnerValue, srcInnerType,
|
||||
destFailureType, srcFailureType,
|
||||
takeOnSuccess && (srcInnerValue == srcValue),
|
||||
mayDeferChecks);
|
||||
mayDeferChecks, prohibitIsolatedConformances);
|
||||
}
|
||||
|
||||
|
||||
static DynamicCastResult tryCastToExtendedExistential(
|
||||
OpaqueValue *destLocation, const Metadata *destType, OpaqueValue *srcValue,
|
||||
const Metadata *srcType, const Metadata *&destFailureType,
|
||||
const Metadata *&srcFailureType, bool takeOnSuccess, bool mayDeferChecks) {
|
||||
const Metadata *&srcFailureType, bool takeOnSuccess, bool mayDeferChecks,
|
||||
bool prohibitIsolatedConformances) {
|
||||
assert(srcType != destType);
|
||||
assert(destType->getKind() == MetadataKind::ExtendedExistential);
|
||||
|
||||
@@ -1886,6 +1900,10 @@ static DynamicCastResult tryCastToExtendedExistential(
|
||||
if (error)
|
||||
return DynamicCastResult::Failure;
|
||||
|
||||
if (prohibitIsolatedConformances &&
|
||||
context.globalActorIsolationType)
|
||||
return DynamicCastResult::Failure;
|
||||
|
||||
if (!swift_isInConformanceExecutionContext(selfType, &context))
|
||||
return DynamicCastResult::Failure;
|
||||
}
|
||||
@@ -1951,7 +1969,7 @@ tryCastToOpaque(
|
||||
OpaqueValue *destLocation, const Metadata *destType,
|
||||
OpaqueValue *srcValue, const Metadata *srcType,
|
||||
const Metadata *&destFailureType, const Metadata *&srcFailureType,
|
||||
bool takeOnSuccess, bool mayDeferChecks)
|
||||
bool takeOnSuccess, bool mayDeferChecks, bool prohibitIsolatedConformances)
|
||||
{
|
||||
assert(srcType != destType);
|
||||
assert(destType->getKind() == MetadataKind::Opaque);
|
||||
@@ -1990,7 +2008,7 @@ tryCastToMetatype(
|
||||
OpaqueValue *destLocation, const Metadata *destType,
|
||||
OpaqueValue *srcValue, const Metadata *srcType,
|
||||
const Metadata *&destFailureType, const Metadata *&srcFailureType,
|
||||
bool takeOnSuccess, bool mayDeferChecks)
|
||||
bool takeOnSuccess, bool mayDeferChecks, bool prohibitIsolatedConformances)
|
||||
{
|
||||
assert(srcType != destType);
|
||||
assert(destType->getKind() == MetadataKind::Metatype);
|
||||
@@ -2023,7 +2041,8 @@ tryCastToMetatype(
|
||||
auto srcInnerValue = reinterpret_cast<OpaqueValue *>(&metatype);
|
||||
auto srcInnerType = swift_getMetatypeMetadata(metatype);
|
||||
return tryCast(destLocation, destType, srcInnerValue, srcInnerType,
|
||||
destFailureType, srcFailureType, takeOnSuccess, mayDeferChecks);
|
||||
destFailureType, srcFailureType, takeOnSuccess, mayDeferChecks,
|
||||
prohibitIsolatedConformances);
|
||||
}
|
||||
#endif
|
||||
return DynamicCastResult::Failure;
|
||||
@@ -2040,7 +2059,7 @@ _dynamicCastMetatypeToExistentialMetatype(
|
||||
OpaqueValue *destLocation, const ExistentialMetatypeMetadata *destType,
|
||||
const Metadata *srcMetatype,
|
||||
const Metadata *&destFailureType, const Metadata *&srcFailureType,
|
||||
bool takeOnSuccess, bool mayDeferChecks)
|
||||
bool takeOnSuccess, bool mayDeferChecks, bool prohibitIsolatedConformances)
|
||||
{
|
||||
// The instance type of an existential metatype must be either an
|
||||
// existential or an existential metatype.
|
||||
@@ -2057,7 +2076,7 @@ _dynamicCastMetatypeToExistentialMetatype(
|
||||
= destMetatype ? destMetatype->getWitnessTables() : nullptr;
|
||||
if (!_conformsToProtocols(nullptr, srcMetatype,
|
||||
targetInstanceTypeAsExistential,
|
||||
conformance)) {
|
||||
conformance, prohibitIsolatedConformances)) {
|
||||
return DynamicCastResult::Failure;
|
||||
}
|
||||
|
||||
@@ -2096,7 +2115,7 @@ _dynamicCastMetatypeToExistentialMetatype(
|
||||
srcInstanceType,
|
||||
destFailureType,
|
||||
srcFailureType,
|
||||
takeOnSuccess, mayDeferChecks);
|
||||
takeOnSuccess, mayDeferChecks, prohibitIsolatedConformances);
|
||||
}
|
||||
|
||||
// "ExistentialMetatype" is the metatype for an existential type.
|
||||
@@ -2105,7 +2124,7 @@ tryCastToExistentialMetatype(
|
||||
OpaqueValue *destLocation, const Metadata *destType,
|
||||
OpaqueValue *srcValue, const Metadata *srcType,
|
||||
const Metadata *&destFailureType, const Metadata *&srcFailureType,
|
||||
bool takeOnSuccess, bool mayDeferChecks)
|
||||
bool takeOnSuccess, bool mayDeferChecks, bool prohibitIsolatedConformances)
|
||||
{
|
||||
assert(srcType != destType);
|
||||
assert(destType->getKind() == MetadataKind::ExistentialMetatype);
|
||||
@@ -2122,7 +2141,7 @@ tryCastToExistentialMetatype(
|
||||
srcMetatype,
|
||||
destFailureType,
|
||||
srcFailureType,
|
||||
takeOnSuccess, mayDeferChecks);
|
||||
takeOnSuccess, mayDeferChecks, prohibitIsolatedConformances);
|
||||
}
|
||||
|
||||
case MetadataKind::ObjCClassWrapper: {
|
||||
@@ -2142,7 +2161,7 @@ tryCastToExistentialMetatype(
|
||||
metatype,
|
||||
destFailureType,
|
||||
srcFailureType,
|
||||
takeOnSuccess, mayDeferChecks);
|
||||
takeOnSuccess, mayDeferChecks, prohibitIsolatedConformances);
|
||||
}
|
||||
#endif
|
||||
return DynamicCastResult::Failure;
|
||||
@@ -2262,7 +2281,7 @@ tryCast(
|
||||
OpaqueValue *destLocation, const Metadata *destType,
|
||||
OpaqueValue *srcValue, const Metadata *srcType,
|
||||
const Metadata *&destFailureType, const Metadata *&srcFailureType,
|
||||
bool takeOnSuccess, bool mayDeferChecks)
|
||||
bool takeOnSuccess, bool mayDeferChecks, bool prohibitIsolatedConformances)
|
||||
{
|
||||
destFailureType = destType;
|
||||
srcFailureType = srcType;
|
||||
@@ -2295,7 +2314,8 @@ tryCast(
|
||||
return DynamicCastResult::Failure;
|
||||
}
|
||||
auto castResult = tryCastToDestType(destLocation, destType, srcValue,
|
||||
srcType, destFailureType, srcFailureType, takeOnSuccess, mayDeferChecks);
|
||||
srcType, destFailureType, srcFailureType, takeOnSuccess, mayDeferChecks,
|
||||
prohibitIsolatedConformances);
|
||||
if (isSuccess(castResult)) {
|
||||
return castResult;
|
||||
}
|
||||
@@ -2312,7 +2332,8 @@ tryCast(
|
||||
srcFailureType = srcDynamicType;
|
||||
auto castResult = tryCastToDestType(
|
||||
destLocation, destType, srcValue, srcDynamicType,
|
||||
destFailureType, srcFailureType, takeOnSuccess, mayDeferChecks);
|
||||
destFailureType, srcFailureType, takeOnSuccess, mayDeferChecks,
|
||||
prohibitIsolatedConformances);
|
||||
if (isSuccess(castResult)) {
|
||||
return castResult;
|
||||
}
|
||||
@@ -2345,7 +2366,8 @@ tryCast(
|
||||
// Try unwrapping Obj-C __SwiftValue implementation
|
||||
auto subcastResult = tryCastUnwrappingObjCSwiftValueSource(
|
||||
destLocation, destType, srcValue, srcType,
|
||||
destFailureType, srcFailureType, takeOnSuccess, mayDeferChecks);
|
||||
destFailureType, srcFailureType, takeOnSuccess, mayDeferChecks,
|
||||
prohibitIsolatedConformances);
|
||||
if (isSuccess(subcastResult)) {
|
||||
return subcastResult;
|
||||
}
|
||||
@@ -2379,7 +2401,8 @@ tryCast(
|
||||
case MetadataKind::Existential: {
|
||||
auto subcastResult = tryCastUnwrappingExistentialSource(
|
||||
destLocation, destType, srcValue, srcType,
|
||||
destFailureType, srcFailureType, takeOnSuccess, mayDeferChecks);
|
||||
destFailureType, srcFailureType, takeOnSuccess, mayDeferChecks,
|
||||
prohibitIsolatedConformances);
|
||||
if (isSuccess(subcastResult)) {
|
||||
return subcastResult;
|
||||
}
|
||||
@@ -2389,7 +2412,8 @@ tryCast(
|
||||
case MetadataKind::ExistentialMetatype: {
|
||||
auto subcastResult = tryCastUnwrappingExistentialMetatypeSource(
|
||||
destLocation, destType, srcValue, srcType,
|
||||
destFailureType, srcFailureType, takeOnSuccess, mayDeferChecks);
|
||||
destFailureType, srcFailureType, takeOnSuccess, mayDeferChecks,
|
||||
prohibitIsolatedConformances);
|
||||
if (isSuccess(subcastResult)) {
|
||||
return subcastResult;
|
||||
}
|
||||
@@ -2399,7 +2423,8 @@ tryCast(
|
||||
case MetadataKind::ExtendedExistential: {
|
||||
auto subcastResult = tryCastUnwrappingExtendedExistentialSource(
|
||||
destLocation, destType, srcValue, srcType, destFailureType,
|
||||
srcFailureType, takeOnSuccess, mayDeferChecks);
|
||||
srcFailureType, takeOnSuccess, mayDeferChecks,
|
||||
prohibitIsolatedConformances);
|
||||
if (isSuccess(subcastResult)) {
|
||||
return subcastResult;
|
||||
}
|
||||
@@ -2423,14 +2448,16 @@ tryCast(
|
||||
if (srcKind == MetadataKind::Optional) {
|
||||
auto subcastResult = tryCastUnwrappingOptionalBoth(
|
||||
destLocation, destType, srcValue, srcType,
|
||||
destFailureType, srcFailureType, takeOnSuccess, mayDeferChecks);
|
||||
destFailureType, srcFailureType, takeOnSuccess, mayDeferChecks,
|
||||
prohibitIsolatedConformances);
|
||||
if (isSuccess(subcastResult)) {
|
||||
return subcastResult;
|
||||
}
|
||||
}
|
||||
auto subcastResult = tryCastUnwrappingOptionalDestination(
|
||||
destLocation, destType, srcValue, srcType,
|
||||
destFailureType, srcFailureType, takeOnSuccess, mayDeferChecks);
|
||||
destFailureType, srcFailureType, takeOnSuccess, mayDeferChecks,
|
||||
prohibitIsolatedConformances);
|
||||
if (isSuccess(subcastResult)) {
|
||||
return subcastResult;
|
||||
}
|
||||
@@ -2439,7 +2466,8 @@ tryCast(
|
||||
if (srcKind == MetadataKind::Optional) {
|
||||
auto subcastResult = tryCastUnwrappingOptionalSource(
|
||||
destLocation, destType, srcValue, srcType,
|
||||
destFailureType, srcFailureType, takeOnSuccess, mayDeferChecks);
|
||||
destFailureType, srcFailureType, takeOnSuccess, mayDeferChecks,
|
||||
prohibitIsolatedConformances);
|
||||
if (isSuccess(subcastResult)) {
|
||||
return subcastResult;
|
||||
}
|
||||
@@ -2583,6 +2611,11 @@ swift_dynamicCastImpl(OpaqueValue *destLocation,
|
||||
// actually accessed.
|
||||
bool mayDeferChecks = flags & DynamicCastFlags::Unconditional;
|
||||
|
||||
// Whether the compiler told us that we aren't allowed to use *any* isolated
|
||||
// conformances, regardless of whether we are in that isolation domain.
|
||||
bool prohibitIsolatedConformances =
|
||||
flags & DynamicCastFlags::ProhibitIsolatedConformances;
|
||||
|
||||
// Attempt the cast...
|
||||
const Metadata *destFailureType = destType;
|
||||
const Metadata *srcFailureType = srcType;
|
||||
@@ -2590,7 +2623,7 @@ swift_dynamicCastImpl(OpaqueValue *destLocation,
|
||||
destLocation, destType,
|
||||
srcValue, srcType,
|
||||
destFailureType, srcFailureType,
|
||||
takeOnSuccess, mayDeferChecks);
|
||||
takeOnSuccess, mayDeferChecks, prohibitIsolatedConformances);
|
||||
|
||||
switch (result) {
|
||||
case DynamicCastResult::Failure:
|
||||
|
||||
Reference in New Issue
Block a user