Skip to content

Commit 9b5573a

Browse files
committed
Fix scala#8585: Refresh names to avoid name clashes
1 parent 2c3212b commit 9b5573a

12 files changed

+201
-137
lines changed

library/src/scala/tasty/reflect/SourceCodePrinter.scala

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -324,7 +324,7 @@ class SourceCodePrinter[R <: Reflection & Singleton](val tasty: R)(syntaxHighlig
324324

325325
case tree: Ident =>
326326
splicedName(tree.symbol) match {
327-
case Some(name) => this += name
327+
case Some(name) => this += highlightTypeDef(name)
328328
case _ => printType(tree.tpe)
329329
}
330330

@@ -834,7 +834,7 @@ class SourceCodePrinter[R <: Reflection & Singleton](val tasty: R)(syntaxHighlig
834834
}
835835

836836
def printParamDef(arg: ValDef)(using elideThis: Option[Symbol]): Unit = {
837-
val name = arg.name
837+
val name = splicedName(arg.symbol).getOrElse(arg.symbol.name)
838838
val sym = arg.symbol.owner
839839
if sym.isDefDef && sym.name == "<init>" then
840840
val ClassDef(_, _, _, _, _, body) = sym.owner.tree
@@ -1409,11 +1409,26 @@ class SourceCodePrinter[R <: Reflection & Singleton](val tasty: R)(syntaxHighlig
14091409
private def escapedString(str: String): String = str flatMap escapedChar
14101410
}
14111411

1412+
private[this] val names = collection.mutable.Map.empty[Symbol, String]
1413+
private[this] val namesIndex = collection.mutable.Map.empty[String, Int]
1414+
14121415
private def splicedName(sym: Symbol)(using ctx: Context): Option[String] = {
14131416
sym.annots.find(_.symbol.owner == ctx.requiredClass("scala.internal.quoted.showName")).flatMap {
14141417
case Apply(_, Literal(Constant(c: String)) :: Nil) => Some(c)
14151418
case Apply(_, Inlined(_, _, Literal(Constant(c: String))) :: Nil) => Some(c)
14161419
case annot => None
1420+
}.orElse {
1421+
if sym.owner.isClassDef then None
1422+
else names.get(sym).orElse {
1423+
val name0 = sym.name
1424+
val index = namesIndex.getOrElse(name0, 1)
1425+
namesIndex(name0) = index + 1
1426+
val name =
1427+
if index == 1 then name0
1428+
else s"`$name0${index.toString.toCharArray.map {x => (x - '0' + '₀').toChar}.mkString}`"
1429+
names(sym) = name
1430+
Some(name)
1431+
}
14171432
}
14181433
}
14191434

tests/run-macros/flops-rewrite.check

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
scala.Nil.map[scala.Nothing](((x: scala.Nothing) => x))
22
scala.Nil
33

4-
scala.Nil.map[scala.Nothing](((x: scala.Nothing) => x)).++[scala.Nothing](scala.Nil.map[scala.Nothing](((x: scala.Nothing) => x)))
4+
scala.Nil.map[scala.Nothing](((x: scala.Nothing) => x)).++[scala.Nothing](scala.Nil.map[scala.Nothing](((`x₂`: scala.Nothing) => `x₂`)))
55
scala.Nil
66

77
scala.Nil.map[scala.Nothing](((x: scala.Nothing) => x)).++[scala.Int](scala.List.apply[scala.Int](3)).++[scala.Int](scala.Nil)

tests/run-macros/quote-matching-optimize-1.check

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
1-
Original: ls.filter(((x: scala.Int) => x.<(3))).filter(((x: scala.Int) => x.>(1)))
1+
Original: ls.filter(((x: scala.Int) => x.<(3))).filter(((`x₂`: scala.Int) => `x₂`.>(1)))
22
Optimized: ls.filter(((x: scala.Int) => x.<(3).&&(x.>(1))))
33
Result: List(2)
44

5-
Original: ls2.filter(((x: scala.Char) => x.<('c'))).filter(((x: scala.Char) => x.>('a')))
5+
Original: ls2.filter(((x: scala.Char) => x.<('c'))).filter(((`x₂`: scala.Char) => `x₂`.>('a')))
66
Optimized: ls2.filter(((x: scala.Char) => x.<('c').&&(x.>('a'))))
77
Result: List(b)
88

9-
Original: ls.filter(((x: scala.Int) => x.<(3))).filter(((x: scala.Int) => x.>(1))).filter(((x: scala.Int) => x.==(2)))
9+
Original: ls.filter(((x: scala.Int) => x.<(3))).filter(((`x₂`: scala.Int) => `x₂`.>(1))).filter(((`x₃`: scala.Int) => `x₃`.==(2)))
1010
Optimized: ls.filter(((x: scala.Int) => x.<(3).&&(x.>(1).&&(x.==(2)))))
1111
Result: List(2)
1212

1313
1
1414
2
15-
Original: ls.filter(((x: scala.Int) => x.<(3))).foreach[scala.Unit](((x: scala.Int) => scala.Predef.println(x)))
15+
Original: ls.filter(((x: scala.Int) => x.<(3))).foreach[scala.Unit](((`x₂`: scala.Int) => scala.Predef.println(`x₂`)))
1616
Optimized: ls.foreach[scala.Unit](((x: scala.Int) => if (x.<(3)) scala.Predef.println(x) else ()))
1717
Result: ()
1818

tests/run-macros/quote-matching-optimize-2.check

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
1-
Original: ls.filter(((x: scala.Int) => x.<(3))).filter(((x: scala.Int) => x.>(1)))
1+
Original: ls.filter(((x: scala.Int) => x.<(3))).filter(((`x₂`: scala.Int) => `x₂`.>(1)))
22
Optimized: ls.filter(((x: scala.Int) => x.<(3).&&(x.>(1))))
33
Result: List(2)
44

5-
Original: ls2.filter(((x: scala.Char) => x.<('c'))).filter(((x: scala.Char) => x.>('a')))
5+
Original: ls2.filter(((x: scala.Char) => x.<('c'))).filter(((`x₂`: scala.Char) => `x₂`.>('a')))
66
Optimized: ls2.filter(((x: scala.Char) => x.<('c').&&(x.>('a'))))
77
Result: List(b)
88

9-
Original: ls.filter(((x: scala.Int) => x.<(3))).filter(((x: scala.Int) => x.>(1))).filter(((x: scala.Int) => x.==(2)))
9+
Original: ls.filter(((x: scala.Int) => x.<(3))).filter(((`x₂`: scala.Int) => `x₂`.>(1))).filter(((`x₃`: scala.Int) => `x₃`.==(2)))
1010
Optimized: ls.filter(((x: scala.Int) => x.<(3).&&(x.>(1).&&(x.==(2)))))
1111
Result: List(2)
1212

1313
1
1414
2
15-
Original: ls.filter(((x: scala.Int) => x.<(3))).foreach[scala.Unit](((x: scala.Int) => scala.Predef.println(x)))
15+
Original: ls.filter(((x: scala.Int) => x.<(3))).foreach[scala.Unit](((`x₂`: scala.Int) => scala.Predef.println(`x₂`)))
1616
Optimized: ls.foreach[scala.Any](((x: scala.Int) => if (x.<(3)) scala.Predef.println(x) else ()))
1717
Result: ()
1818

tests/run-macros/quote-matching-optimize-3.check

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
1-
Original: ls.filter(((x: scala.Int) => x.<(3))).filter(((x: scala.Int) => x.>(1)))
2-
Optimized: ls.filter(((x: scala.Int) => ((x: scala.Int) => x.<(3)).apply(x).&&(((x: scala.Int) => x.>(1)).apply(x))))
1+
Original: ls.filter(((x: scala.Int) => x.<(3))).filter(((`x₂`: scala.Int) => `x₂`.>(1)))
2+
Optimized: ls.filter(((x: scala.Int) => ((`x₂`: scala.Int) => `x₂`.<(3)).apply(x).&&(((`x₃`: scala.Int) => `x₃`.>(1)).apply(x))))
33
Result: List(2)
44

5-
Original: ls2.filter(((x: scala.Char) => x.<('c'))).filter(((x: scala.Char) => x.>('a')))
6-
Optimized: ls2.filter(((x: scala.Char) => ((x: scala.Char) => x.<('c')).apply(x).&&(((x: scala.Char) => x.>('a')).apply(x))))
5+
Original: ls2.filter(((x: scala.Char) => x.<('c'))).filter(((`x₂`: scala.Char) => `x₂`.>('a')))
6+
Optimized: ls2.filter(((x: scala.Char) => ((`x₂`: scala.Char) => `x₂`.<('c')).apply(x).&&(((`x₃`: scala.Char) => `x₃`.>('a')).apply(x))))
77
Result: List(b)
88

9-
Original: ls.filter(((x: scala.Int) => x.<(3))).filter(((x: scala.Int) => x.>(1))).filter(((x: scala.Int) => x.==(2)))
10-
Optimized: ls.filter(((x: scala.Int) => ((x: scala.Int) => x.<(3)).apply(x).&&(((x: scala.Int) => ((x: scala.Int) => x.>(1)).apply(x).&&(((x: scala.Int) => x.==(2)).apply(x))).apply(x))))
9+
Original: ls.filter(((x: scala.Int) => x.<(3))).filter(((`x₂`: scala.Int) => `x₂`.>(1))).filter(((`x₃`: scala.Int) => `x₃`.==(2)))
10+
Optimized: ls.filter(((x: scala.Int) => ((`x₂`: scala.Int) => `x₂`.<(3)).apply(x).&&(((`x₃`: scala.Int) => ((`x₄`: scala.Int) => `x₄`.>(1)).apply(`x₃`).&&(((`x₅`: scala.Int) => `x₅`.==(2)).apply(`x₃`))).apply(x))))
1111
Result: List(2)
1212

1313
1
1414
2
15-
Original: ls.filter(((x: scala.Int) => x.<(3))).foreach[scala.Unit](((x: scala.Int) => scala.Predef.println(x)))
16-
Optimized: ls.foreach[scala.Any](((x: scala.Int) => if (((x: scala.Int) => x.<(3)).apply(x)) ((x: scala.Int) => scala.Predef.println(x)).apply(x) else ()))
15+
Original: ls.filter(((x: scala.Int) => x.<(3))).foreach[scala.Unit](((`x₂`: scala.Int) => scala.Predef.println(`x₂`)))
16+
Optimized: ls.foreach[scala.Any](((x: scala.Int) => if (((`x₂`: scala.Int) => `x₂`.<(3)).apply(x)) ((`x₃`: scala.Int) => scala.Predef.println(`x₃`)).apply(x) else ()))
1717
Result: ()
1818

1919
Original: ls.map[scala.Long](((a: scala.Int) => a.toLong)).map[java.lang.String](((b: scala.Long) => b.toString()))

tests/run-staging/i3876-c.check

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
{
33
val f: scala.Function1[scala.Int, scala.Int] {
44
def apply(x: scala.Int): scala.Int
5-
} = ((x: scala.Int) => x.+(x))
5+
} = ((`x₂`: scala.Int) => `x₂`.+(`x₂`))
66

77
(f: scala.Function1[scala.Int, scala.Int] {
88
def apply(x: scala.Int): scala.Int

tests/run-staging/i5144.check

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
{
2-
def f(x: scala.Int): scala.Int = ((x: scala.Int) => f(x)).apply(42)
2+
def f(x: scala.Int): scala.Int = ((`x₂`: scala.Int) => f(`x₂`)).apply(42)
33
()
4-
}
4+
}

tests/run-staging/i8585.check

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
The following would not compile:
2+
((x: scala.Double) => {
3+
val y: scala.Double = x.*(x)
4+
val `y₂`: scala.Double = y.*(y)
5+
`y₂`.*(`y₂`)
6+
})
7+
3^8 = 6561.0
8+
The following would not compile:
9+
((x: scala.Double) => x.*({
10+
val y: scala.Double = x.*(x)
11+
y.*({
12+
val `y₂`: scala.Double = y.*(y)
13+
`y₂`.*({
14+
val `y₃`: scala.Double = `y₂`.*(`y₂`)
15+
`y₃`.*({
16+
val `y₄`: scala.Double = `y₃`.*(`y₃`)
17+
`y₄`.*(`y₄`)
18+
})
19+
})
20+
})
21+
}))
22+
2^47 = 1.40737488355328E14

tests/run-staging/i8585.scala

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import scala.quoted._
2+
import scala.quoted.staging.{run, withQuoteContext, Toolbox}
3+
4+
object Test {
5+
given Toolbox = Toolbox.make(getClass.getClassLoader)
6+
7+
def main(args: Array[String]): Unit = {
8+
val toTheEighth = stagedPower(8)
9+
println("3^8 = " + toTheEighth(3))
10+
11+
val toThe47 = stagedPower(47)
12+
println("2^47 = " + toThe47(2))
13+
}
14+
15+
def stagedPower(n: Int): Double => Double = {
16+
def code(using QuoteContext) = '{ (x: Double) => ${ powerCode(n, 'x) } }
17+
println("The following would not compile:")
18+
println(withQuoteContext(code.show))
19+
run(code)
20+
}
21+
22+
def powerCode(n: Int, x: Expr[Double])(using ctx: QuoteContext): Expr[Double] =
23+
if (n == 1) x
24+
else if (n == 2) '{ $x * $x }
25+
else if (n % 2 == 1) '{ $x * ${ powerCode(n - 1, x) } }
26+
else '{ val y = $x * $x; ${ powerCode(n / 2, 'y) } }
27+
}

tests/run-staging/quote-run-2.check

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,11 @@
1111
{
1212
val y: scala.Double = 5.0.*(5.0)
1313
y.*({
14-
val y: scala.Double = y.*(y)
15-
y.*({
16-
val y: scala.Double = y.*(y)
17-
val y: scala.Double = y.*(y)
18-
y
14+
val `y₂`: scala.Double = y.*(y)
15+
`y₂`.*({
16+
val `y₃`: scala.Double = `y₂`.*(`y₂`)
17+
val `y₄`: scala.Double = `y₃`.*(`y₃`)
18+
`y₄`
1919
})
2020
})
2121
}

tests/run-staging/quote-unrolled-foreach.check

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
var i: scala.Int = 0
3434
while (i.<(size)) {
3535
val element: scala.Int = arr.apply(i)
36-
((i: scala.Int) => java.lang.System.out.println(i)).apply(element)
36+
((`i₂`: scala.Int) => java.lang.System.out.println(`i₂`)).apply(element)
3737
i = i.+(1)
3838
}
3939
})

0 commit comments

Comments
 (0)