Skip to content

Commit 323dbce

Browse files
committed
Fix inlining when outer select is needed from inline call prefix
1 parent 77bcd0d commit 323dbce

File tree

4 files changed

+29
-4
lines changed

4 files changed

+29
-4
lines changed

compiler/src/dotty/tools/dotc/core/TypeOps.scala

+3
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,9 @@ object TypeOps:
6060

6161
/** Map a `C.this` type to the right prefix. If the prefix is unstable, and
6262
* the current variance is <= 0, return a range.
63+
* @param pre The prefix
64+
* @param cls The class in which the `C.this` type occurs
65+
* @param thiscls The prefix `C` of the `C.this` type.
6366
*/
6467
def toPrefix(pre: Type, cls: Symbol, thiscls: ClassSymbol): Type = /*>|>*/ trace.conditionally(track, s"toPrefix($pre, $cls, $thiscls)", show = true) /*<|<*/ {
6568
if ((pre eq NoType) || (pre eq NoPrefix) || (cls is PackageClass))

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

+4-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,10 @@ class ExplicitSelf extends MiniPhase {
2727
override def description: String = ExplicitSelf.description
2828

2929
private def needsCast(tree: RefTree, cls: ClassSymbol)(using Context) =
30-
!cls.is(Package) && cls.givenSelfType.exists && !cls.derivesFrom(tree.symbol.owner)
30+
!cls.is(Package)
31+
&& cls.givenSelfType.exists
32+
&& tree.symbol.exists
33+
&& !cls.derivesFrom(tree.symbol.owner)
3134

3235
private def castQualifier(tree: RefTree, cls: ClassSymbol, thiz: Tree)(using Context) =
3336
val selfType = cls.classInfo.selfType

compiler/src/dotty/tools/dotc/typer/Inliner.scala

+7-3
Original file line numberDiff line numberDiff line change
@@ -573,9 +573,13 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(using Context) {
573573
else if lastSelf.exists then
574574
ref(lastSelf).outerSelect(lastLevel - level, selfSym.info)
575575
else
576-
inlineCallPrefix match
577-
case Super(_, _) => This(rhsClsSym.asClass)
578-
case _ => inlineCallPrefix
576+
val pre = inlineCallPrefix match
577+
case Super(qual, _) => qual
578+
case pre => pre
579+
val preLevel = inlinedMethod.owner.ownersIterator.length
580+
if preLevel > level then pre.outerSelect(preLevel - level, selfSym.info)
581+
else pre
582+
579583
val binding = accountForOpaques(
580584
ValDef(selfSym.asTerm, QuoteUtils.changeOwnerOfTree(rhs, selfSym)).withSpan(selfSym.span))
581585
bindingsBuf += binding

tests/run/i15317.scala

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
class Outer {
2+
val outer = 1
3+
object Inner {
4+
def forwarder: Int = inlined
5+
transparent inline def inlined: Int = outer
6+
}
7+
object Inner2 {
8+
def forwarder: Int = inlined
9+
inline def inlined: Int = outer
10+
}
11+
}
12+
13+
@main def Test =
14+
assert((new Outer).Inner.forwarder == 1)
15+
assert((new Outer).Inner2.forwarder == 1)

0 commit comments

Comments
 (0)