@@ -3037,7 +3037,9 @@ CheckedCastKind TypeChecker::typeCheckCheckedCast(Type fromType,
30373037 Expr *fromExpr,
30383038 SourceRange diagToRange) {
30393039 // Determine whether we should suppress diagnostics.
3040- const bool suppressDiagnostics = contextKind == CheckedCastContextKind::None;
3040+ const bool suppressDiagnostics =
3041+ contextKind == CheckedCastContextKind::None ||
3042+ contextKind == CheckedCastContextKind::CollectionElement;
30413043 assert ((suppressDiagnostics || diagLoc.isValid ()) &&
30423044 " diagnostics require a valid source location" );
30433045
@@ -3101,7 +3103,18 @@ CheckedCastKind TypeChecker::typeCheckCheckedCast(Type fromType,
31013103 .highlight (diagFromRange)
31023104 .highlight (diagToRange);
31033105 }
3104- return CheckedCastKind::Unresolved;
3106+
3107+ // In the context of collection element we just return a value cast
3108+ // becasue there may be situation where this can be convertible
3109+ // at runtime. e.g.
3110+ //
3111+ // func f(a: [Any], b: [AnyObject]) {
3112+ // _ = a is [String?] // Ok
3113+ // - = b is [String?] // Ok
3114+ // }
3115+ return (contextKind != CheckedCastContextKind::CollectionElement)
3116+ ? CheckedCastKind::Unresolved
3117+ : CheckedCastKind::ValueCast;
31053118 }
31063119
31073120 toType = toValueType;
@@ -3132,6 +3145,7 @@ CheckedCastKind TypeChecker::typeCheckCheckedCast(Type fromType,
31323145 !fromType->isEqual (toType) && !isConvertibleTo (fromType, toType, dc);
31333146
31343147 switch (contextKind) {
3148+ case CheckedCastContextKind::CollectionElement:
31353149 case CheckedCastContextKind::None:
31363150 llvm_unreachable (" suppressing diagnostics" );
31373151
@@ -3249,12 +3263,8 @@ CheckedCastKind TypeChecker::typeCheckCheckedCast(Type fromType,
32493263
32503264 auto checkElementCast = [&](Type fromElt, Type toElt,
32513265 CheckedCastKind castKind) -> CheckedCastKind {
3252- // Let's not emit diagnostic when the element type is erased because
3253- // we can't statically know if element is convertible.
3254- if (fromElt->isAny () || toElt->isAny ())
3255- return castKind;
3256-
3257- switch (typeCheckCheckedCast (fromElt, toElt, CheckedCastContextKind::None,
3266+ switch (typeCheckCheckedCast (fromElt, toElt,
3267+ CheckedCastContextKind::CollectionElement,
32583268 dc, SourceLoc (), nullptr , SourceRange ())) {
32593269 case CheckedCastKind::Coercion:
32603270 return CheckedCastKind::Coercion;
@@ -3428,6 +3438,7 @@ CheckedCastKind TypeChecker::typeCheckCheckedCast(Type fromType,
34283438 case CheckedCastContextKind::EnumElementPattern:
34293439 case CheckedCastContextKind::IsExpr:
34303440 case CheckedCastContextKind::None:
3441+ case CheckedCastContextKind::CollectionElement:
34313442 break ;
34323443 }
34333444 }
0 commit comments