@@ -140,21 +140,14 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling wi
140
140
141
141
private def firstTry (tp1 : Type , tp2 : Type ): Boolean = tp2 match {
142
142
case tp2 : NamedType =>
143
- def compareHKOrAlias (info1 : Type ) =
144
- tp2.name == tpnme.Apply && {
145
- val lambda2 = tp2.prefix.LambdaClass (forcing = true )
146
- lambda2.exists && ! tp1.isLambda &&
147
- tp1.testLifted(lambda2.typeParams, isSubType(_, tp2.prefix))
148
- } || {
149
- tp2.info match {
150
- case info2 : TypeAlias => isSubType(tp1, info2.alias)
151
- case _ => info1 match {
152
- case info1 : TypeAlias => isSubType(info1.alias, tp2)
153
- case NoType => secondTry(tp1, tp2)
154
- case _ => thirdTryNamed(tp1, tp2)
155
- }
156
- }
143
+ def compareAlias (info1 : Type ) = tp2.info match {
144
+ case info2 : TypeAlias => isSubType(tp1, info2.alias)
145
+ case _ => info1 match {
146
+ case info1 : TypeAlias => isSubType(info1.alias, tp2)
147
+ case NoType => secondTry(tp1, tp2)
148
+ case _ => thirdTryNamed(tp1, tp2)
157
149
}
150
+ }
158
151
def compareNamed = {
159
152
implicit val ctx : Context = this .ctx // Dotty deviation: implicits need explicit type
160
153
tp1 match {
@@ -183,9 +176,12 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling wi
183
176
! tp1.isInstanceOf [WithFixedSym ] &&
184
177
! tp2.isInstanceOf [WithFixedSym ]
185
178
) ||
186
- compareHKOrAlias(tp1.info)
179
+ compareHK(tp1, tp2, inOrder = true ) ||
180
+ compareHK(tp2, tp1, inOrder = false ) ||
181
+ compareAlias(tp1.info)
187
182
case _ =>
188
- compareHKOrAlias(NoType )
183
+ compareHK(tp2, tp1, inOrder = false ) ||
184
+ compareAlias(NoType )
189
185
}
190
186
}
191
187
compareNamed
@@ -243,7 +239,9 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling wi
243
239
case tp1 : NamedType =>
244
240
tp1.info match {
245
241
case info1 : TypeAlias => isSubType(info1.alias, tp2)
246
- case _ => thirdTry(tp1, tp2)
242
+ case _ => compareHK(tp1, tp2, inOrder = true ) || thirdTry(tp1, tp2)
243
+ // Note: If we change the order here, doing compareHK first and following aliases second,
244
+ // we get a -Ycheck error when compiling dotc/transform. Need to investigate.
247
245
}
248
246
case tp1 : PolyParam =>
249
247
def flagNothingBound = {
@@ -460,6 +458,18 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling wi
460
458
false
461
459
}
462
460
461
+ /** If `projection` is of the form T # Apply where `T` is an instance of a Lambda class,
462
+ * and `other` is not a type lambda projection, then convert `other` to a type lambda `U`, and
463
+ * continue with `T <:< U` if `inOrder` is true and `U <:< T` otherwise.
464
+ */
465
+ def compareHK (projection : NamedType , other : Type , inOrder : Boolean ) =
466
+ projection.name == tpnme.Apply && {
467
+ val lambda = projection.prefix.LambdaClass (forcing = true )
468
+ lambda.exists && ! other.isLambda &&
469
+ other.testLifted(lambda.typeParams,
470
+ if (inOrder) isSubType(projection.prefix, _) else isSubType(_, projection.prefix))
471
+ }
472
+
463
473
/** Returns true iff either `tp11 <:< tp21` or `tp12 <:< tp22`, trying at the same time
464
474
* to keep the constraint as wide as possible. Specifically, if
465
475
*
@@ -524,7 +534,7 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling wi
524
534
case mbr : SingleDenotation => qualifies(mbr)
525
535
case _ => mbr hasAltWith qualifies
526
536
}
527
- /* >|>*/ ctx.traceIndented(i " hasMatchingMember( $tp1 . $name :? ${tp2.refinedInfo}) ${tp1 .member(name).info.show} $rinfo2" , subtyping) /* <|<*/ {
537
+ /* >|>*/ ctx.traceIndented(i " hasMatchingMember( $base . $name :? ${tp2.refinedInfo}) ${base .member(name).info.show} $rinfo2" , subtyping) /* <|<*/ {
528
538
memberMatches(base member name) ||
529
539
tp1.isInstanceOf [SingletonType ] &&
530
540
{ // special case for situations like:
0 commit comments