This transform normalizes type tests and type casts, also replacing type tests with singleton argument type with reference equality check Any remaining type tests
use the object methods $isInstanceOf and $asInstanceOf
have a reference type as receiver
can be translated directly to machine instructions
Unfortunately this phase ended up being not Y-checkable unless types are erased. A cast to an ConstantType(3) or x.type cannot be rewritten before erasure. That's why TypeTestsCasts is called from Erasure.
Tests whether (x: X).isInstanceOf[P] is uncheckable at runtime, returning the reason, or the empty string if it is checkable.
Tests whether (x: X).isInstanceOf[P] is uncheckable at runtime, returning the reason, or the empty string if it is checkable.
First do the following substitution: (a) replace T @unchecked and pattern binder types (e.g., _$1) in P with WildcardType
Then check:
if X <:< P, ""
if P is a singleton type, ""
if P refers to an abstract type member or type parameter, "it refers to an abstract type member or type parameter"
if P = Array[T], checkable(E, T) where E is the element type of X, defaults to Any.
if P is pre.F[Ts] and pre.F refers to a class which is not Array: (a) replace Ts with fresh type variables Xs (b) constrain Xs with pre.F[Xs] <:< X (c) maximize pre.F[Xs] (d) if !pre.F[Xs] <:< P, "its type arguments can't be determined from $X"
if P = T1 | T2 or P = T1 & T2, checkable(X, T1) && checkable(X, T2).
if P is a refinement type, "it's a refinement type"
if P is a local class which is not statically reachable from the scope where X is defined, "it's a local class"
if X is T1 | T2, checkable(T1, P) && checkable(T2, P).