Skip to content

Commit 951b53e

Browse files
authored
Merge pull request #2912 from dotty-staging/fix-#2895
Fix #2895: Two fixes for inlining
2 parents 9233de3 + 81e2d38 commit 951b53e

File tree

4 files changed

+49
-5
lines changed

4 files changed

+49
-5
lines changed

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

+1-2
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@ class Bridges(root: ClassSymbol)(implicit ctx: Context) {
3939
* before erasure, if the following conditions are satisfied.
4040
*
4141
* - `member` and other have different signatures
42-
* - `member` is not inline
4342
* - there is not yet a bridge with the same name and signature in `root`
4443
*
4544
* The bridge has the erased info of `other` and forwards to `member`.
@@ -48,7 +47,7 @@ class Bridges(root: ClassSymbol)(implicit ctx: Context) {
4847
def bridgeExists =
4948
bridgesScope.lookupAll(member.name).exists(bridge =>
5049
bridgeTarget(bridge) == member && bridge.signature == other.signature)
51-
if (!(member.is(Inline) || member.signature == other.signature || bridgeExists))
50+
if (!(member.signature == other.signature || bridgeExists))
5251
addBridge(member, other)
5352
}
5453

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

+5-3
Original file line numberDiff line numberDiff line change
@@ -356,6 +356,10 @@ class Inliner(call: tpd.Tree, rhs: tpd.Tree)(implicit ctx: Context) {
356356
assert(argss.isEmpty)
357357
}
358358

359+
private def canElideThis(tpe: ThisType): Boolean =
360+
prefix.tpe == tpe && ctx.owner.isContainedIn(tpe.cls) ||
361+
tpe.cls.is(Package)
362+
359363
/** Populate `thisProxy` and `paramProxy` as follows:
360364
*
361365
* 1a. If given type refers to a static this, thisProxy binds it to corresponding global reference,
@@ -368,9 +372,7 @@ class Inliner(call: tpd.Tree, rhs: tpd.Tree)(implicit ctx: Context) {
368372
* and MethodParams, not TypeRefs or TermRefs.
369373
*/
370374
private def registerType(tpe: Type): Unit = tpe match {
371-
case tpe: ThisType
372-
if !ctx.owner.isContainedIn(tpe.cls) && !tpe.cls.is(Package) &&
373-
!thisProxy.contains(tpe.cls) =>
375+
case tpe: ThisType if !canElideThis(tpe) && !thisProxy.contains(tpe.cls) =>
374376
val proxyName = s"${tpe.cls.name}_this".toTermName
375377
val proxyType = tpe.asSeenFrom(prefix.tpe, meth.owner)
376378
thisProxy(tpe.cls) = newSym(proxyName, EmptyFlags, proxyType).termRef

tests/run/i2895.scala

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
object Foo extends (Int => Int) {
2+
inline def apply(x: Int): Int = impl(x)
3+
def impl(x: Int): Int = x + 1
4+
}
5+
6+
object Test {
7+
8+
def test(foo: Foo.type): Int = foo(41)
9+
10+
def test2(f: Int => Int): Int = f(41)
11+
12+
def main(args: Array[String]): Unit = {
13+
assert(test(Foo) == 42)
14+
assert(test2(Foo) == 42)
15+
}
16+
17+
}

tests/run/i2895a.scala

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
2+
trait Foo[A <: Foo[A]] {
3+
4+
def next: A
5+
6+
inline final def once: A = next
7+
8+
def once1: A = once
9+
10+
def twice: A = once.once
11+
}
12+
13+
trait Bar extends Foo[Bar]
14+
15+
case object Bar0 extends Bar { def next = Bar1 }
16+
case object Bar1 extends Bar { def next = Bar2 }
17+
case object Bar2 extends Bar { def next = this }
18+
19+
object Test {
20+
21+
def main(args: Array[String]): Unit = {
22+
assert(Bar0.once.once.toString == "Bar2")
23+
assert(Bar0.twice.toString == "Bar2")
24+
}
25+
}
26+

0 commit comments

Comments
 (0)