@@ -1514,62 +1514,41 @@ tryCastToClassExistentialViaSwiftValue(
1514
1514
auto destExistentialLocation
1515
1515
= reinterpret_cast <ClassExistentialContainer *>(destLocation);
1516
1516
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)) {
1535
1531
return DynamicCastResult::Failure;
1536
- default :
1537
- break ;
1538
1532
}
1539
1533
#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;
1544
1534
}
1545
1535
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
1554
1536
#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
+ }
1563
1545
# 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;
1569
1551
#endif
1570
- }
1571
- }
1572
- }
1573
1552
}
1574
1553
1575
1554
static DynamicCastResult
0 commit comments