@@ -612,7 +612,7 @@ object Erasure {
612
612
val restpe =
613
613
if (sym.isConstructor) defn.UnitType
614
614
else sym.info.resultType
615
- var vparamss1 = (outer.paramDefs (sym) ::: ddef.vparamss.flatten) :: Nil
615
+ var vparamss1 = (outerParamDefs (sym) ::: ddef.vparamss.flatten) :: Nil
616
616
var rhs1 = ddef.rhs
617
617
if (sym.isAnonymousFunction && vparamss1.head.length > MaxImplementedFunctionArity ) {
618
618
val bunchedParam = ctx.newSymbol(sym, nme.ALLARGS , Flags .TermParam , JavaArrayType (defn.ObjectType ))
@@ -635,6 +635,28 @@ object Erasure {
635
635
super .typedDefDef(ddef1, sym)
636
636
}
637
637
638
+ /** The outer parameter definition of a constructor if it needs one */
639
+ private def outerParamDefs (constr : Symbol )(using ctx : Context ): List [ValDef ] =
640
+ if constr.isConstructor && hasOuterParam(constr.owner.asClass) then
641
+ constr.info match
642
+ case MethodTpe (outerName :: _, outerType :: _, _) =>
643
+ val outerSym = ctx.newSymbol(constr, outerName, Flags .Param , outerType)
644
+ ValDef (outerSym) :: Nil
645
+ case _ =>
646
+ // There's a possible race condition that a constructor was looked at
647
+ // after erasure before we had a chance to run ExplicitOuter on its class
648
+ // If furthermore the enclosing class does not always have constructors,
649
+ // but needs constructors in this particular case, we miss the constructor
650
+ // accessor that's produced with an `enteredAfter` in ExplicitOuter, so
651
+ // `tranformInfo` of the constructor in erasure yields a method type without
652
+ // an outer parameter. We fix this problem by adding the missing outer
653
+ // parameter here.
654
+ constr.copySymDenotation(
655
+ info = outer.addParam(constr.owner.asClass, constr.info)
656
+ ).installAfter(erasurePhase)
657
+ outerParamDefs(constr)
658
+ else Nil
659
+
638
660
override def typedClosure (tree : untpd.Closure , pt : Type )(implicit ctx : Context ): Tree = {
639
661
val xxl = defn.isXXLFunctionClass(tree.typeOpt.typeSymbol)
640
662
var implClosure @ Closure (_, meth, _) = super .typedClosure(tree, pt)
0 commit comments