Skip to content

Commit 35bb073

Browse files
authored
Add outer param when java inner class instantiated (#11198)
* Add outer param when java inner class instantiated Update hasOuterParam -> needsOuterParam fix try to fix test * Add comment
1 parent f6112f5 commit 35bb073

File tree

4 files changed

+18
-7
lines changed

4 files changed

+18
-7
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -931,7 +931,7 @@ object Erasure {
931931

932932
/** The outer parameter definition of a constructor if it needs one */
933933
private def outerParamDefs(constr: Symbol)(using Context): List[ValDef] =
934-
if constr.isConstructor && hasOuterParam(constr.owner.asClass) then
934+
if constr.isConstructor && needsOuterParam(constr.owner.asClass) then
935935
constr.info match
936936
case MethodTpe(outerName :: _, outerType :: _, _) =>
937937
val outerSym = newSymbol(constr, outerName, Flags.Param, outerType)

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

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -245,9 +245,11 @@ object ExplicitOuter {
245245
private def hasOuter(cls: ClassSymbol)(using Context): Boolean =
246246
needsOuterIfReferenced(cls) && outerAccessor(cls).exists
247247

248-
/** Class constructor takes an outer argument. Can be called only after phase ExplicitOuter. */
249-
def hasOuterParam(cls: ClassSymbol)(using Context): Boolean =
250-
!cls.is(Trait) && needsOuterIfReferenced(cls) && outerAccessor(cls).exists
248+
/** Class constructor needs an outer argument. Can be called only after phase ExplicitOuter. */
249+
def needsOuterParam(cls: ClassSymbol)(using Context): Boolean =
250+
!cls.is(Trait) && needsOuterIfReferenced(cls) && (
251+
cls.is(JavaDefined) || // java inner class doesn't has outer accessor
252+
outerAccessor(cls).exists)
251253

252254
/** Tree references an outer class of `cls` which is not a static owner.
253255
*/
@@ -357,7 +359,7 @@ object ExplicitOuter {
357359

358360
/** If `cls` has an outer parameter add one to the method type `tp`. */
359361
def addParam(cls: ClassSymbol, tp: Type): Type =
360-
if (hasOuterParam(cls)) {
362+
if (needsOuterParam(cls)) {
361363
val mt @ MethodTpe(pnames, ptypes, restpe) = tp
362364
mt.derivedLambdaType(
363365
nme.OUTER :: pnames, outerClass(cls).typeRef :: ptypes, restpe)
@@ -378,7 +380,7 @@ object ExplicitOuter {
378380
case TypeApply(Select(r, nme.asInstanceOf_), args) =>
379381
outerArg(r) // cast was inserted, skip
380382
}
381-
if (hasOuterParam(cls))
383+
if (needsOuterParam(cls))
382384
methPart(fun) match {
383385
case Select(receiver, _) => outerArg(receiver).withSpan(fun.span) :: Nil
384386
}
@@ -390,7 +392,7 @@ object ExplicitOuter {
390392
* argument, the singleton list with the argument, otherwise Nil.
391393
*/
392394
def argsForNew(cls: ClassSymbol, tpe: Type): List[Tree] =
393-
if (hasOuterParam(cls)) singleton(fixThis(outerPrefix(tpe))) :: Nil
395+
if (needsOuterParam(cls)) singleton(fixThis(outerPrefix(tpe))) :: Nil
394396
else Nil
395397

396398
/** A path of outer accessors starting from node `start`. `start` defaults to the

tests/run/10838/A.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
public class A {
2+
public class B {}
3+
}

tests/run/10838/Test.scala

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
object Test {
2+
def main(args: Array[String]): Unit = {
3+
val a = new A
4+
new a.B
5+
}
6+
}

0 commit comments

Comments
 (0)