Skip to content

Commit b5be833

Browse files
Merge pull request #6066 from dotty-staging/fix-#6026
Use argument span for inlined singleton an type arguments
2 parents 09a56e5 + 0206e57 commit b5be833

File tree

6 files changed

+87
-34
lines changed

6 files changed

+87
-34
lines changed

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

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,9 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(implicit ctx: Context) {
211211
*/
212212
private val paramBinding = new mutable.HashMap[Name, Type]
213213

214+
/** A map from parameter names of the inlineable method to spans of the actual arguments */
215+
private val paramSpan = new mutable.HashMap[Name, Span]
216+
214217
/** A map from references to (type and value) parameters of the inlineable method
215218
* to their corresponding argument or proxy references, as given by `paramBinding`.
216219
*/
@@ -271,12 +274,14 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(implicit ctx: Context) {
271274
private def computeParamBindings(tp: Type, targs: List[Tree], argss: List[List[Tree]]): Unit = tp match {
272275
case tp: PolyType =>
273276
(tp.paramNames, targs).zipped.foreach { (name, arg) =>
277+
paramSpan(name) = arg.span
274278
paramBinding(name) = arg.tpe.stripTypeVar
275279
}
276280
computeParamBindings(tp.resultType, Nil, argss)
277281
case tp: MethodType =>
278282
assert(argss.nonEmpty, i"missing bindings: $tp in $call")
279283
(tp.paramNames, tp.paramInfos, argss.head).zipped.foreach { (name, paramtp, arg) =>
284+
paramSpan(name) = arg.span
280285
paramBinding(name) = arg.tpe.dealias match {
281286
case _: SingletonType if isIdempotentExpr(arg) => arg.tpe
282287
case _ => paramBindingDef(name, paramtp, arg, bindingsBuf).symbol.termRef
@@ -439,12 +444,19 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(implicit ctx: Context) {
439444
case _ => tree
440445
}
441446
case tree: Ident =>
447+
/* Span of the argument. Used when the argument is inlined directly without a binding */
448+
def argSpan =
449+
if (tree.name == nme.WILDCARD) tree.span // From type match
450+
else if (tree.symbol.isTypeParam && tree.symbol.owner.isClass) tree.span // TODO is this the correct span?
451+
else paramSpan(tree.name)
442452
paramProxy.get(tree.tpe) match {
443453
case Some(t) if tree.isTerm && t.isSingleton =>
444-
// FIXME wrong span, this is the span inside the inline method
445-
singleton(t.dealias).withSpan(tree.span)
454+
t.dealias match {
455+
case tp: ConstantType => Inlined(EmptyTree, Nil, singleton(tp).withSpan(argSpan)).withSpan(tree.span)
456+
case tp => singleton(tp).withSpan(argSpan)
457+
}
446458
case Some(t) if tree.isType =>
447-
TypeTree(t).withSpan(tree.span)
459+
TypeTree(t).withSpan(argSpan)
448460
case _ => tree
449461
}
450462
case tree => tree
@@ -877,6 +889,8 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(implicit ctx: Context) {
877889
case _ =>
878890
false
879891
}
892+
case Inlined(EmptyTree, Nil, ipat) =>
893+
reducePattern(bindingsBuf, fromBuf, toBuf, scrut, ipat)
880894
case _ => false
881895
}
882896
}
File renamed without changes.

tests/run/i4947a2.check

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
track (i = 0): Test$.main(i4947a2.scala:4)
2+
track (i = 0): Test$.main(i4947a2.scala:5)
3+
track (i = 2): Test$.main(i4947a2.scala:4)
4+
track (i = 2): Test$.main(i4947a2.scala:5)
5+
main1 (i = -1): Test$.main(i4947a2.scala:21)
6+
main2 (i = -1): Test$.main(i4947a2.scala:22)
7+
track (i = 1): Test$.main(i4947a2.scala:4)
8+
track (i = 1): Test$.main(i4947a2.scala:5)
9+
main1 (i = -1): Test$.main(i4947a2.scala:21)
10+
main2 (i = -1): Test$.main(i4947a2.scala:22)
11+
track (i = 0): Test$.main(i4947a2.scala:4)
12+
track (i = 0): Test$.main(i4947a2.scala:5)
13+
main1 (i = -1): Test$.main(i4947a2.scala:21)
14+
main2 (i = -1): Test$.main(i4947a2.scala:22)

tests/run/i4947a2.scala

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
object Test {
2+
3+
inline def fact[T](inline i: Int)(f: => T): Int = {
4+
printStack(i, "track")
5+
printStack(i, "track")
6+
f
7+
if (i == 0)
8+
1
9+
else {
10+
i * fact(i-1)(f)
11+
}
12+
}
13+
14+
def printStack(i: Int, tag: String): Unit = {
15+
println(s"$tag (i = $i): ${new Exception().getStackTrace().apply(1)}")
16+
}
17+
18+
def main(args: Array[String]): Unit = {
19+
fact(0) {
20+
fact(2) {
21+
printStack(-1, "main1")
22+
printStack(-1, "main2")
23+
}
24+
}
25+
}
26+
27+
}

tests/run/tasty-macro-positions.check

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,36 @@
1-
quoted_2.scala:[103..103]
1+
quoted_2.scala:[173..174]
22
a
3-
quoted_2.scala:[103..103]
3+
quoted_2.scala:[184..185]
44
b
5-
quoted_2.scala:[213..214]
5+
quoted_2.scala:[195..196]
66
c
7-
quoted_2.scala:[224..225]
7+
quoted_2.scala:[206..207]
88
d
9-
quoted_2.scala:[103..103]
9+
quoted_2.scala:[217..222]
1010
"abc"
11-
quoted_2.scala:[259..272]
11+
quoted_2.scala:[232..245]
1212
("abc": scala.Predef.String)
13-
quoted_2.scala:[282..296]
13+
quoted_2.scala:[255..269]
1414
_root_.scala.StringContext.apply(("abc", "": scala.<repeated>[scala#Predef.String])).s(("def": scala.<repeated>[scala.Any]))
15-
quoted_2.scala:[154..154]
15+
quoted_2.scala:[281..282]
1616
a
17-
quoted_2.scala:[154..154]
17+
quoted_2.scala:[293..294]
1818
b
19-
quoted_2.scala:[350..351]
19+
quoted_2.scala:[305..306]
2020
c
21-
quoted_2.scala:[362..363]
21+
quoted_2.scala:[317..318]
2222
d
23-
quoted_2.scala:[154..154]
23+
quoted_2.scala:[329..334]
2424
"abc"
25-
quoted_2.scala:[399..412]
25+
quoted_2.scala:[345..358]
2626
("abc": scala.Predef.String)
27-
quoted_2.scala:[423..437]
27+
quoted_2.scala:[369..383]
2828
_root_.scala.StringContext.apply(("abc", "": scala.<repeated>[scala#Predef.String])).s(("def": scala.<repeated>[scala.Any]))
29-
quoted_2.scala:[201..202]
29+
quoted_2.scala:[426..427]
3030
T
31-
quoted_2.scala:[201..202]
31+
quoted_2.scala:[438..444]
3232
scala.Predef.String
33-
quoted_2.scala:[201..202]
33+
quoted_2.scala:[455..460]
3434
"abc"
35-
quoted_2.scala:[201..202]
35+
quoted_2.scala:[471..472]
3636
U

tests/run/tasty-macro-positions/quoted_2.scala

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8,31 +8,29 @@ object Test {
88
def c: String = "abc"
99
def d: 42 = 42
1010

11-
fun(a) // ERROR
12-
fun(b) // ERROR
11+
fun(a)
12+
fun(b)
1313
fun(c)
1414
fun(d)
15-
fun("abc") // ERROR
15+
fun("abc")
1616
fun("abc": String)
1717
fun(s"abc${"def"}")
1818

19-
fun2(a) // ERROR
20-
fun2(b) // ERROR
19+
fun2(a)
20+
fun2(b)
2121
fun2(c)
2222
fun2(d)
23-
fun2("abc") // ERROR
23+
fun2("abc")
2424
fun2("abc": String)
2525
fun2(s"abc${"def"}")
2626

2727
type T
2828
type U = "abc"
2929

30-
fun3[T] // ERROR
31-
fun3[String] // ERROR
32-
fun3["abc"] // ERROR
33-
fun3[U] // ERROR
30+
fun3[T]
31+
fun3[String]
32+
fun3["abc"]
33+
fun3[U]
3434
}
35-
// FIXME all the lines marked as ERROR have the wrong position on the three of the argument.
36-
// they all have as source file this file but the span of `'x` in `fun` or `fun2`.
37-
// see #6026 and #6027
35+
3836
}

0 commit comments

Comments
 (0)