diff --git a/compiler/src/dotty/tools/dotc/typer/Inliner.scala b/compiler/src/dotty/tools/dotc/typer/Inliner.scala index 562a5e6898c6..d0f0cdbb772c 100644 --- a/compiler/src/dotty/tools/dotc/typer/Inliner.scala +++ b/compiler/src/dotty/tools/dotc/typer/Inliner.scala @@ -211,6 +211,9 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(implicit ctx: Context) { */ private val paramBinding = new mutable.HashMap[Name, Type] + /** A map from parameter names of the inlineable method to spans of the actual arguments */ + private val paramSpan = new mutable.HashMap[Name, Span] + /** A map from references to (type and value) parameters of the inlineable method * to their corresponding argument or proxy references, as given by `paramBinding`. */ @@ -271,12 +274,14 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(implicit ctx: Context) { private def computeParamBindings(tp: Type, targs: List[Tree], argss: List[List[Tree]]): Unit = tp match { case tp: PolyType => (tp.paramNames, targs).zipped.foreach { (name, arg) => + paramSpan(name) = arg.span paramBinding(name) = arg.tpe.stripTypeVar } computeParamBindings(tp.resultType, Nil, argss) case tp: MethodType => assert(argss.nonEmpty, i"missing bindings: $tp in $call") (tp.paramNames, tp.paramInfos, argss.head).zipped.foreach { (name, paramtp, arg) => + paramSpan(name) = arg.span paramBinding(name) = arg.tpe.dealias match { case _: SingletonType if isIdempotentExpr(arg) => arg.tpe case _ => paramBindingDef(name, paramtp, arg, bindingsBuf).symbol.termRef @@ -439,12 +444,19 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(implicit ctx: Context) { case _ => tree } case tree: Ident => + /* Span of the argument. Used when the argument is inlined directly without a binding */ + def argSpan = + if (tree.name == nme.WILDCARD) tree.span // From type match + else if (tree.symbol.isTypeParam && tree.symbol.owner.isClass) tree.span // TODO is this the correct span? + else paramSpan(tree.name) paramProxy.get(tree.tpe) match { case Some(t) if tree.isTerm && t.isSingleton => - // FIXME wrong span, this is the span inside the inline method - singleton(t.dealias).withSpan(tree.span) + t.dealias match { + case tp: ConstantType => Inlined(EmptyTree, Nil, singleton(tp).withSpan(argSpan)).withSpan(tree.span) + case tp => singleton(tp).withSpan(argSpan) + } case Some(t) if tree.isType => - TypeTree(t).withSpan(tree.span) + TypeTree(t).withSpan(argSpan) case _ => tree } case tree => tree @@ -877,6 +889,8 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(implicit ctx: Context) { case _ => false } + case Inlined(EmptyTree, Nil, ipat) => + reducePattern(bindingsBuf, fromBuf, toBuf, scrut, ipat) case _ => false } } diff --git a/tests/run/i4947a.scala b/tests/disabled/run/i4947a.scala similarity index 100% rename from tests/run/i4947a.scala rename to tests/disabled/run/i4947a.scala diff --git a/tests/run/i4947a2.check b/tests/run/i4947a2.check new file mode 100644 index 000000000000..89bc9c7f299b --- /dev/null +++ b/tests/run/i4947a2.check @@ -0,0 +1,14 @@ +track (i = 0): Test$.main(i4947a2.scala:4) +track (i = 0): Test$.main(i4947a2.scala:5) +track (i = 2): Test$.main(i4947a2.scala:4) +track (i = 2): Test$.main(i4947a2.scala:5) +main1 (i = -1): Test$.main(i4947a2.scala:21) +main2 (i = -1): Test$.main(i4947a2.scala:22) +track (i = 1): Test$.main(i4947a2.scala:4) +track (i = 1): Test$.main(i4947a2.scala:5) +main1 (i = -1): Test$.main(i4947a2.scala:21) +main2 (i = -1): Test$.main(i4947a2.scala:22) +track (i = 0): Test$.main(i4947a2.scala:4) +track (i = 0): Test$.main(i4947a2.scala:5) +main1 (i = -1): Test$.main(i4947a2.scala:21) +main2 (i = -1): Test$.main(i4947a2.scala:22) diff --git a/tests/run/i4947a2.scala b/tests/run/i4947a2.scala new file mode 100644 index 000000000000..a08e9fe01f46 --- /dev/null +++ b/tests/run/i4947a2.scala @@ -0,0 +1,27 @@ +object Test { + + inline def fact[T](inline i: Int)(f: => T): Int = { + printStack(i, "track") + printStack(i, "track") + f + if (i == 0) + 1 + else { + i * fact(i-1)(f) + } + } + + def printStack(i: Int, tag: String): Unit = { + println(s"$tag (i = $i): ${new Exception().getStackTrace().apply(1)}") + } + + def main(args: Array[String]): Unit = { + fact(0) { + fact(2) { + printStack(-1, "main1") + printStack(-1, "main2") + } + } + } + +} diff --git a/tests/run/tasty-macro-positions.check b/tests/run/tasty-macro-positions.check index dae4b61f268f..25b2142bc36f 100644 --- a/tests/run/tasty-macro-positions.check +++ b/tests/run/tasty-macro-positions.check @@ -1,36 +1,36 @@ -quoted_2.scala:[103..103] +quoted_2.scala:[173..174] a -quoted_2.scala:[103..103] +quoted_2.scala:[184..185] b -quoted_2.scala:[213..214] +quoted_2.scala:[195..196] c -quoted_2.scala:[224..225] +quoted_2.scala:[206..207] d -quoted_2.scala:[103..103] +quoted_2.scala:[217..222] "abc" -quoted_2.scala:[259..272] +quoted_2.scala:[232..245] ("abc": scala.Predef.String) -quoted_2.scala:[282..296] +quoted_2.scala:[255..269] _root_.scala.StringContext.apply(("abc", "": scala.[scala#Predef.String])).s(("def": scala.[scala.Any])) -quoted_2.scala:[154..154] +quoted_2.scala:[281..282] a -quoted_2.scala:[154..154] +quoted_2.scala:[293..294] b -quoted_2.scala:[350..351] +quoted_2.scala:[305..306] c -quoted_2.scala:[362..363] +quoted_2.scala:[317..318] d -quoted_2.scala:[154..154] +quoted_2.scala:[329..334] "abc" -quoted_2.scala:[399..412] +quoted_2.scala:[345..358] ("abc": scala.Predef.String) -quoted_2.scala:[423..437] +quoted_2.scala:[369..383] _root_.scala.StringContext.apply(("abc", "": scala.[scala#Predef.String])).s(("def": scala.[scala.Any])) -quoted_2.scala:[201..202] +quoted_2.scala:[426..427] T -quoted_2.scala:[201..202] +quoted_2.scala:[438..444] scala.Predef.String -quoted_2.scala:[201..202] +quoted_2.scala:[455..460] "abc" -quoted_2.scala:[201..202] +quoted_2.scala:[471..472] U diff --git a/tests/run/tasty-macro-positions/quoted_2.scala b/tests/run/tasty-macro-positions/quoted_2.scala index 942c4715e404..105dfe581364 100644 --- a/tests/run/tasty-macro-positions/quoted_2.scala +++ b/tests/run/tasty-macro-positions/quoted_2.scala @@ -8,31 +8,29 @@ object Test { def c: String = "abc" def d: 42 = 42 - fun(a) // ERROR - fun(b) // ERROR + fun(a) + fun(b) fun(c) fun(d) - fun("abc") // ERROR + fun("abc") fun("abc": String) fun(s"abc${"def"}") - fun2(a) // ERROR - fun2(b) // ERROR + fun2(a) + fun2(b) fun2(c) fun2(d) - fun2("abc") // ERROR + fun2("abc") fun2("abc": String) fun2(s"abc${"def"}") type T type U = "abc" - fun3[T] // ERROR - fun3[String] // ERROR - fun3["abc"] // ERROR - fun3[U] // ERROR + fun3[T] + fun3[String] + fun3["abc"] + fun3[U] } - // FIXME all the lines marked as ERROR have the wrong position on the three of the argument. - // they all have as source file this file but the span of `'x` in `fun` or `fun2`. - // see #6026 and #6027 + }