Skip to content
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

Dealias before checking for outer references in types #16525

Merged
merged 1 commit into from
Dec 17, 2022
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
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