Skip to content

Commit adcee1a

Browse files
committed
Identity package and nested package object in isSubPrefix
Identity package and nested package object when comparing prefixes of types. Fies #12168
1 parent aadc10f commit adcee1a

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
@@ -848,11 +848,15 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
848848
}
849849

850850
/** When called from `pre1.A <:< pre2.A` does `pre1` relate to `pre2` so that
851-
* the subtype test is true? This is the case if `pre1 <:< pre2`, or
852-
* `pre1` and `pre2` are both this-types of related classes. Here, two classes
853-
* are related if each of them has a self type that derives from the other.
851+
* the subtype test is true? This is the case if
854852
*
855-
* This criterion is a bit dubious. I.e. in the test
853+
* 1. `pre1 <:< pre2`, or
854+
* 2. One of `pre1` and `pre2` refers to a package and the other to a
855+
* package object in that package, or
856+
* 3. `pre1` and `pre2` are both this-types of related classes.
857+
*
858+
* Here, two classes are related if each of them has a self type that derives from the other.
859+
* The third criterion is a bit dubious. I.e. in the test
856860
*
857861
* A.this.T <:< B.this.T
858862
*
@@ -872,18 +876,32 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
872876
|* does not conform to dotty.tools.dotc.util.Property.Key[Typer.this.Deriver & Namer.this.Deriver]
873877
*/
874878
def isSubPrefix(pre1: Type, pre2: Type): Boolean =
879+
def samePkg(sym1: Symbol, sym2: Symbol) =
880+
sym2.is(Package) && sym1.isPackageObject && sym1.owner == sym2.moduleClass
881+
|| sym1.is(Package) && sym2.isPackageObject && sym2.owner == sym1.moduleClass
875882
pre1 match
876883
case pre1: ThisType =>
877884
pre2 match
878885
case pre2: ThisType =>
886+
if samePkg(pre1.cls, pre2.cls) then return true
879887
if pre1.cls.classInfo.selfType.derivesFrom(pre2.cls)
880888
&& pre2.cls.classInfo.selfType.derivesFrom(pre1.cls)
881889
then
882890
subtyping.println(i"assume equal prefixes $pre1 $pre2")
883891
return true
892+
case pre2: TermRef =>
893+
if samePkg(pre1.cls, pre2.symbol) then return true
894+
case _ =>
895+
case pre1: TermRef =>
896+
pre2 match
897+
case pre2: TermRef =>
898+
if samePkg(pre1.symbol, pre2.symbol) then return true
899+
case pre2: ThisType =>
900+
if samePkg(pre1.symbol, pre2.cls) then return true
884901
case _ =>
885902
case _ =>
886903
isSubType(pre1, pre2)
904+
end isSubPrefix
887905

888906
/** Compare `tycon[args]` with `other := otherTycon[otherArgs]`, via `>:>` if fromBelow is true, `<:<` otherwise
889907
* (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)