Skip to content

Commit 958929c

Browse files
committed
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 cfccb37 commit 958929c

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
@@ -141,6 +141,20 @@ object ExplicitOuter {
141141
private def newOuterAccessors(cls: ClassSymbol)(implicit ctx: Context) =
142142
newOuterAccessor(cls, cls) :: (if (cls is Trait) Nil else newOuterParamAccessor(cls) :: Nil)
143143

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

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

0 commit comments

Comments
 (0)