@@ -88,19 +88,33 @@ object Checkable {
88
88
}
89
89
}
90
90
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
+
91
102
def isClassDetermined (X : Type , P : AppliedType )(implicit ctx : Context ) = {
92
103
val AppliedType (tycon, _) = P
93
104
val typeLambda = tycon.ensureLambdaSub.asInstanceOf [TypeLambda ]
94
105
val tvars = constrained(typeLambda, untpd.EmptyTree , alwaysAddTypeVars = true )._2.map(_.tpe)
95
106
val P1 = tycon.appliedTo(tvars)
96
107
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
100
113
101
- P1 <:< X // may fail, ignore
114
+ // use fromScala2x to avoid generating pattern bound symbols
115
+ maximizeType(P1 , pos, fromScala2x = true )
102
116
103
- val res = isFullyDefined( P1 , ForceDegree .noBottom) && P1 <:< P
117
+ val res = P1 <:< P
104
118
debug.println(" P1 : " + P1 )
105
119
debug.println(" P1 <:< P = " + res)
106
120
@@ -116,7 +130,9 @@ object Checkable {
116
130
case defn.ArrayOf (tpE) => recur(tpE, tpT)
117
131
case _ => recur(defn.AnyType , tpT)
118
132
}
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())
120
136
case AndType (tp1, tp2) => recur(X , tp1) && recur(X , tp2)
121
137
case OrType (tp1, tp2) => recur(X , tp1) && recur(X , tp2)
122
138
case AnnotatedType (t, _) => recur(X , t)
0 commit comments