Skip to content

Commit 5120282

Browse files
committed
Handle ownership changes in InlineTyper
Fixes a part of #13334 which now works for `transparent inline`.
1 parent 1b70511 commit 5120282

File tree

3 files changed

+51
-17
lines changed

3 files changed

+51
-17
lines changed

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

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ class YCheckPositions extends Phase {
2222
override def checkPostCondition(tree: Tree)(using Context): Unit =
2323
tree match {
2424
case PackageDef(pid, _) if tree.symbol.owner == defn.RootClass =>
25-
new TreeTraverser {
25+
val checker = new TreeTraverser {
2626
private var sources: List[SourceFile] = ctx.source :: Nil
2727
def traverse(tree: tpd.Tree)(using Context): Unit = {
2828

@@ -36,23 +36,26 @@ class YCheckPositions extends Phase {
3636
assert(tree.source == currentSource, i"wrong source set for $tree # ${tree.uniqueId} of ${tree.getClass}, set to ${tree.source} but context had $currentSource\n ${tree.symbol.flagsString}")
3737

3838
// Recursivlely check children while keeping track of current source
39-
tree match {
40-
case Inlined(EmptyTree, bindings, expansion) =>
41-
assert(bindings.isEmpty)
42-
val old = sources
43-
sources = old.tail
44-
traverse(expansion)(using inlineContext(EmptyTree).withSource(sources.head))
45-
sources = old
46-
case Inlined(call, bindings, expansion) =>
47-
// bindings.foreach(traverse(_)) // TODO check inline proxies (see tests/tun/lst)
48-
sources = call.symbol.topLevelClass.source :: sources
49-
if (!isMacro(call)) // FIXME macro implementations can drop Inlined nodes. We should reinsert them after macro expansion based on the positions of the trees
50-
traverse(expansion)(using inlineContext(call).withSource(sources.head))
51-
sources = sources.tail
52-
case _ => traverseChildren(tree)
39+
reporting.trace(i"check pos ${tree.getClass} ${tree.source} ${sources.head} $tree") {
40+
tree match {
41+
case Inlined(EmptyTree, bindings, expansion) =>
42+
assert(bindings.isEmpty)
43+
val old = sources
44+
sources = old.tail
45+
traverse(expansion)(using inlineContext(EmptyTree).withSource(sources.head))
46+
sources = old
47+
case Inlined(call, bindings, expansion) =>
48+
// bindings.foreach(traverse(_)) // TODO check inline proxies (see tests/tun/lst)
49+
sources = call.symbol.topLevelClass.source :: sources
50+
if (!isMacro(call)) // FIXME macro implementations can drop Inlined nodes. We should reinsert them after macro expansion based on the positions of the trees
51+
traverse(expansion)(using inlineContext(call).withSource(sources.head))
52+
sources = sources.tail
53+
case _ => traverseChildren(tree)
54+
}
5355
}
5456
}
55-
}.traverse(tree)
57+
}
58+
checker.traverse(tree)
5659
case _ =>
5760
}
5861

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

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1540,7 +1540,15 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(using Context) {
15401540
ctx
15411541

15421542
override def typedIdent(tree: untpd.Ident, pt: Type)(using Context): Tree =
1543-
inlineIfNeeded(tryInlineArg(tree.asInstanceOf[tpd.Tree]) `orElse` super.typedIdent(tree, pt))
1543+
val tree1 = inlineIfNeeded(
1544+
tryInlineArg(tree.asInstanceOf[tpd.Tree]) `orElse` super.typedIdent(tree, pt)
1545+
)
1546+
tree1 match
1547+
case id: Ident if tpd.needsSelect(id.tpe) =>
1548+
inlining.println(i"expanding $id to selection")
1549+
ref(id.tpe.asInstanceOf[TermRef]).withSpan(id.span)
1550+
case _ =>
1551+
tree1
15441552

15451553
override def typedSelect(tree: untpd.Select, pt: Type)(using Context): Tree = {
15461554
val qual1 = typed(tree.qualifier, shallowSelectionProto(tree.name, pt, this))

tests/pos/i13334.scala

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
class Bar
2+
3+
transparent inline def bar(i: Int): Bar =
4+
new Bar:
5+
def j = i
6+
7+
class Foo(x: Int):
8+
def foo = bar(x)
9+
10+
trait DFC
11+
given DFC = new DFC {}
12+
13+
trait TC
14+
object TC:
15+
def foo()(using DFC): Unit = {}
16+
17+
transparent inline given (using DFC): TC = new TC:
18+
foo()
19+
20+
class Baz(using DFC):
21+
summon[TC]
22+
23+
val top = new Baz

0 commit comments

Comments
 (0)