Skip to content

Commit 9f75e15

Browse files
gspssmarter
authored andcommitted
Fix #4342: When calling a Scala 2.x method with an outer parameter, adapt to the old behavior in picking the outer parameter's type, i.e., prefer the enclosing class's self type, rather than the enclosing class itself.
1 parent 3c62b96 commit 9f75e15

File tree

1 file changed

+16
-2
lines changed

1 file changed

+16
-2
lines changed

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

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,20 @@ object ExplicitOuter {
140140
private def newOuterAccessors(cls: ClassSymbol)(implicit ctx: Context) =
141141
newOuterAccessor(cls, cls) :: (if (cls is Trait) Nil else newOuterParamAccessor(cls) :: Nil)
142142

143+
/** Scala 2.x and Dotty don't always agree on what should be the type of the outer parameter,
144+
* so we replicate the old behavior when passing arguments to methods coming from Scala 2.x.
145+
*/
146+
private def outerClass(cls: ClassSymbol)(implicit ctx: Context): Symbol = {
147+
val encl = cls.owner.enclosingClass
148+
if (cls.is(Scala2x))
149+
encl.asClass.classInfo.selfInfo match {
150+
case tp: TypeRef => tp.classSymbol
151+
case self: Symbol => self
152+
case _ => encl
153+
}
154+
else encl
155+
}
156+
143157
/** A new outer accessor or param accessor.
144158
* @param owner The class where the outer accessor is located
145159
* @param cls The class relative to which the outer is computed (can be a base class of owner)
@@ -155,7 +169,7 @@ object ExplicitOuter {
155169
*/
156170
private def newOuterSym(owner: ClassSymbol, cls: ClassSymbol, name: TermName, flags: FlagSet)(implicit ctx: Context) = {
157171
val outerThis = owner.owner.enclosingClass.thisType
158-
val outerCls = cls.owner.enclosingClass
172+
val outerCls = outerClass(cls)
159173
val target =
160174
if (owner == cls)
161175
outerCls.appliedRef
@@ -340,7 +354,7 @@ object ExplicitOuter {
340354
if (hasOuterParam(cls)) {
341355
val mt @ MethodTpe(pnames, ptypes, restpe) = tp
342356
mt.derivedLambdaType(
343-
nme.OUTER :: pnames, cls.owner.enclosingClass.typeRef :: ptypes, restpe)
357+
nme.OUTER :: pnames, outerClass(cls).typeRef :: ptypes, restpe)
344358
} else tp
345359

346360
/** If function in an apply node is a constructor that needs to be passed an

0 commit comments

Comments
 (0)