Skip to content

Only track inlined positions #9966

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

Closed
Closed
Show file tree
Hide file tree
Changes from 2 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
6 changes: 2 additions & 4 deletions compiler/src/dotty/tools/dotc/ast/Trees.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1242,11 +1242,9 @@ object Trees {
protected def skipTransform(tree: Tree)(using Context): Boolean = false

/** For untyped trees, this is just the identity.
* For typed trees, a context derived form `ctx` that records `call` as the
* innermost enclosing call for which the inlined version is currently
* processed.
* For typed trees, this record the position of an enclosing inlined positions
*/
protected def inlineContext(call: Tree)(using Context): Context = ctx
protected def inlineContext(pos: SrcPos)(using Context): Context = ctx

abstract class TreeMap(val cpy: TreeCopier = inst.cpy) { self =>
def transform(tree: Tree)(using Context): Tree = {
Expand Down
22 changes: 6 additions & 16 deletions compiler/src/dotty/tools/dotc/ast/tpd.scala
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import typer.ProtoTypes
import transform.SymUtils._
import transform.TypeUtils._
import core._
import util.Spans._, Types._, Contexts._, Constants._, Names._, Flags._, NameOps._
import util.Spans._, util.SrcPos, Types._, Contexts._, Constants._, Names._, Flags._, NameOps._
import Symbols._, StdNames._, Annotations._, Trees._, Symbols._
import Decorators._, DenotTransformers._
import collection.{immutable, mutable}
Expand Down Expand Up @@ -1232,37 +1232,27 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
}

/** A key to be used in a context property that tracks enclosing inlined calls */
private val InlinedCalls = Property.Key[List[Tree]]()
private val InlinedCalls = Property.Key[List[SrcPos]]()

/** A key to be used in a context property that tracks the number of inlined trees */
private val InlinedTrees = Property.Key[Counter]()
final class Counter {
var count: Int = 0
}

/** Record an enclosing inlined call.
* EmptyTree calls (for parameters) cancel the next-enclosing call in the list instead of being added to it.
* We assume parameters are never nested inside parameters.
*/
override def inlineContext(call: Tree)(using Context): Context = {
/** Record an enclosing inlined positions. */
override def inlineContext(pos: SrcPos)(using Context): Context = {
// We assume enclosingInlineds is already normalized, and only process the new call with the head.
val oldIC = enclosingInlineds

val newIC =
if call.isEmpty then
oldIC match
case t1 :: ts2 => ts2
case _ => oldIC
else
call :: oldIC
val newIC = pos :: oldIC

val ctx1 = ctx.fresh.setProperty(InlinedCalls, newIC)
if oldIC.isEmpty then ctx1.setProperty(InlinedTrees, new Counter) else ctx1
}

/** All enclosing calls that are currently inlined, from innermost to outermost.
*/
def enclosingInlineds(using Context): List[Tree] =
def enclosingInlineds(using Context): List[SrcPos] =
ctx.property(InlinedCalls).getOrElse(Nil)

/** Record inlined trees */
Expand Down
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/dotc/quoted/MacroExpansion.scala
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ object MacroExpansion {
def position(using Context): Option[SourcePosition] =
ctx.property(MacroExpansionPosition)

def context(inlinedFrom: tpd.Tree)(using Context): Context =
def context(inlinedFrom: SourcePosition)(using Context): Context =
ctx.fresh.setProperty(MacroExpansionPosition, SourcePosition(inlinedFrom.source, inlinedFrom.span)).setTypeAssigner(new Typer).withSource(inlinedFrom.source)
}

Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ object QuoteContextImpl {
new QuoteContextImpl(ctx)

def showTree(tree: tpd.Tree)(using Context): String = {
val qctx = QuoteContextImpl()(using MacroExpansion.context(tree))
val qctx = QuoteContextImpl()(using MacroExpansion.context(tree.sourcePos))
val syntaxHighlight =
if (ctx.settings.color.value == "always") SyntaxHighlight.ANSI
else SyntaxHighlight.plain
Expand Down
4 changes: 2 additions & 2 deletions compiler/src/dotty/tools/dotc/report.scala
Original file line number Diff line number Diff line change
Expand Up @@ -115,8 +115,8 @@ object report:
if (ctx.settings.Ydebug.value) warning(msg, pos)

private def addInlineds(pos: SrcPos)(using Context): SourcePosition =
def recur(pos: SourcePosition, inlineds: List[Trees.Tree[?]]): SourcePosition = inlineds match
case inlined :: inlineds1 => pos.withOuter(recur(inlined.sourcePos, inlineds1))
def recur(pos: SourcePosition, inlineds: List[SrcPos]): SourcePosition = inlineds match
case inlined :: inlineds1 => pos.sourcePos.withOuter(recur(inlined.sourcePos, inlineds1))
case Nil => pos
recur(pos.sourcePos, tpd.enclosingInlineds)

Expand Down
8 changes: 4 additions & 4 deletions compiler/src/dotty/tools/dotc/typer/Inliner.scala
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ object Inliner {
i"""|Maximal number of $reason (${setting.value}) exceeded,
|Maybe this is caused by a recursive inline method?
|You can use ${setting.name} to change the limit.""",
(tree :: enclosingInlineds).last.srcPos
(tree :: enclosingInlineds).last
)
tree2
}
Expand Down Expand Up @@ -724,7 +724,7 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(using Context) {
val callToReport = if (enclosingInlineds.nonEmpty) enclosingInlineds.last else call
val ctxToReport = ctx.outersIterator.dropWhile(enclosingInlineds(using _).nonEmpty).next
inContext(ctxToReport) {
report.error(message, callToReport.srcPos)
report.error(message, callToReport)
}
case _ =>
}
Expand Down Expand Up @@ -1431,8 +1431,8 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(using Context) {
if suspendable then
ctx.compilationUnit.suspend() // this throws a SuspendException

val evaluatedSplice = inContext(quoted.MacroExpansion.context(inlinedFrom)) {
Splicer.splice(body, inlinedFrom.srcPos, MacroClassLoader.fromContext)
val evaluatedSplice = inContext(quoted.MacroExpansion.context(inlinedFrom.sourcePos)) {
Splicer.splice(body, inlinedFrom, MacroClassLoader.fromContext)
}
val inlinedNormailizer = new TreeMap {
override def transform(tree: tpd.Tree)(using Context): tpd.Tree = tree match {
Expand Down
30 changes: 15 additions & 15 deletions tests/run/i4947b.check
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ main1: Test$.main(Test_2.scala:4)
main2: Test$.main(Test_2.scala:5)
track: Test$.main(Test_2.scala:7)
track: Test$.main(Test_2.scala:7)
track: Test$.main(Test_2.scala:8)
track: Test$.main(Test_2.scala:8)
track: Test$.main(Test_2.scala:7)
track: Test$.main(Test_2.scala:7)
main3: Test$.main(Test_2.scala:9)
main4: Test$.main(Test_2.scala:10)
track (i = 0): Test$.main(Test_2.scala:13)
Expand All @@ -15,22 +15,22 @@ track: Test$.main(Test_2.scala:13)
fact: Test$.main(Test_2.scala:13)
track (i = 2): Test$.main(Test_2.scala:14)
track (i = 2): Test$.main(Test_2.scala:14)
track: Test$.main(Test_2.scala:14)
track: Test$.main(Test_2.scala:14)
fact: Test$.main(Test_2.scala:14)
track: Test$.main(Test_2.scala:13)
track: Test$.main(Test_2.scala:13)
fact: Test$.main(Test_2.scala:13)
main1 (i = -1): Test$.main(Test_2.scala:15)
main2 (i = -1): Test$.main(Test_2.scala:16)
track (i = 1): Test$.main(Test_2.scala:14)
track (i = 1): Test$.main(Test_2.scala:14)
track: Test$.main(Test_2.scala:14)
track: Test$.main(Test_2.scala:14)
fact: Test$.main(Test_2.scala:14)
track (i = 1): Test$.main(Test_2.scala:13)
track (i = 1): Test$.main(Test_2.scala:13)
track: Test$.main(Test_2.scala:13)
track: Test$.main(Test_2.scala:13)
fact: Test$.main(Test_2.scala:13)
main1 (i = -1): Test$.main(Test_2.scala:15)
main2 (i = -1): Test$.main(Test_2.scala:16)
track (i = 0): Test$.main(Test_2.scala:14)
track (i = 0): Test$.main(Test_2.scala:14)
track: Test$.main(Test_2.scala:14)
track: Test$.main(Test_2.scala:14)
fact: Test$.main(Test_2.scala:14)
track (i = 0): Test$.main(Test_2.scala:13)
track (i = 0): Test$.main(Test_2.scala:13)
track: Test$.main(Test_2.scala:13)
track: Test$.main(Test_2.scala:13)
fact: Test$.main(Test_2.scala:13)
main1 (i = -1): Test$.main(Test_2.scala:15)
main2 (i = -1): Test$.main(Test_2.scala:16)