@@ -262,13 +262,13 @@ class TypeComparer(initctx: Context) extends ConstraintHandling[AbsentContext] w
262
262
if ((sym1 ne NoSymbol ) && (sym1 eq sym2))
263
263
ctx.erasedTypes ||
264
264
sym1.isStaticOwner ||
265
- isSubType (tp1.prefix, tp2.prefix) ||
265
+ isSubPrefix (tp1.prefix, tp2.prefix) ||
266
266
thirdTryNamed(tp2)
267
267
else
268
268
( (tp1.name eq tp2.name)
269
269
&& tp1.isMemberRef
270
270
&& tp2.isMemberRef
271
- && isSubType (tp1.prefix, tp2.prefix)
271
+ && isSubPrefix (tp1.prefix, tp2.prefix)
272
272
&& tp1.signature == tp2.signature
273
273
&& ! (sym1.isClass && sym2.isClass) // class types don't subtype each other
274
274
) ||
@@ -297,12 +297,6 @@ class TypeComparer(initctx: Context) extends ConstraintHandling[AbsentContext] w
297
297
def compareThis = {
298
298
val cls2 = tp2.cls
299
299
tp1 match {
300
- case tp1 : ThisType =>
301
- // We treat two prefixes A.this, B.this as equivalent if
302
- // A's selftype derives from B and B's selftype derives from A.
303
- val cls1 = tp1.cls
304
- cls1.classInfo.selfType.derivesFrom(cls2) &&
305
- cls2.classInfo.selfType.derivesFrom(cls1)
306
300
case tp1 : NamedType if cls2.is(Module ) && cls2.eq(tp1.widen.typeSymbol) =>
307
301
cls2.isStaticOwner ||
308
302
recur(tp1.prefix, cls2.owner.thisType) ||
@@ -498,7 +492,7 @@ class TypeComparer(initctx: Context) extends ConstraintHandling[AbsentContext] w
498
492
if (base.typeSymbol == cls2) return true
499
493
}
500
494
else if tp1.isLambdaSub && ! tp1.isAnyKind then
501
- return recur(tp1, EtaExpansion (cls2.typeRef ))
495
+ return recur(tp1, EtaExpansion (tp2 ))
502
496
fourthTry
503
497
}
504
498
@@ -820,6 +814,44 @@ class TypeComparer(initctx: Context) extends ConstraintHandling[AbsentContext] w
820
814
false
821
815
}
822
816
817
+ /** When called from `pre1.A <:< pre2.A` does `pre1` relate to `pre2` so that
818
+ * the subtype test is true? This is the case if `pre1 <:< pre2`, or
819
+ * `pre1` and `pre2` are both this-types of related classes. Here, two classes
820
+ * are related if each of them has a self type that derives from the other.
821
+ *
822
+ * This criterion is a bit dubious. I.e. in the test
823
+ *
824
+ * A.this.T <:< B.this.T
825
+ *
826
+ * where `T` is the same type, what relationship must exist between A and B
827
+ * for the test to be guaranteed true? The problem is we can't tell without additional
828
+ * info. One could be an outer this at the point where we do the test, but that
829
+ * location is unknown to us.
830
+ *
831
+ * The conservative choice would be to require A == B, but then some tests involving
832
+ * self types fail. Specifically, t360, t361 and pat_iuli fail the pickling test, and
833
+ * Namer fails to compile. At line 203, we get
834
+ *
835
+ * val Deriver : Property.Key[typer.Deriver] = new Property.Key
836
+ * ^
837
+ * value Deriver in class Namer is not a legal implementation of `Deriver` in class Namer.
838
+ * its type dotty.tools.dotc.util.Property.Key[Namer.this.Deriver]
839
+ |* does not conform to dotty.tools.dotc.util.Property.Key[Typer.this.Deriver & Namer.this.Deriver]
840
+ */
841
+ def isSubPrefix (pre1 : Type , pre2 : Type ): Boolean =
842
+ pre1 match
843
+ case pre1 : ThisType =>
844
+ pre2 match
845
+ case pre2 : ThisType =>
846
+ if pre1.cls.classInfo.selfType.derivesFrom(pre2.cls)
847
+ && pre2.cls.classInfo.selfType.derivesFrom(pre1.cls)
848
+ then
849
+ subtyping.println(i " assume equal prefixes $pre1 $pre2" )
850
+ return true
851
+ case _ =>
852
+ case _ =>
853
+ isSubType(pre1, pre2)
854
+
823
855
/** Subtype test for the hk application `tp2 = tycon2[args2]`.
824
856
*/
825
857
def compareAppliedType2 (tp2 : AppliedType , tycon2 : Type , args2 : List [Type ]): Boolean = {
@@ -858,7 +890,7 @@ class TypeComparer(initctx: Context) extends ConstraintHandling[AbsentContext] w
858
890
859
891
val res = (
860
892
tycon1sym == tycon2sym
861
- && isSubType (tycon1.prefix, tycon2.prefix)
893
+ && isSubPrefix (tycon1.prefix, tycon2.prefix)
862
894
|| byGadtBounds(tycon1sym, tycon2, fromAbove = true )
863
895
|| byGadtBounds(tycon2sym, tycon1, fromAbove = false )
864
896
) && {
0 commit comments