summaryrefslogtreecommitdiff
path: root/test/files/run/t8047.scala
diff options
context:
space:
mode:
authorDen Shabalin <den.shabalin@gmail.com>2013-12-08 20:18:56 +0100
committerDen Shabalin <den.shabalin@gmail.com>2013-12-16 14:07:40 +0100
commitb97d44b2d813c1bf482b23efb353e4550818700c (patch)
treede432783867f16d86a016296156a793fa46b110c /test/files/run/t8047.scala
parent75cc6cf256df9e152eaec771121ce0db9f7039f8 (diff)
downloadscala-b97d44b2d813c1bf482b23efb353e4550818700c.tar.gz
scala-b97d44b2d813c1bf482b23efb353e4550818700c.tar.bz2
scala-b97d44b2d813c1bf482b23efb353e4550818700c.zip
SI-8047 change fresh name encoding to avoid owner corruption
Previously a following encoding was used to represent fresh names that should be created at runtime of the quasiquote: build.withFreshTermName(prefix1) { name$1 => ... build.withFreshTermName(prefixN) { name$N => tree } ... } It turned out that this encoding causes symbol corruption when tree defines symbols of its own. After being spliced into anonymous functions, the owner chain of those symbols will become corrupted. Now a simpler and probably better performing alternative is used instead: { val name$1 = universe.build.freshTermName(prefix1) ... val name$N = universe.build.freshTermName(prefixN) tree } Here owner stays the same and doesn’t need any adjustment.
Diffstat (limited to 'test/files/run/t8047.scala')
-rw-r--r--test/files/run/t8047.scala31
1 files changed, 31 insertions, 0 deletions
diff --git a/test/files/run/t8047.scala b/test/files/run/t8047.scala
new file mode 100644
index 0000000000..f5660541e8
--- /dev/null
+++ b/test/files/run/t8047.scala
@@ -0,0 +1,31 @@
+object Test extends App {
+ import scala.reflect.runtime.universe._
+ //
+ // x's owner is outer Test scope. Previosly the quasiquote expansion
+ // looked like:
+ //
+ // object Test {
+ // build.withFreshTermName("doWhile")(n =>
+ // LabelDef(n, List(),
+ // Block(
+ // List({ val x = 1; x }),
+ // If(Literal(Constant(true)), Apply(Ident(n), List()), Literal(Constant(())))))
+ // }
+ //
+ // Here the proper owner is anonymous function, not the Test. Hence
+ // symbol corruption. In new encoding this is represented as:
+ //
+ // object Test {
+ // {
+ // val n = build.freshTermName("doWhile")
+ // LabelDef(n, List(),
+ // Block(
+ // List({ val x = 1; x }),
+ // If(Literal(Constant(true)), Apply(Ident(n), List()), Literal(Constant(()))))
+ // }
+ // }
+ //
+ // Owner stays the same and life is good again.
+ //
+ println(q"do ${ val x = 1; x } while(true)")
+}