@@ -3267,6 +3267,12 @@ CheckedCastKind TypeChecker::typeCheckCheckedCast(Type fromType,
3267
3267
return castKind;
3268
3268
3269
3269
case CheckedCastKind::Unresolved:
3270
+ // Even though we know the elements cannot be downcast, we cannot return
3271
+ // failed() here as it's possible for an empty Array, Set or Dictionary to
3272
+ // be cast to any element type at runtime (SR-6192). The one exception to
3273
+ // this is when we're checking whether we can treat a coercion as a checked
3274
+ // cast because we don't want to tell the user to use as!, as it's probably
3275
+ // the wrong suggestion.
3270
3276
if (contextKind == CheckedCastContextKind::Coercion)
3271
3277
return failed ();
3272
3278
return castKind;
@@ -3301,6 +3307,8 @@ CheckedCastKind TypeChecker::typeCheckCheckedCast(Type fromType,
3301
3307
break ;
3302
3308
3303
3309
case CheckedCastKind::Unresolved:
3310
+ // Handled the same as in checkElementCast; see comment there for
3311
+ // rationale.
3304
3312
if (contextKind == CheckedCastContextKind::Coercion)
3305
3313
return failed ();
3306
3314
LLVM_FALLTHROUGH;
@@ -3326,6 +3334,8 @@ CheckedCastKind TypeChecker::typeCheckCheckedCast(Type fromType,
3326
3334
break ;
3327
3335
3328
3336
case CheckedCastKind::Unresolved:
3337
+ // Handled the same as in checkElementCast; see comment there for
3338
+ // rationale.
3329
3339
if (contextKind == CheckedCastContextKind::Coercion)
3330
3340
return failed ();
3331
3341
LLVM_FALLTHROUGH;
@@ -3566,8 +3576,7 @@ CheckedCastKind TypeChecker::typeCheckCheckedCast(Type fromType,
3566
3576
}
3567
3577
} else if (auto protocolComposition =
3568
3578
fromType->getAs <ProtocolCompositionType>()) {
3569
- if (!protocolComposition->getMembers ().empty () &&
3570
- llvm::any_of (protocolComposition->getMembers (),
3579
+ if (llvm::any_of (protocolComposition->getMembers (),
3571
3580
[&](Type protocolType) {
3572
3581
if (auto protocolDecl = dyn_cast_or_null<ProtocolDecl>(
3573
3582
protocolType->getAnyNominal ())) {
0 commit comments