@@ -31,7 +31,8 @@ object TypeTestsCasts {
3131 import typer .Inferencing .maximizeType
3232 import typer .ProtoTypes .constrained
3333
34- /** Whether `(x: X).isInstanceOf[P]` can be checked at runtime?
34+ /** Tests whether `(x: X).isInstanceOf[P]` is uncheckable at runtime, returning the reason,
35+ * or the empty string if it is checkable.
3536 *
3637 * First do the following substitution:
3738 * (a) replace `T @unchecked` and pattern binder types (e.g., `_$1`) in P with WildcardType
@@ -52,7 +53,7 @@ object TypeTestsCasts {
5253 * 8. if `P` is a local class which is not statically reachable from the scope where `X` is defined, "it's a local class"
5354 * 9. otherwise, ""
5455 */
55- def checkable (X : Type , P : Type , span : Span )(using Context ): String = atPhase(Phases .refchecksPhase.next) {
56+ def whyUncheckable (X : Type , P : Type , span : Span )(using Context ): String = atPhase(Phases .refchecksPhase.next) {
5657 extension (inline s1 : String ) inline def && (inline s2 : String ): String = if s1 == " " then s2 else s1
5758 extension (inline b : Boolean ) inline def ||| (inline s : String ): String = if b then " " else s
5859
@@ -354,10 +355,11 @@ object TypeTestsCasts {
354355 if (sym.isTypeTest) {
355356 val argType = tree.args.head.tpe
356357 val isTrusted = tree.hasAttachment(PatternMatcher .TrustedTypeTestKey )
357- val unchecked = expr.tpe.widenTermRefExpr.hasAnnotation(defn.UncheckedAnnot )
358- val uncheckable = if isTrusted || unchecked then " " else checkable(expr.tpe, argType, tree.span)
359- if (uncheckable != " " )
360- report.uncheckedWarning(i " the type test for $argType cannot be checked at runtime because $uncheckable" , expr.srcPos)
358+ val isUnchecked = expr.tpe.widenTermRefExpr.hasAnnotation(defn.UncheckedAnnot )
359+ if ! isTrusted && ! isUnchecked then
360+ val whyNot = whyUncheckable(expr.tpe, argType, tree.span)
361+ if whyNot.nonEmpty then
362+ report.uncheckedWarning(i " the type test for $argType cannot be checked at runtime because $whyNot" , expr.srcPos)
361363 transformTypeTest(expr, argType,
362364 flagUnrelated = enclosingInlineds.isEmpty) // if test comes from inlined code, dont't flag it even if it always false
363365 }
0 commit comments