@@ -247,6 +247,7 @@ static void _buildNameForMetadata(const Metadata *type,
247
247
result);
248
248
}
249
249
case MetadataKind::Enum:
250
+ case MetadataKind::Optional:
250
251
case MetadataKind::Struct: {
251
252
auto structType = static_cast <const StructMetadata *>(type);
252
253
return _buildNominalTypeName (structType->Description ,
@@ -574,6 +575,7 @@ static bool _conformsToProtocol(const OpaqueValue *value,
574
575
case MetadataKind::HeapGenericLocalVariable:
575
576
case MetadataKind::ErrorObject:
576
577
case MetadataKind::Enum:
578
+ case MetadataKind::Optional:
577
579
case MetadataKind::Opaque:
578
580
case MetadataKind::Struct:
579
581
case MetadataKind::Tuple:
@@ -634,6 +636,7 @@ static bool _conformsToProtocol(const OpaqueValue *value,
634
636
case MetadataKind::ErrorObject:
635
637
case MetadataKind::Metatype:
636
638
case MetadataKind::Enum:
639
+ case MetadataKind::Optional:
637
640
case MetadataKind::Opaque:
638
641
case MetadataKind::Struct:
639
642
case MetadataKind::Tuple:
@@ -736,6 +739,7 @@ static void findDynamicValueAndType(OpaqueValue *value, const Metadata *type,
736
739
case MetadataKind::HeapGenericLocalVariable:
737
740
case MetadataKind::ErrorObject:
738
741
case MetadataKind::Enum:
742
+ case MetadataKind::Optional:
739
743
case MetadataKind::Opaque:
740
744
case MetadataKind::Struct:
741
745
case MetadataKind::Tuple:
@@ -797,6 +801,7 @@ static void deallocateDynamicValue(OpaqueValue *value, const Metadata *type) {
797
801
case MetadataKind::HeapGenericLocalVariable:
798
802
case MetadataKind::ErrorObject:
799
803
case MetadataKind::Enum:
804
+ case MetadataKind::Optional:
800
805
case MetadataKind::Opaque:
801
806
case MetadataKind::Struct:
802
807
case MetadataKind::Tuple:
@@ -822,6 +827,7 @@ swift_dynamicCastMetatypeToObjectConditional(const Metadata *metatype) {
822
827
// Other kinds of metadata don't cast to AnyObject.
823
828
case MetadataKind::Struct:
824
829
case MetadataKind::Enum:
830
+ case MetadataKind::Optional:
825
831
case MetadataKind::Opaque:
826
832
case MetadataKind::Tuple:
827
833
case MetadataKind::Function:
@@ -852,6 +858,7 @@ swift_dynamicCastMetatypeToObjectUnconditional(const Metadata *metatype) {
852
858
// Other kinds of metadata don't cast to AnyObject.
853
859
case MetadataKind::Struct:
854
860
case MetadataKind::Enum:
861
+ case MetadataKind::Optional:
855
862
case MetadataKind::Opaque:
856
863
case MetadataKind::Tuple:
857
864
case MetadataKind::Function:
@@ -939,6 +946,7 @@ static bool _dynamicCastToExistential(OpaqueValue *dest,
939
946
940
947
case MetadataKind::Struct:
941
948
case MetadataKind::Enum:
949
+ case MetadataKind::Optional:
942
950
#if SWIFT_OBJC_INTEROP
943
951
// If the source type is bridged to Objective-C, try to bridge.
944
952
if (auto srcBridgeWitness = findBridgeWitness (srcDynamicType)) {
@@ -1111,6 +1119,7 @@ swift::swift_dynamicCastUnknownClass(const void *object,
1111
1119
case MetadataKind::ErrorObject:
1112
1120
case MetadataKind::Metatype:
1113
1121
case MetadataKind::Enum:
1122
+ case MetadataKind::Optional:
1114
1123
case MetadataKind::Opaque:
1115
1124
case MetadataKind::Struct:
1116
1125
case MetadataKind::Tuple:
@@ -1166,6 +1175,7 @@ swift::swift_dynamicCastUnknownClassUnconditional(const void *object,
1166
1175
case MetadataKind::ErrorObject:
1167
1176
case MetadataKind::Metatype:
1168
1177
case MetadataKind::Enum:
1178
+ case MetadataKind::Optional:
1169
1179
case MetadataKind::Opaque:
1170
1180
case MetadataKind::Struct:
1171
1181
case MetadataKind::Tuple:
@@ -1225,6 +1235,7 @@ swift::swift_dynamicCastMetatype(const Metadata *sourceType,
1225
1235
case MetadataKind::ErrorObject:
1226
1236
case MetadataKind::Metatype:
1227
1237
case MetadataKind::Enum:
1238
+ case MetadataKind::Optional:
1228
1239
case MetadataKind::Opaque:
1229
1240
case MetadataKind::Struct:
1230
1241
case MetadataKind::Tuple:
@@ -1255,6 +1266,7 @@ swift::swift_dynamicCastMetatype(const Metadata *sourceType,
1255
1266
case MetadataKind::ErrorObject:
1256
1267
case MetadataKind::Metatype:
1257
1268
case MetadataKind::Enum:
1269
+ case MetadataKind::Optional:
1258
1270
case MetadataKind::Opaque:
1259
1271
case MetadataKind::Struct:
1260
1272
case MetadataKind::Tuple:
@@ -1270,6 +1282,7 @@ swift::swift_dynamicCastMetatype(const Metadata *sourceType,
1270
1282
case MetadataKind::ErrorObject:
1271
1283
case MetadataKind::Metatype:
1272
1284
case MetadataKind::Enum:
1285
+ case MetadataKind::Optional:
1273
1286
case MetadataKind::Opaque:
1274
1287
case MetadataKind::Struct:
1275
1288
case MetadataKind::Tuple:
@@ -1332,6 +1345,7 @@ swift::swift_dynamicCastMetatypeUnconditional(const Metadata *sourceType,
1332
1345
case MetadataKind::ErrorObject:
1333
1346
case MetadataKind::Metatype:
1334
1347
case MetadataKind::Enum:
1348
+ case MetadataKind::Optional:
1335
1349
case MetadataKind::Opaque:
1336
1350
case MetadataKind::Struct:
1337
1351
case MetadataKind::Tuple:
@@ -1363,6 +1377,7 @@ swift::swift_dynamicCastMetatypeUnconditional(const Metadata *sourceType,
1363
1377
case MetadataKind::ErrorObject:
1364
1378
case MetadataKind::Metatype:
1365
1379
case MetadataKind::Enum:
1380
+ case MetadataKind::Optional:
1366
1381
case MetadataKind::Opaque:
1367
1382
case MetadataKind::Struct:
1368
1383
case MetadataKind::Tuple:
@@ -1377,6 +1392,7 @@ swift::swift_dynamicCastMetatypeUnconditional(const Metadata *sourceType,
1377
1392
case MetadataKind::ErrorObject:
1378
1393
case MetadataKind::Metatype:
1379
1394
case MetadataKind::Enum:
1395
+ case MetadataKind::Optional:
1380
1396
case MetadataKind::Opaque:
1381
1397
case MetadataKind::Struct:
1382
1398
case MetadataKind::Tuple:
@@ -1715,6 +1731,7 @@ static bool _dynamicCastToMetatype(OpaqueValue *dest,
1715
1731
case MetadataKind::HeapGenericLocalVariable:
1716
1732
case MetadataKind::ErrorObject:
1717
1733
case MetadataKind::Enum:
1734
+ case MetadataKind::Optional:
1718
1735
case MetadataKind::Opaque:
1719
1736
case MetadataKind::Struct:
1720
1737
case MetadataKind::Tuple:
@@ -1885,6 +1902,7 @@ static bool _dynamicCastToExistentialMetatype(OpaqueValue *dest,
1885
1902
case MetadataKind::HeapGenericLocalVariable:
1886
1903
case MetadataKind::ErrorObject:
1887
1904
case MetadataKind::Enum:
1905
+ case MetadataKind::Optional:
1888
1906
case MetadataKind::Opaque:
1889
1907
case MetadataKind::Struct:
1890
1908
case MetadataKind::Tuple:
@@ -1947,6 +1965,7 @@ static bool _dynamicCastToFunction(OpaqueValue *dest,
1947
1965
case MetadataKind::Class:
1948
1966
case MetadataKind::Struct:
1949
1967
case MetadataKind::Enum:
1968
+ case MetadataKind::Optional:
1950
1969
case MetadataKind::ObjCClassWrapper:
1951
1970
case MetadataKind::ForeignClass:
1952
1971
case MetadataKind::ExistentialMetatype:
@@ -1971,13 +1990,59 @@ static id dynamicCastValueToNSError(OpaqueValue *src,
1971
1990
}
1972
1991
#endif
1973
1992
1993
+ static bool canCastToExistential (OpaqueValue *dest, OpaqueValue *src,
1994
+ const Metadata *srcType,
1995
+ const Metadata *targetType) {
1996
+ if (targetType->getKind () != MetadataKind::Existential)
1997
+ return false ;
1998
+
1999
+ return _dynamicCastToExistential (dest, src, srcType,
2000
+ cast<ExistentialTypeMetadata>(targetType),
2001
+ DynamicCastFlags::Default);
2002
+ }
2003
+
1974
2004
// / Perform a dynamic cast to an arbitrary type.
1975
2005
bool swift::swift_dynamicCast (OpaqueValue *dest,
1976
2006
OpaqueValue *src,
1977
2007
const Metadata *srcType,
1978
2008
const Metadata *targetType,
1979
2009
DynamicCastFlags flags) {
2010
+ // Check if the cast source is Optional and the target is not an existential
2011
+ // that Optional conforms to. Unwrap one level of Optional and continue.
2012
+ if (srcType->getKind () == MetadataKind::Optional
2013
+ && !canCastToExistential (dest, src, srcType, targetType)) {
2014
+ const Metadata *payloadType =
2015
+ cast<EnumMetadata>(srcType)->getGenericArgs ()[0 ];
2016
+ int enumCase =
2017
+ swift_getEnumCaseSinglePayload (src, payloadType, 1 /* emptyCases=*/ );
2018
+ if (enumCase != -1 ) {
2019
+ // Allow Optional<T>.None -> Optional<U>.None
2020
+ if (targetType->getKind () != MetadataKind::Optional)
2021
+ return _fail (src, srcType, targetType, flags);
2022
+ // Inject the .None tag
2023
+ swift_storeEnumTagSinglePayload (dest, payloadType, enumCase,
2024
+ 1 /* emptyCases=*/ );
2025
+ return _succeed (dest, src, srcType, flags);
2026
+ }
2027
+ // .Some
2028
+ // Single payload enums are guaranteed layout compatible with their
2029
+ // payload. Only the source's payload needs to be taken or destroyed.
2030
+ srcType = payloadType;
2031
+ }
2032
+
1980
2033
switch (targetType->getKind ()) {
2034
+ // Handle wrapping an Optional target.
2035
+ case MetadataKind::Optional: {
2036
+ // Recursively cast into the layout compatible payload area.
2037
+ const Metadata *payloadType =
2038
+ cast<EnumMetadata>(targetType)->getGenericArgs ()[0 ];
2039
+ if (swift_dynamicCast (dest, src, srcType, payloadType, flags)) {
2040
+ swift_storeEnumTagSinglePayload (dest, payloadType, -1 /* case*/ ,
2041
+ 1 /* emptyCases*/ );
2042
+ return true ;
2043
+ }
2044
+ return false ;
2045
+ }
1981
2046
1982
2047
// Casts to class type.
1983
2048
case MetadataKind::Class:
@@ -2020,6 +2085,7 @@ bool swift::swift_dynamicCast(OpaqueValue *dest,
2020
2085
}
2021
2086
2022
2087
case MetadataKind::Enum:
2088
+ case MetadataKind::Optional:
2023
2089
case MetadataKind::Struct: {
2024
2090
#if SWIFT_OBJC_INTEROP
2025
2091
// If the source type is bridged to Objective-C, try to bridge.
@@ -2092,6 +2158,7 @@ bool swift::swift_dynamicCast(OpaqueValue *dest,
2092
2158
}
2093
2159
2094
2160
case MetadataKind::Enum:
2161
+ case MetadataKind::Optional:
2095
2162
case MetadataKind::Existential:
2096
2163
case MetadataKind::ExistentialMetatype:
2097
2164
case MetadataKind::Function:
@@ -2970,6 +3037,7 @@ findBridgeWitness(const Metadata *T) {
2970
3037
case MetadataKind::Class:
2971
3038
case MetadataKind::Struct:
2972
3039
case MetadataKind::Enum:
3040
+ case MetadataKind::Optional:
2973
3041
case MetadataKind::Opaque:
2974
3042
case MetadataKind::Tuple:
2975
3043
case MetadataKind::Function:
@@ -3149,3 +3217,7 @@ extern "C" const Metadata *_swift_getSuperclass_nonNull(
3149
3217
extern " C" bool swift_isClassType (const Metadata *type) {
3150
3218
return Metadata::isAnyKindOfClass (type->getKind ());
3151
3219
}
3220
+
3221
+ extern " C" bool swift_isOptionalType (const Metadata *type) {
3222
+ return type->getKind () == MetadataKind::Optional;
3223
+ }
0 commit comments