@@ -1514,62 +1514,41 @@ tryCastToClassExistentialViaSwiftValue(
15141514 auto destExistentialLocation
15151515 = reinterpret_cast <ClassExistentialContainer *>(destLocation);
15161516
1517- switch (srcType->getKind ()) {
1518- case MetadataKind::Class:
1519- case MetadataKind::ObjCClassWrapper:
1520- case MetadataKind::ForeignClass:
1521- // Class references always go directly into
1522- // class existentials; it makes no sense to wrap them.
1523- return DynamicCastResult::Failure;
1524-
1525- case MetadataKind::Metatype: {
1526- #if SWIFT_OBJC_INTEROP
1527- auto metatypePtr = reinterpret_cast <const Metadata **>(srcValue);
1528- auto metatype = *metatypePtr;
1529- switch (metatype->getKind ()) {
1530- case MetadataKind::Class:
1531- case MetadataKind::ObjCClassWrapper:
1532- case MetadataKind::ForeignClass:
1533- // Exclude class metatypes on Darwin, since those are object types and can
1534- // be stored directly.
1517+ // Fail if the target has constraints that make it unsuitable for
1518+ // a __SwiftValue box.
1519+ // FIXME: We should not have different checks here for
1520+ // Obj-C vs non-Obj-C. The _SwiftValue boxes should conform
1521+ // to the exact same protocols on both platforms.
1522+ bool destIsConstrained = destExistentialType->NumProtocols != 0 ;
1523+ if (destIsConstrained) {
1524+ #if SWIFT_OBJC_INTEROP // __SwiftValue is an Obj-C class
1525+ if (!findSwiftValueConformances (
1526+ destExistentialType, destExistentialLocation->getWitnessTables ())) {
1527+ return DynamicCastResult::Failure;
1528+ }
1529+ #else // __SwiftValue is a native class
1530+ if (!swift_swiftValueConformsTo (destType, destType)) {
15351531 return DynamicCastResult::Failure;
1536- default :
1537- break ;
15381532 }
15391533#endif
1540- // Non-class metatypes are never objects, and
1541- // metatypes on non-Darwin are never objects, so
1542- // fall through to box those.
1543- SWIFT_FALLTHROUGH;
15441534 }
15451535
1546- default : {
1547- if (destExistentialType->NumProtocols != 0 ) {
1548- // The destination is a class-constrained protocol type
1549- // and the source is not a class, so....
1550- return DynamicCastResult::Failure;
1551- } else {
1552- // This is a simple (unconstrained) `AnyObject` so we can populate
1553- // it by stuffing a non-class instance into a __SwiftValue box
15541536#if SWIFT_OBJC_INTEROP
1555- auto object = bridgeAnythingToSwiftValueObject (
1556- srcValue, srcType, takeOnSuccess);
1557- destExistentialLocation->Value = object;
1558- if (takeOnSuccess) {
1559- return DynamicCastResult::SuccessViaTake;
1560- } else {
1561- return DynamicCastResult::SuccessViaCopy;
1562- }
1537+ auto object = bridgeAnythingToSwiftValueObject (
1538+ srcValue, srcType, takeOnSuccess);
1539+ destExistentialLocation->Value = object;
1540+ if (takeOnSuccess) {
1541+ return DynamicCastResult::SuccessViaTake;
1542+ } else {
1543+ return DynamicCastResult::SuccessViaCopy;
1544+ }
15631545# else
1564- // Note: Code below works correctly on both Obj-C and non-Obj-C platforms,
1565- // but the code above is slightly faster on Obj-C platforms.
1566- auto object = _bridgeAnythingToObjectiveC (srcValue, srcType);
1567- destExistentialLocation->Value = object;
1568- return DynamicCastResult::SuccessViaCopy;
1546+ // Note: Code below works correctly on both Obj-C and non-Obj-C platforms,
1547+ // but the code above is slightly faster on Obj-C platforms.
1548+ auto object = _bridgeAnythingToObjectiveC (srcValue, srcType);
1549+ destExistentialLocation->Value = object;
1550+ return DynamicCastResult::SuccessViaCopy;
15691551#endif
1570- }
1571- }
1572- }
15731552}
15741553
15751554static DynamicCastResult
0 commit comments