diff --git a/compiler/src/dotty/tools/dotc/core/TypeOps.scala b/compiler/src/dotty/tools/dotc/core/TypeOps.scala index 2cfdd08128ce..1dd061a0224b 100644 --- a/compiler/src/dotty/tools/dotc/core/TypeOps.scala +++ b/compiler/src/dotty/tools/dotc/core/TypeOps.scala @@ -60,6 +60,9 @@ object TypeOps: /** Map a `C.this` type to the right prefix. If the prefix is unstable, and * the current variance is <= 0, return a range. + * @param pre The prefix + * @param cls The class in which the `C.this` type occurs + * @param thiscls The prefix `C` of the `C.this` type. */ def toPrefix(pre: Type, cls: Symbol, thiscls: ClassSymbol): Type = /*>|>*/ trace.conditionally(track, s"toPrefix($pre, $cls, $thiscls)", show = true) /*<|<*/ { if ((pre eq NoType) || (pre eq NoPrefix) || (cls is PackageClass)) diff --git a/compiler/src/dotty/tools/dotc/transform/ExplicitSelf.scala b/compiler/src/dotty/tools/dotc/transform/ExplicitSelf.scala index 8d5b58dee944..a6f7a29accd7 100644 --- a/compiler/src/dotty/tools/dotc/transform/ExplicitSelf.scala +++ b/compiler/src/dotty/tools/dotc/transform/ExplicitSelf.scala @@ -27,7 +27,10 @@ class ExplicitSelf extends MiniPhase { override def description: String = ExplicitSelf.description private def needsCast(tree: RefTree, cls: ClassSymbol)(using Context) = - !cls.is(Package) && cls.givenSelfType.exists && !cls.derivesFrom(tree.symbol.owner) + !cls.is(Package) + && cls.givenSelfType.exists + && tree.symbol.exists + && !cls.derivesFrom(tree.symbol.owner) private def castQualifier(tree: RefTree, cls: ClassSymbol, thiz: Tree)(using Context) = val selfType = cls.classInfo.selfType diff --git a/compiler/src/dotty/tools/dotc/typer/Inliner.scala b/compiler/src/dotty/tools/dotc/typer/Inliner.scala index 88101a53f2b3..09e4ff2d718c 100644 --- a/compiler/src/dotty/tools/dotc/typer/Inliner.scala +++ b/compiler/src/dotty/tools/dotc/typer/Inliner.scala @@ -573,9 +573,13 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(using Context) { else if lastSelf.exists then ref(lastSelf).outerSelect(lastLevel - level, selfSym.info) else - inlineCallPrefix match - case Super(_, _) => This(rhsClsSym.asClass) - case _ => inlineCallPrefix + val pre = inlineCallPrefix match + case Super(qual, _) => qual + case pre => pre + val preLevel = inlinedMethod.owner.ownersIterator.length + if preLevel > level then pre.outerSelect(preLevel - level, selfSym.info) + else pre + val binding = accountForOpaques( ValDef(selfSym.asTerm, QuoteUtils.changeOwnerOfTree(rhs, selfSym)).withSpan(selfSym.span)) bindingsBuf += binding diff --git a/tests/run/i15317.scala b/tests/run/i15317.scala new file mode 100644 index 000000000000..d7ccb854da45 --- /dev/null +++ b/tests/run/i15317.scala @@ -0,0 +1,15 @@ +class Outer { + val outer = 1 + object Inner { + def forwarder: Int = inlined + transparent inline def inlined: Int = outer + } + object Inner2 { + def forwarder: Int = inlined + inline def inlined: Int = outer + } +} + +@main def Test = + assert((new Outer).Inner.forwarder == 1) + assert((new Outer).Inner2.forwarder == 1)