Skip to content

Commit b981f56

Browse files
authored
Merge pull request #12297 from dotty-staging/fix-12168
Identify package and nested package object in isSubPrefix
2 parents f5bfed9 + adcee1a commit b981f56

File tree

2 files changed

+31
-4
lines changed

2 files changed

+31
-4
lines changed

compiler/src/dotty/tools/dotc/core/TypeComparer.scala

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -850,11 +850,15 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
850850
}
851851

852852
/** When called from `pre1.A <:< pre2.A` does `pre1` relate to `pre2` so that
853-
* the subtype test is true? This is the case if `pre1 <:< pre2`, or
854-
* `pre1` and `pre2` are both this-types of related classes. Here, two classes
855-
* are related if each of them has a self type that derives from the other.
853+
* the subtype test is true? This is the case if
856854
*
857-
* This criterion is a bit dubious. I.e. in the test
855+
* 1. `pre1 <:< pre2`, or
856+
* 2. One of `pre1` and `pre2` refers to a package and the other to a
857+
* package object in that package, or
858+
* 3. `pre1` and `pre2` are both this-types of related classes.
859+
*
860+
* Here, two classes are related if each of them has a self type that derives from the other.
861+
* The third criterion is a bit dubious. I.e. in the test
858862
*
859863
* A.this.T <:< B.this.T
860864
*
@@ -874,18 +878,32 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
874878
|* does not conform to dotty.tools.dotc.util.Property.Key[Typer.this.Deriver & Namer.this.Deriver]
875879
*/
876880
def isSubPrefix(pre1: Type, pre2: Type): Boolean =
881+
def samePkg(sym1: Symbol, sym2: Symbol) =
882+
sym2.is(Package) && sym1.isPackageObject && sym1.owner == sym2.moduleClass
883+
|| sym1.is(Package) && sym2.isPackageObject && sym2.owner == sym1.moduleClass
877884
pre1 match
878885
case pre1: ThisType =>
879886
pre2 match
880887
case pre2: ThisType =>
888+
if samePkg(pre1.cls, pre2.cls) then return true
881889
if pre1.cls.classInfo.selfType.derivesFrom(pre2.cls)
882890
&& pre2.cls.classInfo.selfType.derivesFrom(pre1.cls)
883891
then
884892
subtyping.println(i"assume equal prefixes $pre1 $pre2")
885893
return true
894+
case pre2: TermRef =>
895+
if samePkg(pre1.cls, pre2.symbol) then return true
896+
case _ =>
897+
case pre1: TermRef =>
898+
pre2 match
899+
case pre2: TermRef =>
900+
if samePkg(pre1.symbol, pre2.symbol) then return true
901+
case pre2: ThisType =>
902+
if samePkg(pre1.symbol, pre2.cls) then return true
886903
case _ =>
887904
case _ =>
888905
isSubType(pre1, pre2)
906+
end isSubPrefix
889907

890908
/** Compare `tycon[args]` with `other := otherTycon[otherArgs]`, via `>:>` if fromBelow is true, `<:<` otherwise
891909
* (we call this relationship `~:~` in the rest of this comment).

tests/pos/i12168.scala

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package A {
2+
opaque type T = Int
3+
def t: T = 0
4+
}
5+
6+
package B {
7+
export A.T
8+
val t: B.T = A.t
9+
}

0 commit comments

Comments
 (0)