From 326d00f6f9d985ca6c50a1b6bdf5cb2d6e01d4a7 Mon Sep 17 00:00:00 2001 From: changvvb Date: Sun, 24 Jan 2021 01:27:17 +0800 Subject: [PATCH 1/2] Add outer param when java inner class instantiated Update hasOuterParam -> needsOuterParam fix try to fix test --- .../src/dotty/tools/dotc/transform/Erasure.scala | 2 +- .../dotty/tools/dotc/transform/ExplicitOuter.scala | 12 ++++++------ tests/run/10838/A.java | 3 +++ tests/run/10838/Test.scala | 6 ++++++ 4 files changed, 16 insertions(+), 7 deletions(-) create mode 100644 tests/run/10838/A.java create mode 100644 tests/run/10838/Test.scala diff --git a/compiler/src/dotty/tools/dotc/transform/Erasure.scala b/compiler/src/dotty/tools/dotc/transform/Erasure.scala index 0d80ef87056f..27c39a79cf14 100644 --- a/compiler/src/dotty/tools/dotc/transform/Erasure.scala +++ b/compiler/src/dotty/tools/dotc/transform/Erasure.scala @@ -931,7 +931,7 @@ object Erasure { /** The outer parameter definition of a constructor if it needs one */ private def outerParamDefs(constr: Symbol)(using Context): List[ValDef] = - if constr.isConstructor && hasOuterParam(constr.owner.asClass) then + if constr.isConstructor && needsOuterParam(constr.owner.asClass) then constr.info match case MethodTpe(outerName :: _, outerType :: _, _) => val outerSym = newSymbol(constr, outerName, Flags.Param, outerType) diff --git a/compiler/src/dotty/tools/dotc/transform/ExplicitOuter.scala b/compiler/src/dotty/tools/dotc/transform/ExplicitOuter.scala index d64c94f6bc98..2b68b7249565 100644 --- a/compiler/src/dotty/tools/dotc/transform/ExplicitOuter.scala +++ b/compiler/src/dotty/tools/dotc/transform/ExplicitOuter.scala @@ -245,9 +245,9 @@ object ExplicitOuter { private def hasOuter(cls: ClassSymbol)(using Context): Boolean = needsOuterIfReferenced(cls) && outerAccessor(cls).exists - /** Class constructor takes an outer argument. Can be called only after phase ExplicitOuter. */ - def hasOuterParam(cls: ClassSymbol)(using Context): Boolean = - !cls.is(Trait) && needsOuterIfReferenced(cls) && outerAccessor(cls).exists + /** Class constructor needs an outer argument. Can be called only after phase ExplicitOuter. */ + def needsOuterParam(cls: ClassSymbol)(using Context): Boolean = + !cls.is(Trait) && needsOuterIfReferenced(cls) && (cls.is(JavaDefined) || outerAccessor(cls).exists) /** Tree references an outer class of `cls` which is not a static owner. */ @@ -357,7 +357,7 @@ object ExplicitOuter { /** If `cls` has an outer parameter add one to the method type `tp`. */ def addParam(cls: ClassSymbol, tp: Type): Type = - if (hasOuterParam(cls)) { + if (needsOuterParam(cls)) { val mt @ MethodTpe(pnames, ptypes, restpe) = tp mt.derivedLambdaType( nme.OUTER :: pnames, outerClass(cls).typeRef :: ptypes, restpe) @@ -378,7 +378,7 @@ object ExplicitOuter { case TypeApply(Select(r, nme.asInstanceOf_), args) => outerArg(r) // cast was inserted, skip } - if (hasOuterParam(cls)) + if (needsOuterParam(cls)) methPart(fun) match { case Select(receiver, _) => outerArg(receiver).withSpan(fun.span) :: Nil } @@ -390,7 +390,7 @@ object ExplicitOuter { * argument, the singleton list with the argument, otherwise Nil. */ def argsForNew(cls: ClassSymbol, tpe: Type): List[Tree] = - if (hasOuterParam(cls)) singleton(fixThis(outerPrefix(tpe))) :: Nil + if (needsOuterParam(cls)) singleton(fixThis(outerPrefix(tpe))) :: Nil else Nil /** A path of outer accessors starting from node `start`. `start` defaults to the diff --git a/tests/run/10838/A.java b/tests/run/10838/A.java new file mode 100644 index 000000000000..126809cadba6 --- /dev/null +++ b/tests/run/10838/A.java @@ -0,0 +1,3 @@ +public class A { + public class B {} +} diff --git a/tests/run/10838/Test.scala b/tests/run/10838/Test.scala new file mode 100644 index 000000000000..ebcf8298faf2 --- /dev/null +++ b/tests/run/10838/Test.scala @@ -0,0 +1,6 @@ +object Test { + def main(args: Array[String]): Unit = { + val a = new A + new a.B + } +} From d8669d956c60d2ecf7dd2361845f54c8f6abfced Mon Sep 17 00:00:00 2001 From: changvvb Date: Mon, 25 Jan 2021 10:15:57 +0800 Subject: [PATCH 2/2] Add comment --- compiler/src/dotty/tools/dotc/transform/ExplicitOuter.scala | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/compiler/src/dotty/tools/dotc/transform/ExplicitOuter.scala b/compiler/src/dotty/tools/dotc/transform/ExplicitOuter.scala index 2b68b7249565..91edf0feea79 100644 --- a/compiler/src/dotty/tools/dotc/transform/ExplicitOuter.scala +++ b/compiler/src/dotty/tools/dotc/transform/ExplicitOuter.scala @@ -247,7 +247,9 @@ object ExplicitOuter { /** Class constructor needs an outer argument. Can be called only after phase ExplicitOuter. */ def needsOuterParam(cls: ClassSymbol)(using Context): Boolean = - !cls.is(Trait) && needsOuterIfReferenced(cls) && (cls.is(JavaDefined) || outerAccessor(cls).exists) + !cls.is(Trait) && needsOuterIfReferenced(cls) && ( + cls.is(JavaDefined) || // java inner class doesn't has outer accessor + outerAccessor(cls).exists) /** Tree references an outer class of `cls` which is not a static owner. */