Skip to content

Fix handling of AppliedType aliases in outerPrefix #20190

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 3 commits into from
Apr 25, 2024
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
23 changes: 5 additions & 18 deletions compiler/src/dotty/tools/dotc/transform/ExplicitOuter.scala
Original file line number Diff line number Diff line change
Expand Up @@ -343,25 +343,12 @@ object ExplicitOuter {
private final val HoistableFlags = Method | Lazy | Module

/** The outer prefix implied by type `tpe` */
private def outerPrefix(tpe: Type)(using Context): Type = tpe match {
case tpe: TypeRef =>
tpe.symbol match {
case cls: ClassSymbol =>
if (tpe.prefix eq NoPrefix) cls.owner.enclosingClass.thisType
else tpe.prefix
case _ =>
// Need to be careful to dealias before erasure, otherwise we lose prefixes.
atPhaseNoLater(erasurePhase)(outerPrefix(tpe.underlying))
// underlying is fine here and below since we are calling this after erasure.
// However, there is some weird stuff going on with parboiled2 where an
// AppliedType with a type alias as constructor is fed to outerPrefix.
// For some other unknown reason this works with underlying but not with superType.
// I was not able to minimize the problem and parboiled2 spits out way too much
// macro generated code to be able to pinpoint the root problem.
}
private def outerPrefix(tpe: Type)(using Context): Type = tpe match
case tpe: TypeRef if tpe.symbol.isClass =>
if tpe.prefix eq NoPrefix then tpe.symbol.owner.enclosingClass.thisType
else tpe.prefix
case tpe: TypeProxy =>
outerPrefix(tpe.underlying)
}
atPhaseNoLater(erasurePhase)(outerPrefix(tpe.superType))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

superType will reduce AppliedTypes but not match types, so I think we could still trigger the issue.


/** It's possible (i1755.scala gives an example) that the type
* given by outerPrefix contains a This-reference to a module outside
Expand Down
12 changes: 12 additions & 0 deletions tests/pos/i20184.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
object Outer:
def Test =
object Inner:
var x: Int = 2
class Rgb():
def f = x

type Id[X] = X
type TRgb = Id[Inner.Rgb]

val ok = new Inner.Rgb()
val crash = new Id[Inner.Rgb]
Loading