@@ -411,8 +411,19 @@ static bool _conformsToProtocol(const OpaqueValue *value,
411
411
// / list of conformances.
412
412
static bool _conformsToProtocols (const OpaqueValue *value,
413
413
const Metadata *type,
414
- const ProtocolDescriptorList &protocols ,
414
+ const ExistentialTypeMetadata *existentialType ,
415
415
const WitnessTable **conformances) {
416
+ if (auto *superclass = existentialType->getSuperclassConstraint ()) {
417
+ if (!swift_dynamicCastMetatype (type, superclass))
418
+ return false ;
419
+ }
420
+
421
+ if (existentialType->isClassBounded ()) {
422
+ if (!Metadata::isAnyKindOfClass (type->getKind ()))
423
+ return false ;
424
+ }
425
+
426
+ auto &protocols = existentialType->Protocols ;
416
427
for (unsigned i = 0 , n = protocols.NumProtocols ; i != n; ++i) {
417
428
const ProtocolDescriptor *protocol = protocols[i];
418
429
if (!_conformsToProtocol (value, type, protocol, conformances))
@@ -876,7 +887,7 @@ static bool _dynamicCastToExistential(OpaqueValue *dest,
876
887
#if SWIFT_OBJC_INTEROP
877
888
// If the destination type is a set of protocols that SwiftValue
878
889
// implements, we're fine.
879
- if (findSwiftValueConformances (targetType-> Protocols ,
890
+ if (findSwiftValueConformances (targetType,
880
891
destExistential->getWitnessTables ())) {
881
892
bool consumeValue = dynamicFlags & DynamicCastFlags::TakeOnSuccess;
882
893
destExistential->Value =
@@ -963,7 +974,7 @@ static bool _dynamicCastToExistential(OpaqueValue *dest,
963
974
// container with a class instance to AnyObject. In this case no check is
964
975
// necessary.
965
976
if (srcDynamicType && !_conformsToProtocols (srcDynamicValue, srcDynamicType,
966
- targetType-> Protocols ,
977
+ targetType,
967
978
destExistential->getWitnessTables ()))
968
979
return fallbackForNonDirectConformance ();
969
980
@@ -981,7 +992,7 @@ static bool _dynamicCastToExistential(OpaqueValue *dest,
981
992
982
993
// Check for protocol conformances and fill in the witness tables.
983
994
if (!_conformsToProtocols (srcDynamicValue, srcDynamicType,
984
- targetType-> Protocols ,
995
+ targetType,
985
996
destExistential->getWitnessTables ()))
986
997
return fallbackForNonDirectConformance ();
987
998
@@ -1015,7 +1026,7 @@ static bool _dynamicCastToExistential(OpaqueValue *dest,
1015
1026
assert (targetType->Protocols .NumProtocols == 1 );
1016
1027
const WitnessTable *errorWitness;
1017
1028
if (!_conformsToProtocols (srcDynamicValue, srcDynamicType,
1018
- targetType-> Protocols ,
1029
+ targetType,
1019
1030
&errorWitness))
1020
1031
return fallbackForNonDirectConformance ();
1021
1032
@@ -1052,6 +1063,8 @@ static bool _dynamicCastToExistential(OpaqueValue *dest,
1052
1063
static const void *
1053
1064
_dynamicCastUnknownClassToExistential (const void *object,
1054
1065
const ExistentialTypeMetadata *targetType) {
1066
+ // FIXME: check superclass constraint here.
1067
+
1055
1068
for (unsigned i = 0 , e = targetType->Protocols .NumProtocols ; i < e; ++i) {
1056
1069
const ProtocolDescriptor *protocol = targetType->Protocols [i];
1057
1070
@@ -1848,18 +1861,14 @@ static bool _dynamicCastMetatypeToExistentialMetatype(OpaqueValue *dest,
1848
1861
dyn_cast<ExistentialTypeMetadata>(targetInstanceType)) {
1849
1862
// Check for conformance to all the protocols.
1850
1863
// TODO: collect the witness tables.
1851
- auto &protocols = targetInstanceTypeAsExistential->Protocols ;
1852
1864
const WitnessTable **conformance
1853
1865
= writeDestMetatype ? destMetatype->getWitnessTables () : nullptr ;
1854
- for (unsigned i = 0 , n = protocols.NumProtocols ; i != n; ++i) {
1855
- const ProtocolDescriptor *protocol = protocols[i];
1856
- if (!_conformsToProtocol (nullptr , srcMetatype, protocol, conformance)) {
1857
- if (flags & DynamicCastFlags::Unconditional)
1858
- swift_dynamicCastFailure (srcMetatype, targetType);
1859
- return false ;
1860
- }
1861
- if (conformance && protocol->Flags .needsWitnessTable ())
1862
- ++conformance;
1866
+ if (!_conformsToProtocols (nullptr , srcMetatype,
1867
+ targetInstanceTypeAsExistential,
1868
+ conformance)) {
1869
+ if (flags & DynamicCastFlags::Unconditional)
1870
+ swift_dynamicCastFailure (srcMetatype, targetType);
1871
+ return false ;
1863
1872
}
1864
1873
1865
1874
if (writeDestMetatype)
0 commit comments