@@ -88,19 +88,35 @@ object Checkable {
88
88
}
89
89
}
90
90
91
+ def maximize (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
+ if (variance == 0 ) range(lo, hi)
97
+ else if (variance == 1 ) hi
98
+ else lo
99
+ case _ =>
100
+ mapOver(tp)
101
+ }
102
+ }
103
+
91
104
def isClassDetermined (X : Type , P : AppliedType )(implicit ctx : Context ) = {
92
105
val AppliedType (tycon, _) = P
93
106
val typeLambda = tycon.ensureLambdaSub.asInstanceOf [TypeLambda ]
94
107
val tvars = constrained(typeLambda, untpd.EmptyTree , alwaysAddTypeVars = true )._2.map(_.tpe)
95
108
val P1 = tycon.appliedTo(tvars)
96
109
97
- debug.println(" P : " + P .show)
98
- debug.println(" P1 : " + P1 .show)
99
- debug.println(" X : " + X .show)
110
+ debug.println(" P : " + P )
111
+ debug.println(" P1 : " + P1 )
112
+ debug.println(" X : " + X )
113
+
114
+ P1 <:< X // constraint P1
100
115
101
- P1 <:< X // may fail, ignore
116
+ // use fromScala2x to avoid generating pattern bound symbols
117
+ maximizeType(P1 , pos, fromScala2x = true )
102
118
103
- val res = isFullyDefined( P1 , ForceDegree .noBottom) && P1 <:< P
119
+ val res = P1 <:< P
104
120
debug.println(" P1 : " + P1 )
105
121
debug.println(" P1 <:< P = " + res)
106
122
@@ -116,7 +132,9 @@ object Checkable {
116
132
case defn.ArrayOf (tpE) => recur(tpE, tpT)
117
133
case _ => recur(defn.AnyType , tpT)
118
134
}
119
- case tpe : AppliedType => isClassDetermined(X , tpe)(ctx.fresh.setNewTyperState())
135
+ case tpe : AppliedType =>
136
+ isClassDetermined(X , tpe)(ctx.fresh.setNewTyperState()) ||
137
+ isClassDetermined(maximize.apply(X ), tpe)(ctx.fresh.setNewTyperState())
120
138
case AndType (tp1, tp2) => recur(X , tp1) && recur(X , tp2)
121
139
case OrType (tp1, tp2) => recur(X , tp1) && recur(X , tp2)
122
140
case AnnotatedType (t, _) => recur(X , t)
0 commit comments