Skip to content

Commit 8395ec0

Browse files
Implement grandparent inline traits, fix parameters shadowing
Allow an inline trait to extend another inline trait, and prevent code from being inlined inside the child inline trait: only inline in first non-inline class-like element When parameters shadow each other (e.g. val x and private[this] val x), rename the instance-private ones to avoid clash If multiple non-instance-private fields are present, the compiler should still raise the same error as with normal traits
1 parent 6a08c89 commit 8395ec0

File tree

4 files changed

+60
-2
lines changed

4 files changed

+60
-2
lines changed

compiler/src/dotty/tools/dotc/inlines/Inlines.scala

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import staging.StagingLevel
2020
import collection.mutable
2121
import reporting.trace
2222
import util.Spans.{Span, spanCoord}
23+
import NameOps.expandedName
2324

2425
/** Support for querying inlineable methods and for inlining calls to such methods */
2526
object Inlines:
@@ -486,7 +487,17 @@ object Inlines:
486487
}
487488
}
488489

490+
protected class InlineTraitTreeMap extends InlinerTreeMap {
491+
override def apply(tree: Tree) = tree match {
492+
case tree @ Select(This(ident), name) if ident.name == parentSym.name && localParamAccessorsNames.contains(name) =>
493+
Select(This(ctx.owner.asClass), localParamAccessorsNames(name)).withSpan(parent.span)
494+
case tree =>
495+
super.apply(tree)
496+
}
497+
}
498+
489499
override protected val inlinerTypeMap: InlinerTypeMap = InlineTraitTypeMap()
500+
override protected val inlinerTreeMap: InlinerTreeMap = InlineTraitTreeMap()
490501

491502
private val paramAccessorsValueOf: Map[Name, Tree] =
492503
def allArgs(tree: Tree, acc: Vector[List[Tree]]): List[List[Tree]] = tree match
@@ -502,6 +513,8 @@ object Inlines:
502513
else parent.symbol.info
503514
allParams(info, Nil).flatten.zip(allArgs(parent, Vector.empty).flatten).toMap
504515

516+
private val localParamAccessorsNames = new mutable.HashMap[Name, Name]
517+
505518
private def isStatAlreadyOverridden(stat: Tree): Boolean =
506519
overriddenDecls.contains(stat.symbol)
507520

@@ -524,11 +537,17 @@ object Inlines:
524537
val inlinedInfo = ClassInfo(prefix, cls, declaredParents, Scopes.newScope, selfInfo) // TODO adapt parents
525538
sym.copy(owner = ctx.owner, info = inlinedInfo, coord = spanCoord(parent.span)).entered.asClass
526539
case _ =>
540+
var name = sym.name
527541
var flags = sym.flags | Synthetic
528542
if sym.isType || !sym.is(Private) then flags |= Override
529-
if sym.isTermParamAccessor then flags &~= ParamAccessor
543+
if sym.isTermParamAccessor then
544+
flags &~= ParamAccessor
545+
if sym.is(Local) then
546+
name = name.expandedName(parentSym)
547+
localParamAccessorsNames(sym.name) = name
530548
sym.copy(
531549
owner = ctx.owner,
550+
name = name,
532551
flags = flags,
533552
info = inlinerTypeMap(sym.info),
534553
coord = spanCoord(parent.span)).entered

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2658,7 +2658,7 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
26582658
else {
26592659
val dummy = localDummy(cls, impl)
26602660
val inlineTraitDefs =
2661-
if ctx.isAfterTyper then
2661+
if ctx.isAfterTyper || cls.isInlineTrait then
26622662
Nil
26632663
else
26642664
val overriddenSyms = cls.info.decls.toList.flatMap(_.allOverriddenSymbols).toSet
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
0
2+
(Test SimpleC,Hello)
3+
4+
5678
5+
(Test C,Hello,9)
6+
5678
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package simpleGrandParent:
2+
inline trait SimpleGrandParent[T]:
3+
def foo(): Int = 0
4+
def foooo(): T = ???
5+
6+
inline trait SimpleParent[T, U](x: T, z: U) extends SimpleGrandParent[U]:
7+
def bar(a: T) = (a, x)
8+
9+
class SimpleC extends SimpleParent("Hello", 1234)
10+
11+
package grandParentWithArgs:
12+
inline trait GrandParent[T](val x: T, val y: T):
13+
def foo(): T = x
14+
def foooo(): T = y
15+
16+
inline trait Parent[T, U](x: T, z: U) extends GrandParent[U]:
17+
def bar(a: T) = (a, x, y)
18+
19+
class C extends Parent("Hello", 1234), GrandParent(5678, 9)
20+
21+
@main def Test =
22+
import simpleGrandParent.SimpleC
23+
import grandParentWithArgs.C
24+
25+
val simpleC = SimpleC()
26+
println(simpleC.foo())
27+
println(simpleC.bar("Test SimpleC"))
28+
println
29+
30+
val c = C()
31+
println(c.foo())
32+
println(c.bar("Test C"))
33+
println(c.x)

0 commit comments

Comments
 (0)