@@ -226,13 +226,13 @@ class TypeComparer(initctx: Context) extends ConstraintHandling[AbsentContext] {
226226 implicit val ctx : Context = this .ctx
227227 tp2.info match {
228228 case info2 : TypeAlias =>
229- recur(tp1, info2.alias) || tryPackagePrefix2(tp1, tp2)
229+ recur(tp1, info2.alias)
230230 case _ => tp1 match {
231231 case tp1 : NamedType =>
232232 tp1.info match {
233233 case info1 : TypeAlias =>
234234 if (recur(info1.alias, tp2)) return true
235- if (tp1.prefix.isStable) return tryPackagePrefix1(tp1, tp2)
235+ if (tp1.prefix.isStable) return false
236236 // If tp1.prefix is stable, the alias does contain all information about the original ref, so
237237 // there's no need to try something else. (This is important for performance).
238238 // To see why we cannot in general stop here, consider:
@@ -254,7 +254,7 @@ class TypeComparer(initctx: Context) extends ConstraintHandling[AbsentContext] {
254254 if ((sym1 ne NoSymbol ) && (sym1 eq sym2))
255255 ctx.erasedTypes ||
256256 sym1.isStaticOwner ||
257- isSubType(stripPackageObject( tp1.prefix), stripPackageObject( tp2.prefix) ) ||
257+ isSubType(tp1.prefix, tp2.prefix) ||
258258 thirdTryNamed(tp2)
259259 else
260260 ( (tp1.name eq tp2.name)
@@ -353,7 +353,7 @@ class TypeComparer(initctx: Context) extends ConstraintHandling[AbsentContext] {
353353 tp1.info match {
354354 case info1 : TypeAlias =>
355355 if (recur(info1.alias, tp2)) return true
356- if (tp1.prefix.isStable) return tryPackagePrefix1(tp1, tp2)
356+ if (tp1.prefix.isStable) return tryLiftedToThis1
357357 case _ =>
358358 if (tp1 eq NothingType ) return true
359359 }
@@ -456,7 +456,7 @@ class TypeComparer(initctx: Context) extends ConstraintHandling[AbsentContext] {
456456 narrowGADTBounds(tp2, tp1, approx, isUpper = false )) &&
457457 { tp1.isRef(NothingClass ) || GADTusage (tp2.symbol) }
458458 }
459- isSubApproxHi(tp1, info2.lo) || compareGADT || fourthTry
459+ isSubApproxHi(tp1, info2.lo) || compareGADT || tryLiftedToThis2 || fourthTry
460460
461461 case _ =>
462462 val cls2 = tp2.symbol
@@ -715,7 +715,7 @@ class TypeComparer(initctx: Context) extends ConstraintHandling[AbsentContext] {
715715 narrowGADTBounds(tp1, tp2, approx, isUpper = true )) &&
716716 { tp2.isRef(AnyClass ) || GADTusage (tp1.symbol) }
717717 }
718- isSubType(hi1, tp2, approx.addLow) || compareGADT
718+ isSubType(hi1, tp2, approx.addLow) || compareGADT || tryLiftedToThis1
719719 case _ =>
720720 def isNullable (tp : Type ): Boolean = tp.widenDealias match {
721721 case tp : TypeRef => tp.symbol.isNullableClass
@@ -959,7 +959,8 @@ class TypeComparer(initctx: Context) extends ConstraintHandling[AbsentContext] {
959959 case _ =>
960960 fourthTry
961961 }
962- }
962+ } || tryLiftedToThis2
963+
963964 case _ : TypeVar =>
964965 recur(tp1, tp2.superType)
965966 case tycon2 : AnnotatedType if ! tycon2.isRefining =>
@@ -986,9 +987,11 @@ class TypeComparer(initctx: Context) extends ConstraintHandling[AbsentContext] {
986987 isSubType(bounds(param1).hi.applyIfParameterized(args1), tp2, approx.addLow)
987988 case tycon1 : TypeRef =>
988989 val sym = tycon1.symbol
989- ! sym.isClass && (
990+ ! sym.isClass && {
990991 defn.isCompiletime_S(sym) && compareS(tp1, tp2, fromBelow = false ) ||
991- recur(tp1.superType, tp2))
992+ recur(tp1.superType, tp2) ||
993+ tryLiftedToThis1
994+ }
992995 case tycon1 : TypeProxy =>
993996 recur(tp1.superType, tp2)
994997 case _ =>
@@ -1029,6 +1032,16 @@ class TypeComparer(initctx: Context) extends ConstraintHandling[AbsentContext] {
10291032 def isSubApproxHi (tp1 : Type , tp2 : Type ): Boolean =
10301033 tp1.eq(tp2) || tp2.ne(NothingType ) && isSubType(tp1, tp2, approx.addHigh)
10311034
1035+ def tryLiftedToThis1 : Boolean = {
1036+ val tp1a = liftToThis(tp1)
1037+ (tp1a ne tp1) && recur(tp1a, tp2)
1038+ }
1039+
1040+ def tryLiftedToThis2 : Boolean = {
1041+ val tp2a = liftToThis(tp2)
1042+ (tp2a ne tp2) && recur(tp1, tp2a)
1043+ }
1044+
10321045 // begin recur
10331046 if (tp2 eq NoType ) false
10341047 else if (tp1 eq tp2) true
@@ -1058,31 +1071,39 @@ class TypeComparer(initctx: Context) extends ConstraintHandling[AbsentContext] {
10581071 }
10591072 }
10601073
1061- /** If `tp` is a reference to a package object, a reference to the package itself,
1062- * otherwise `tp`.
1063- */
1064- private def stripPackageObject (tp : Type ) = tp match {
1065- case tp : TermRef if tp.symbol.isPackageObject => tp.symbol.owner.thisType
1066- case tp : ThisType if tp.cls.isPackageObject => tp.cls.owner.thisType
1067- case _ => tp
1068- }
1069-
1070- /** If prefix of `tp1` is a reference to a package object, retry with
1071- * the prefix pointing to the package itself, otherwise `false`
1072- */
1073- private def tryPackagePrefix1 (tp1 : NamedType , tp2 : Type ) = {
1074- val pre1 = tp1.prefix
1075- val pre1a = stripPackageObject(pre1)
1076- (pre1a ne pre1) && isSubType(tp1.withPrefix(pre1a), tp2)
1077- }
1078-
1079- /** If prefix of `tp2` is a reference to a package object, retry with
1080- * the prefix pointing to the package itself, otherwise `false`
1074+ /** If `tp` is an external reference to an enclosing module M that contains opaque types,
1075+ * convert to M.this.
1076+ * Note: It would be legal to do the lifting also if M does not contain opaque types,
1077+ * but in this case the retries in tryLiftedToThis would be redundant.
10811078 */
1082- private def tryPackagePrefix2 (tp1 : Type , tp2 : NamedType ) = {
1083- val pre2 = tp2.prefix
1084- val pre2a = stripPackageObject(pre2)
1085- (pre2a ne pre2) && isSubType(tp1, tp2.withPrefix(pre2a))
1079+ private def liftToThis (tp : Type ): Type = {
1080+
1081+ def findEnclosingThis (moduleClass : Symbol , from : Symbol ): Type =
1082+ if ((from.owner eq moduleClass) && from.isPackageObject && from.is(Opaque )) from.thisType
1083+ else if (from.is(Package )) tp
1084+ else if ((from eq moduleClass) && from.is(Opaque )) from.thisType
1085+ else if (from eq NoSymbol ) tp
1086+ else findEnclosingThis(moduleClass, from.owner)
1087+
1088+ tp.stripTypeVar.stripAnnots match {
1089+ case tp : TermRef if tp.symbol.is(Module ) =>
1090+ findEnclosingThis(tp.symbol.moduleClass, ctx.owner)
1091+ case tp : TypeRef =>
1092+ val pre1 = liftToThis(tp.prefix)
1093+ if (pre1 ne tp.prefix) tp.withPrefix(pre1) else tp
1094+ case tp : ThisType if tp.cls.is(Package ) =>
1095+ findEnclosingThis(tp.cls, ctx.owner)
1096+ case tp : AppliedType =>
1097+ val tycon1 = liftToThis(tp.tycon)
1098+ if (tycon1 ne tp.tycon) tp.derivedAppliedType(tycon1, tp.args) else tp
1099+ case tp : TypeVar if tp.isInstantiated =>
1100+ liftToThis(tp.inst)
1101+ case tp : AnnotatedType =>
1102+ val parent1 = liftToThis(tp.parent)
1103+ if (parent1 ne tp.parent) tp.derivedAnnotatedType(parent1, tp.annot) else tp
1104+ case _ =>
1105+ tp
1106+ }
10861107 }
10871108
10881109 /** Optionally, the `n` such that `tp <:< ConstantType(Constant(n: Int))` */
0 commit comments