@@ -45,6 +45,32 @@ mayBridgeToObjectiveC(Module *M, CanType T) {
45
45
return false ;
46
46
}
47
47
48
+ static bool
49
+ mustBridgeToSwiftValueBox (Module *M, CanType T) {
50
+ // If the target type is either an unknown dynamic type, or statically
51
+ // known to bridge, the cast may succeed.
52
+ if (T->hasArchetype ())
53
+ return false ;
54
+
55
+ if (T->isAnyExistentialType ())
56
+ return false ;
57
+
58
+ // getBridgedToObjC() might return a null-type for bridged foundation types
59
+ // during compiling the standard library. Exclude this case here.
60
+ if (auto N = T->getAnyNominal ())
61
+ if (M->getASTContext ().isStandardLibraryTypeBridgedInFoundation (N))
62
+ return false ;
63
+
64
+ auto bridgeTy = M->getASTContext ().getBridgedToObjC (M, T, nullptr );
65
+ if (!bridgeTy.hasValue ())
66
+ return false ;
67
+
68
+ if (bridgeTy->isNull ())
69
+ return true ;
70
+
71
+ return false ;
72
+ }
73
+
48
74
static bool canClassOrSuperclassesHaveExtensions (ClassDecl *CD,
49
75
bool isWholeModuleOpts) {
50
76
while (CD) {
@@ -414,6 +440,24 @@ swift::classifyDynamicCast(Module *M,
414
440
return DynamicCastFeasibility::WillFail;
415
441
}
416
442
443
+ // Casts from a class into a non-class can never succeed if the target must
444
+ // be bridged to a SwiftValueBox. You would need an AnyObject source for
445
+ // that.
446
+ if (!target.isAnyExistentialType () &&
447
+ !target.getClassOrBoundGenericClass () &&
448
+ !isa<ArchetypeType>(target) &&
449
+ mustBridgeToSwiftValueBox (M, target)) {
450
+ assert ((target.getEnumOrBoundGenericEnum () ||
451
+ target.getStructOrBoundGenericStruct () ||
452
+ isa<TupleType>(target) ||
453
+ isa<SILFunctionType>(target) ||
454
+ isa<FunctionType>(target) ||
455
+ isa<MetatypeType>(target)) &&
456
+ " Target should be an enum, struct, tuple, metatype or function type" );
457
+ return DynamicCastFeasibility::WillFail;
458
+ }
459
+
460
+
417
461
// In the Objective-C runtime, class metatypes are also class instances.
418
462
// The cast may succeed if the target type can be inhabited by a class
419
463
// metatype.
@@ -439,6 +483,22 @@ swift::classifyDynamicCast(Module *M,
439
483
// FIXME: Be more careful with bridging conversions from
440
484
// NSArray, NSDictionary and NSSet as they may fail?
441
485
486
+ // We know that a cast from Int -> class foobar will fail.
487
+ if (targetClass &&
488
+ !source.isAnyExistentialType () &&
489
+ !source.getClassOrBoundGenericClass () &&
490
+ !isa<ArchetypeType>(source) &&
491
+ mustBridgeToSwiftValueBox (M, source)) {
492
+ assert ((source.getEnumOrBoundGenericEnum () ||
493
+ source.getStructOrBoundGenericStruct () ||
494
+ isa<TupleType>(source) ||
495
+ isa<SILFunctionType>(source) ||
496
+ isa<FunctionType>(source) ||
497
+ isa<MetatypeType>(source)) &&
498
+ " Source should be an enum, struct, tuple, metatype or function type" );
499
+ return DynamicCastFeasibility::WillFail;
500
+ }
501
+
442
502
// Check if there might be a bridging conversion.
443
503
if (source->isBridgeableObjectType () && mayBridgeToObjectiveC (M, target)) {
444
504
// Try to get the ObjC type which is bridged to target type.
0 commit comments