@@ -4,7 +4,7 @@ package transform
44import util .Positions ._
55import MegaPhase .MiniPhase
66import core ._
7- import Contexts .Context , Types ._ , Decorators ._ , Symbols ._ , typer ._ , ast ._
7+ import Contexts .Context , Types ._ , Decorators ._ , Symbols ._ , typer ._ , ast ._ , NameKinds . _
88import TypeUtils ._ , Flags ._
99import config .Printers .{ transforms => debug }
1010
@@ -18,7 +18,7 @@ class IsInstanceOfChecker extends MiniPhase {
1818
1919 override def transformTypeApply (tree : TypeApply )(implicit ctx : Context ): Tree = {
2020 def ensureCheckable (qual : Tree , pt : Tree ): Tree = {
21- if (! Checkable .checkable(qual.tpe, pt.tpe))
21+ if (! Checkable .checkable(qual.tpe, pt.tpe, tree.pos ))
2222 ctx.warning(
2323 s " the type test for ${pt.show} cannot be checked at runtime " ,
2424 tree.pos
@@ -58,13 +58,14 @@ object Checkable {
5858 * 4. if `P = Array[T]`, checkable(E, T) where `E` is the element type of `X`, defaults to `Any`.
5959 * 5. if `P` is `pre.F[Ts]` and `pre.F` refers to a class which is not `Array`:
6060 * (a) replace `Ts` with fresh type variables `Xs`
61- * (b) constrain `Xs` with `pre.F[Xs] <:< X` (may fail)
61+ * (b) constrain `Xs` with `pre.F[Xs] <:< X`,
62+ * if `X` cannot be uniquely determined, instantiate `X` with fresh type symbol.
6263 * (c) instantiate Xs and check `pre.F[Xs] <:< P`
6364 * 6. if `P = T1 | T2` or `P = T1 & T2`, checkable(X, T1) && checkable(X, T2).
6465 * 7. if `P` is a refinement type, FALSE
6566 * 8. otherwise, TRUE
6667 */
67- def checkable (X : Type , P : Type )(implicit ctx : Context ): Boolean = {
68+ def checkable (X : Type , P : Type , pos : Position )(implicit ctx : Context ): Boolean = {
6869 def isAbstract (P : Type ) = ! P .dealias.typeSymbol.isClass
6970
7071 def replaceP (implicit ctx : Context ) = new TypeMap {
@@ -100,7 +101,17 @@ object Checkable {
100101
101102 P1 <:< X // may fail, ignore
102103
103- val res = isFullyDefined(P1 , ForceDegree .noBottom) && P1 <:< P
104+ tvars.foreach { case tvar : TypeVar =>
105+ val bounds = ctx.typerState.constraint.entry(tvar.origin)
106+ if (bounds.loBound =:= bounds.hiBound)
107+ tvar.instantiateWith(bounds.loBound)
108+ else {
109+ val wildCard = ctx.newSymbol(ctx.owner, WildcardParamName .fresh().toTypeName, Case , tvar.origin.underlying, coord = pos)
110+ tvar.instantiateWith(wildCard.typeRef)
111+ }
112+ }
113+
114+ val res = P1 <:< P
104115 debug.println(" P1 : " + P1 )
105116 debug.println(" P1 <:< P = " + res)
106117
@@ -119,7 +130,7 @@ object Checkable {
119130 case tpe : AppliedType => isClassDetermined(X , tpe)(ctx.fresh.setNewTyperState())
120131 case AndType (tp1, tp2) => recur(X , tp1) && recur(X , tp2)
121132 case OrType (tp1, tp2) => recur(X , tp1) && recur(X , tp2)
122- case AnnotatedType (t, an) => recur(X , t)
133+ case AnnotatedType (t, _) => recur(X , t)
123134 case _ : RefinedType => false
124135 case _ => true
125136 })
0 commit comments