Skip to content

Identify package and nested package object in isSubPrefix #12297

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 10, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 22 additions & 4 deletions compiler/src/dotty/tools/dotc/core/TypeComparer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -848,11 +848,15 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
}

/** When called from `pre1.A <:< pre2.A` does `pre1` relate to `pre2` so that
* the subtype test is true? This is the case if `pre1 <:< pre2`, or
* `pre1` and `pre2` are both this-types of related classes. Here, two classes
* are related if each of them has a self type that derives from the other.
* the subtype test is true? This is the case if
*
* This criterion is a bit dubious. I.e. in the test
* 1. `pre1 <:< pre2`, or
* 2. One of `pre1` and `pre2` refers to a package and the other to a
* package object in that package, or
* 3. `pre1` and `pre2` are both this-types of related classes.
*
* Here, two classes are related if each of them has a self type that derives from the other.
* The third criterion is a bit dubious. I.e. in the test
*
* A.this.T <:< B.this.T
*
Expand All @@ -872,18 +876,32 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
|* does not conform to dotty.tools.dotc.util.Property.Key[Typer.this.Deriver & Namer.this.Deriver]
*/
def isSubPrefix(pre1: Type, pre2: Type): Boolean =
def samePkg(sym1: Symbol, sym2: Symbol) =
sym2.is(Package) && sym1.isPackageObject && sym1.owner == sym2.moduleClass
|| sym1.is(Package) && sym2.isPackageObject && sym2.owner == sym1.moduleClass
pre1 match
case pre1: ThisType =>
pre2 match
case pre2: ThisType =>
if samePkg(pre1.cls, pre2.cls) then return true
if pre1.cls.classInfo.selfType.derivesFrom(pre2.cls)
&& pre2.cls.classInfo.selfType.derivesFrom(pre1.cls)
then
subtyping.println(i"assume equal prefixes $pre1 $pre2")
return true
case pre2: TermRef =>
if samePkg(pre1.cls, pre2.symbol) then return true
case _ =>
case pre1: TermRef =>
pre2 match
case pre2: TermRef =>
if samePkg(pre1.symbol, pre2.symbol) then return true
case pre2: ThisType =>
if samePkg(pre1.symbol, pre2.cls) then return true
case _ =>
case _ =>
isSubType(pre1, pre2)
end isSubPrefix

/** Compare `tycon[args]` with `other := otherTycon[otherArgs]`, via `>:>` if fromBelow is true, `<:<` otherwise
* (we call this relationship `~:~` in the rest of this comment).
Expand Down
9 changes: 9 additions & 0 deletions tests/pos/i12168.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package A {
opaque type T = Int
def t: T = 0
}

package B {
export A.T
val t: B.T = A.t
}