Skip to content

Commit 7967eac

Browse files
authored
Merge pull request #11411 from dotty-staging/fix-11367
Don't generate outer accessors for classes transitively nested in terms
2 parents 7a1c1c9 + 1c302e6 commit 7967eac

File tree

3 files changed

+23
-2
lines changed

3 files changed

+23
-2
lines changed

compiler/src/dotty/tools/dotc/transform/ExplicitOuter.scala

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -217,11 +217,13 @@ object ExplicitOuter {
217217
cls.info.parents.exists(parent => // needs outer to potentially pass along to parent
218218
needsOuterIfReferenced(parent.classSymbol.asClass)))
219219

220-
/** Class is always instantiated in the compilation unit where it is defined */
220+
/** Class is only instantiated in the compilation unit where it is defined */
221221
private def hasLocalInstantiation(cls: ClassSymbol)(using Context): Boolean =
222222
// Modules are normally locally instantiated, except if they are declared in a trait,
223223
// in which case they will be instantiated in the classes that mix in the trait.
224-
cls.owner.isTerm || cls.is(Private, butNot = Module) || (cls.is(Module) && !cls.owner.is(Trait))
224+
cls.owner.ownersIterator.takeWhile(!_.isStatic).exists(_.isTerm)
225+
|| cls.is(Private, butNot = Module)
226+
|| cls.is(Module) && !cls.owner.is(Trait)
225227

226228
/** The outer parameter accessor of cass `cls` */
227229
private def outerParamAccessor(cls: ClassSymbol)(using Context): TermSymbol =

tests/run/i11367.check

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
class C$G has outer fields

tests/run/i11367.scala

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
trait NoOuter:
2+
val outerFields = getClass.getDeclaredFields.filter(_.getName.contains("$outer"))
3+
if outerFields.nonEmpty then println(s"$getClass has outer fields")
4+
5+
class C extends NoOuter:
6+
def foo =
7+
class D extends NoOuter:
8+
class E extends NoOuter
9+
class F extends NoOuter
10+
val d = D()
11+
d.E()
12+
F()
13+
class G extends NoOuter
14+
15+
@main def Test =
16+
val c = C()
17+
c.foo
18+
c.G()

0 commit comments

Comments
 (0)