Skip to content

Commit ddbcf61

Browse files
Merge pull request #15327 from dotty-staging/fix-15317
Fix inlining when outer select is needed from inline call prefix
2 parents 8d13cbb + 323dbce commit ddbcf61

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
@@ -637,9 +637,13 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(using Context) {
637637
else if lastSelf.exists then
638638
ref(lastSelf).outerSelect(lastLevel - level, selfSym.info)
639639
else
640-
inlineCallPrefix match
641-
case Super(_, _) => This(rhsClsSym.asClass)
642-
case _ => inlineCallPrefix
640+
val pre = inlineCallPrefix match
641+
case Super(qual, _) => qual
642+
case pre => pre
643+
val preLevel = inlinedMethod.owner.ownersIterator.length
644+
if preLevel > level then pre.outerSelect(preLevel - level, selfSym.info)
645+
else pre
646+
643647
val binding = accountForOpaques(
644648
ValDef(selfSym.asTerm, QuoteUtils.changeOwnerOfTree(rhs, selfSym)).withSpan(selfSym.span))
645649
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)