@@ -3267,6 +3267,12 @@ CheckedCastKind TypeChecker::typeCheckCheckedCast(Type fromType,
32673267 return castKind;
32683268
32693269 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.
32703276 if (contextKind == CheckedCastContextKind::Coercion)
32713277 return failed ();
32723278 return castKind;
@@ -3301,6 +3307,8 @@ CheckedCastKind TypeChecker::typeCheckCheckedCast(Type fromType,
33013307 break ;
33023308
33033309 case CheckedCastKind::Unresolved:
3310+ // Handled the same as in checkElementCast; see comment there for
3311+ // rationale.
33043312 if (contextKind == CheckedCastContextKind::Coercion)
33053313 return failed ();
33063314 LLVM_FALLTHROUGH;
@@ -3326,6 +3334,8 @@ CheckedCastKind TypeChecker::typeCheckCheckedCast(Type fromType,
33263334 break ;
33273335
33283336 case CheckedCastKind::Unresolved:
3337+ // Handled the same as in checkElementCast; see comment there for
3338+ // rationale.
33293339 if (contextKind == CheckedCastContextKind::Coercion)
33303340 return failed ();
33313341 LLVM_FALLTHROUGH;
@@ -3566,8 +3576,7 @@ CheckedCastKind TypeChecker::typeCheckCheckedCast(Type fromType,
35663576 }
35673577 } else if (auto protocolComposition =
35683578 fromType->getAs <ProtocolCompositionType>()) {
3569- if (!protocolComposition->getMembers ().empty () &&
3570- llvm::any_of (protocolComposition->getMembers (),
3579+ if (llvm::any_of (protocolComposition->getMembers (),
35713580 [&](Type protocolType) {
35723581 if (auto protocolDecl = dyn_cast_or_null<ProtocolDecl>(
35733582 protocolType->getAnyNominal ())) {
0 commit comments