@@ -88,19 +88,33 @@ object Checkable {
8888 }
8989 }
9090
91+ def stripTypeParam (implicit ctx : Context ) = new ApproximatingTypeMap {
92+ def apply (tp : Type ): Type = tp match {
93+ case tp : TypeRef if tp.underlying.isInstanceOf [TypeBounds ] =>
94+ val lo = this (tp.info.loBound)
95+ val hi = this (tp.info.hiBound)
96+ range(lo, hi)
97+ case _ =>
98+ mapOver(tp)
99+ }
100+ }
101+
91102 def isClassDetermined (X : Type , P : AppliedType )(implicit ctx : Context ) = {
92103 val AppliedType (tycon, _) = P
93104 val typeLambda = tycon.ensureLambdaSub.asInstanceOf [TypeLambda ]
94105 val tvars = constrained(typeLambda, untpd.EmptyTree , alwaysAddTypeVars = true )._2.map(_.tpe)
95106 val P1 = tycon.appliedTo(tvars)
96107
97- debug.println(" P : " + P .show)
98- debug.println(" P1 : " + P1 .show)
99- debug.println(" X : " + X .show)
108+ debug.println(" P : " + P )
109+ debug.println(" P1 : " + P1 )
110+ debug.println(" X : " + X )
111+
112+ P1 <:< X // constraint P1
100113
101- P1 <:< X // may fail, ignore
114+ // use fromScala2x to avoid generating pattern bound symbols
115+ maximizeType(P1 , pos, fromScala2x = true )
102116
103- val res = isFullyDefined( P1 , ForceDegree .noBottom) && P1 <:< P
117+ val res = P1 <:< P
104118 debug.println(" P1 : " + P1 )
105119 debug.println(" P1 <:< P = " + res)
106120
@@ -116,7 +130,9 @@ object Checkable {
116130 case defn.ArrayOf (tpE) => recur(tpE, tpT)
117131 case _ => recur(defn.AnyType , tpT)
118132 }
119- case tpe : AppliedType => isClassDetermined(X , tpe)(ctx.fresh.setNewTyperState())
133+ case tpe : AppliedType =>
134+ isClassDetermined(X , tpe)(ctx.fresh.setNewTyperState()) ||
135+ isClassDetermined(stripTypeParam.apply(X ), tpe)(ctx.fresh.setNewTyperState())
120136 case AndType (tp1, tp2) => recur(X , tp1) && recur(X , tp2)
121137 case OrType (tp1, tp2) => recur(X , tp1) && recur(X , tp2)
122138 case AnnotatedType (t, _) => recur(X , t)
0 commit comments