Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handle ownership changes in InlineTyper #14568

Merged
merged 1 commit into from
Mar 7, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 19 additions & 16 deletions compiler/src/dotty/tools/dotc/transform/YCheckPositions.scala
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class YCheckPositions extends Phase {
override def checkPostCondition(tree: Tree)(using Context): Unit =
tree match {
case PackageDef(pid, _) if tree.symbol.owner == defn.RootClass =>
new TreeTraverser {
val checker = new TreeTraverser {
private var sources: List[SourceFile] = ctx.source :: Nil
def traverse(tree: tpd.Tree)(using Context): Unit = {

Expand All @@ -36,23 +36,26 @@ class YCheckPositions extends Phase {
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}")

// Recursivlely check children while keeping track of current source
tree match {
case Inlined(EmptyTree, bindings, expansion) =>
assert(bindings.isEmpty)
val old = sources
sources = old.tail
traverse(expansion)(using inlineContext(EmptyTree).withSource(sources.head))
sources = old
case Inlined(call, bindings, expansion) =>
// bindings.foreach(traverse(_)) // TODO check inline proxies (see tests/tun/lst)
sources = call.symbol.topLevelClass.source :: sources
if (!isMacro(call)) // FIXME macro implementations can drop Inlined nodes. We should reinsert them after macro expansion based on the positions of the trees
traverse(expansion)(using inlineContext(call).withSource(sources.head))
sources = sources.tail
case _ => traverseChildren(tree)
reporting.trace(i"check pos ${tree.getClass} ${tree.source} ${sources.head} $tree") {
tree match {
case Inlined(EmptyTree, bindings, expansion) =>
assert(bindings.isEmpty)
val old = sources
sources = old.tail
traverse(expansion)(using inlineContext(EmptyTree).withSource(sources.head))
sources = old
case Inlined(call, bindings, expansion) =>
// bindings.foreach(traverse(_)) // TODO check inline proxies (see tests/tun/lst)
sources = call.symbol.topLevelClass.source :: sources
if (!isMacro(call)) // FIXME macro implementations can drop Inlined nodes. We should reinsert them after macro expansion based on the positions of the trees
traverse(expansion)(using inlineContext(call).withSource(sources.head))
sources = sources.tail
case _ => traverseChildren(tree)
}
}
}
}.traverse(tree)
}
checker.traverse(tree)
case _ =>
}

Expand Down
10 changes: 9 additions & 1 deletion compiler/src/dotty/tools/dotc/typer/Inliner.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1540,7 +1540,15 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(using Context) {
ctx

override def typedIdent(tree: untpd.Ident, pt: Type)(using Context): Tree =
inlineIfNeeded(tryInlineArg(tree.asInstanceOf[tpd.Tree]) `orElse` super.typedIdent(tree, pt))
val tree1 = inlineIfNeeded(
tryInlineArg(tree.asInstanceOf[tpd.Tree]) `orElse` super.typedIdent(tree, pt)
)
tree1 match
case id: Ident if tpd.needsSelect(id.tpe) =>
inlining.println(i"expanding $id to selection")
ref(id.tpe.asInstanceOf[TermRef]).withSpan(id.span)
case _ =>
tree1

override def typedSelect(tree: untpd.Select, pt: Type)(using Context): Tree = {
val qual1 = typed(tree.qualifier, shallowSelectionProto(tree.name, pt, this))
Expand Down
23 changes: 23 additions & 0 deletions tests/pos/i13334.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
class Bar

transparent inline def bar(i: Int): Bar =
new Bar:
def j = i

class Foo(x: Int):
def foo = bar(x)

trait DFC
given DFC = new DFC {}

trait TC
object TC:
def foo()(using DFC): Unit = {}

transparent inline given (using DFC): TC = new TC:
foo()

class Baz(using DFC):
summon[TC]

val top = new Baz