From d9f070dad733f0de450ae55c991e603b4db80549 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Thu, 9 Dec 2021 17:45:31 +0100 Subject: [PATCH 1/3] Make outer references Java-synthetic Fixes #14083 I verified manually that the puter accessors are now ACC_SYNHETIC. If someone wants to add a bytecode test, this would be good. I don't know how to make one. --- compiler/src/dotty/tools/dotc/transform/ExplicitOuter.scala | 2 +- tests/pos/i14083.scala | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) create mode 100644 tests/pos/i14083.scala diff --git a/compiler/src/dotty/tools/dotc/transform/ExplicitOuter.scala b/compiler/src/dotty/tools/dotc/transform/ExplicitOuter.scala index a6a6b2736b1b..9c50e3c2f114 100644 --- a/compiler/src/dotty/tools/dotc/transform/ExplicitOuter.scala +++ b/compiler/src/dotty/tools/dotc/transform/ExplicitOuter.scala @@ -177,7 +177,7 @@ object ExplicitOuter { else prefix.widen) val info = if (flags.is(Method)) ExprType(target) else target atPhaseNoEarlier(explicitOuterPhase.next) { // outer accessors are entered at explicitOuter + 1, should not be defined before. - newSymbol(owner, name, Synthetic | flags, info, coord = cls.coord) + newSymbol(owner, name, SyntheticArtifact | flags, info, coord = cls.coord) } } diff --git a/tests/pos/i14083.scala b/tests/pos/i14083.scala new file mode 100644 index 000000000000..542640e96bf1 --- /dev/null +++ b/tests/pos/i14083.scala @@ -0,0 +1,3 @@ +class Outer { + class Inner +} \ No newline at end of file From 185f09e15be9760c013b353571305d2ad9a36e9a Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Thu, 9 Dec 2021 18:13:04 +0100 Subject: [PATCH 2/3] Make it a proper test --- tests/pos/i14083.scala | 3 --- tests/run/i14083.scala | 9 +++++++++ 2 files changed, 9 insertions(+), 3 deletions(-) delete mode 100644 tests/pos/i14083.scala create mode 100644 tests/run/i14083.scala diff --git a/tests/pos/i14083.scala b/tests/pos/i14083.scala deleted file mode 100644 index 542640e96bf1..000000000000 --- a/tests/pos/i14083.scala +++ /dev/null @@ -1,3 +0,0 @@ -class Outer { - class Inner -} \ No newline at end of file diff --git a/tests/run/i14083.scala b/tests/run/i14083.scala new file mode 100644 index 000000000000..7c4d7f4da4dc --- /dev/null +++ b/tests/run/i14083.scala @@ -0,0 +1,9 @@ +class Outer { + class Inner +} +@main def Test = + assert( + classOf[Outer#Inner] + .getDeclaredFields + .filter(_.getName == "$outer") + .exists(_.isSynthetic)) From da5b3d89cc081c7ff2baed4fe5b29112a12b8947 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Thu, 9 Dec 2021 18:23:59 +0100 Subject: [PATCH 3/3] Make constructor parameter $outer also Java synthetic This does not work yet, since the backend does not issue a ACC_SYNTHETIC for parameters labeled Artifact. --- compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala | 1 + compiler/src/dotty/tools/dotc/transform/Erasure.scala | 2 +- tests/run/i14083.scala | 4 ++++ 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala b/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala index 03d5ac13665b..4085d87ad7ca 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala @@ -343,6 +343,7 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { def emitParamNames(jmethod: asm.MethodVisitor, params: List[Symbol]) = for param <- params do var access = asm.Opcodes.ACC_FINAL + if param.is(Artifact) then access |= asm.Opcodes.ACC_SYNTHETIC jmethod.visitParameter(param.name.mangledString, access) /* diff --git a/compiler/src/dotty/tools/dotc/transform/Erasure.scala b/compiler/src/dotty/tools/dotc/transform/Erasure.scala index ab6f00dfc575..7a89a819677f 100644 --- a/compiler/src/dotty/tools/dotc/transform/Erasure.scala +++ b/compiler/src/dotty/tools/dotc/transform/Erasure.scala @@ -929,7 +929,7 @@ object Erasure { if constr.isConstructor && needsOuterParam(constr.owner.asClass) then constr.info match case MethodTpe(outerName :: _, outerType :: _, _) => - val outerSym = newSymbol(constr, outerName, Flags.Param, outerType) + val outerSym = newSymbol(constr, outerName, Flags.Param | Flags.SyntheticArtifact, outerType) ValDef(outerSym) :: Nil case _ => // There's a possible race condition that a constructor was looked at diff --git a/tests/run/i14083.scala b/tests/run/i14083.scala index 7c4d7f4da4dc..4014e474ad45 100644 --- a/tests/run/i14083.scala +++ b/tests/run/i14083.scala @@ -2,6 +2,10 @@ class Outer { class Inner } @main def Test = + assert(classOf[Outer#Inner] + .getConstructors.head + .getParameters.head + .isSynthetic) assert( classOf[Outer#Inner] .getDeclaredFields