Skip to content

Commit

Permalink
Dealias before checking for outer references in types (#16525)
Browse files Browse the repository at this point in the history
Fixes #15827
  • Loading branch information
odersky authored Dec 17, 2022
2 parents 4d9a0a0 + 71c90ff commit f3f8ae6
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 5 deletions.
10 changes: 5 additions & 5 deletions compiler/src/dotty/tools/dotc/transform/ExplicitOuter.scala
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,6 @@ object ExplicitOuter {
*/
def referencesOuter(cls: Symbol, tree: Tree)(using Context): Boolean =


val test = new TreeAccumulator[Boolean]:
private var inInline = false

Expand Down Expand Up @@ -302,19 +301,20 @@ object ExplicitOuter {
def containsOuterRefs(t: Tree): Boolean = t match
case _: This | _: Ident => isOuterRef(t.tpe)
case nw: New =>
val newCls = nw.tpe.classSymbol
val newType = nw.tpe.dealias
val newCls = newType.classSymbol
isOuterSym(newCls.owner.enclosingClass) ||
hasOuterPrefix(nw.tpe) ||
hasOuterPrefix(newType) ||
newCls.owner.isTerm && cls.isProperlyContainedIn(newCls)
// newCls might get proxies for free variables. If current class is
// properly contained in newCls, it needs an outer path to newCls access the
// proxies and forward them to the new instance.
case app: TypeApply if app.symbol.isTypeTest =>
// Type tests of singletons translate to `eq` tests with references, which might require outer pointers
containsOuterRefsAtTopLevel(app.args.head.tpe)
containsOuterRefsAtTopLevel(app.args.head.tpe.dealias)
case t: TypeTree if inInline =>
// Expansions of inline methods must be able to address outer types
containsOuterRefsAnywhere(t.tpe)
containsOuterRefsAnywhere(t.tpe.dealias)
case _ =>
false

Expand Down
1 change: 1 addition & 0 deletions compiler/test/dotc/pos-test-pickling.blacklist
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ i9999.scala
i6505.scala
i15158.scala
i15155.scala
i15827.scala

# Opaque type
i5720.scala
Expand Down
55 changes: 55 additions & 0 deletions tests/pos/i15827.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@

trait Mirr {
type MirroredTp
type Elems <: Tuple
}
trait MirrP extends Mirr {
def fromProduct(x: Product): MirroredTp
}
trait MirrS extends Mirr

def outer3Local = {
class Wrapper {
object Nested {
sealed trait Color
}
}
val wrapper = new Wrapper
import wrapper.Nested.Color

object Inner {
case object Red extends Color
case object Green extends Color
case object Blue extends Color
case class Rgb(hex: Int) extends Color
case object Rgb
}

object CallSite {
def run =
import Inner.*
val M: (MirrS { type MirroredTp = Color; type Elems = (Inner.Red.type, Inner.Green.type, Inner.Blue.type, Inner.Rgb) }) =
new MirrS {
type MirroredTp = Color
type Elems = (Inner.Red.type, Inner.Green.type, Inner.Blue.type, Inner.Rgb)
}

val M_Rgb =
type TRgb = Tuple.Elem[M.Elems, 3]
new MirrP {
type MirroredTp = TRgb
type Elems = Int *: EmptyTuple

def fromProduct(x: Product): MirroredTp =
new TRgb(x.productElement(0).asInstanceOf[Int])
}: (MirrP {
type MirroredTp = TRgb
type Elems = Int *: EmptyTuple
})
}

CallSite.run
}

@main def Test =
outer3Local

0 comments on commit f3f8ae6

Please sign in to comment.