Skip to content

Commit dfdd31a

Browse files
Merge pull request #14568 from dotty-staging/fix-13334
Handle ownership changes in InlineTyper
2 parents a05ff76 + 5120282 commit dfdd31a

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
@@ -1542,7 +1542,15 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(using Context) {
15421542
ctx
15431543

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

15471555
override def typedSelect(tree: untpd.Select, pt: Type)(using Context): Tree = {
15481556
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)