Skip to content

Commit 7221287

Browse files
Merge pull request #4081 from dotty-staging/fix-#4044
Fix #4044: Change quote pickled representation
2 parents 785c696 + b74c723 commit 7221287

27 files changed

+453
-81
lines changed

compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1133,19 +1133,14 @@ class TreeUnpickler(reader: TastyReader,
11331133
val idx = readNat()
11341134
val args = until(end)(readTerm())
11351135
val splice = splices(idx)
1136-
1136+
val reifiedArgs = args.map(arg => if (arg.isTerm) new TreeExpr(arg) else new TreeType(arg))
11371137
if (isType) {
1138-
val quotedType =
1139-
if (args.isEmpty) splice.asInstanceOf[quoted.Type[_]]
1140-
else splice.asInstanceOf[Seq[Any] => quoted.Type[_]](args.map(tree => new TreeType(tree)))
1138+
val quotedType = splice.asInstanceOf[Seq[Any] => quoted.Type[_]](reifiedArgs)
11411139
PickledQuotes.quotedTypeToTree(quotedType)
11421140
} else {
1143-
val quotedExpr =
1144-
if (args.isEmpty) splice.asInstanceOf[quoted.Expr[_]]
1145-
else splice.asInstanceOf[Seq[Any] => quoted.Expr[_]](args.map(tree => new TreeExpr(tree)))
1141+
val quotedExpr = splice.asInstanceOf[Seq[Any] => quoted.Expr[_]](reifiedArgs)
11461142
PickledQuotes.quotedExprToTree(quotedExpr)
11471143
}
1148-
11491144
}
11501145

11511146
// ------ Setting positions ------------------------------------------------

compiler/src/dotty/tools/dotc/transform/ReifyQuotes.scala

Lines changed: 174 additions & 73 deletions
Large diffs are not rendered by default.

tests/neg/i4044a.scala

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import scala.quoted._
2+
3+
class Test {
4+
5+
val a = '(1)
6+
'{
7+
a // error
8+
~a
9+
'(~a) // error
10+
'( '(~a) ) // error
11+
}
12+
13+
}

tests/neg/i4044b.scala

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import scala.quoted._
2+
3+
class Test {
4+
5+
'{
6+
7+
val b = '(3)
8+
9+
'{
10+
b // error
11+
~(b)
12+
~('(b)) // error
13+
'( '(~b) ) // error
14+
}
15+
16+
}
17+
18+
}

tests/run-with-compiler/i4044a.check

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
3

tests/run-with-compiler/i4044a.scala

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import scala.quoted._
2+
import dotty.tools.dotc.quoted.Toolbox._
3+
4+
class Foo {
5+
def foo: Unit = {
6+
val e: Expr[Int] = '(3)
7+
val q = '{ ~( '{ ~e } ) }
8+
println(q.show)
9+
}
10+
}
11+
12+
object Test {
13+
def main(args: Array[String]): Unit = {
14+
val f = new Foo
15+
f.foo
16+
}
17+
}

tests/run-with-compiler/i4044b.check

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
var x: Int = 4
3+
x = 3
4+
x
5+
}

tests/run-with-compiler/i4044b.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 dotty.tools.dotc.quoted.Toolbox._
3+
4+
sealed abstract class VarRef[T] {
5+
def update(expr: Expr[T]): Expr[Unit]
6+
def expr: Expr[T]
7+
}
8+
9+
object VarRef {
10+
def apply[T: Type, U](init: Expr[T])(body: VarRef[T] => Expr[U]): Expr[U] = '{
11+
var x = ~init
12+
~body(
13+
new VarRef {
14+
def update(e: Expr[T]): Expr[Unit] = '{ x = ~e }
15+
def expr: Expr[T] = '(x)
16+
}
17+
)
18+
}
19+
20+
}
21+
22+
object Test {
23+
def main(args: Array[String]): Unit = {
24+
val q = VarRef(4)(varRef => '{ ~varRef.update(3); ~varRef.expr })
25+
println(q.show)
26+
}
27+
}

tests/run-with-compiler/i4044c.check

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
5

tests/run-with-compiler/i4044c.scala

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import scala.quoted._
2+
import dotty.tools.dotc.quoted.Toolbox._
3+
4+
class Foo {
5+
def foo: Unit = {
6+
val q = '{ ~( '{ ~( '{ 5 } ) } ) }
7+
println(q.show)
8+
}
9+
}
10+
11+
object Test {
12+
def main(args: Array[String]): Unit = {
13+
val f = new Foo
14+
f.foo
15+
}
16+
}

tests/run-with-compiler/i4044d.check

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
evaluating inner quote
2+
{
3+
val b: Int = 3
4+
b.+(3)
5+
}

tests/run-with-compiler/i4044d.scala

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import scala.quoted._
2+
import dotty.tools.dotc.quoted.Toolbox._
3+
4+
class Foo {
5+
def foo: Unit = {
6+
val a: Expr[Int] = '(3)
7+
val q: Expr[Int] = '{
8+
val b = 3
9+
~{
10+
println("evaluating inner quote")
11+
'{
12+
b + ~a
13+
}
14+
}
15+
}
16+
println(q.show)
17+
}
18+
}
19+
20+
object Test {
21+
def main(args: Array[String]): Unit = {
22+
val f = new Foo
23+
f.foo
24+
}
25+
}

tests/run-with-compiler/i4044e.check

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
3.+(5).asInstanceOf[Int]

tests/run-with-compiler/i4044e.scala

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import scala.quoted._
2+
import dotty.tools.dotc.quoted.Toolbox._
3+
4+
class Foo {
5+
def foo: Unit = {
6+
val e: Expr[Int] = '(3)
7+
val f: Expr[Int] = '(5)
8+
val t: Type[Int] = '[Int]
9+
val q = '{ ~( '{ (~e + ~f).asInstanceOf[~t] } ) }
10+
println(q.show)
11+
}
12+
}
13+
14+
object Test {
15+
def main(args: Array[String]): Unit = {
16+
val f = new Foo
17+
f.foo
18+
}
19+
}

tests/run-with-compiler/i4044f.check

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
val e1: Int = 3
3+
val f1: Int = 5
4+
e1.+(2).+(f1)
5+
}

tests/run-with-compiler/i4044f.scala

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import scala.quoted._
2+
import dotty.tools.dotc.quoted.Toolbox._
3+
4+
class Foo {
5+
def foo: Unit = {
6+
val e: Expr[Int] = '(3)
7+
val f: Expr[Int] = '(5)
8+
def foo(x: Expr[Int], y: Expr[Int]): Expr[Int] = '{ ~x + ~y }
9+
val q = '{
10+
val e1 = ~e
11+
val f1 = ~f
12+
~{
13+
val u = '(2)
14+
foo('{e1 + ~u}, '(f1))
15+
}
16+
}
17+
println(q.show)
18+
}
19+
}
20+
21+
object Test {
22+
def main(args: Array[String]): Unit = {
23+
val f = new Foo
24+
f.foo
25+
}
26+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import scala.quoted._
2+
3+
object Test {
4+
def main(args: Array[String]): Unit = {
5+
'{ (x: Int) => ~('(x)) }
6+
}
7+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<special-ops>.'[Int](3)
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import quoted._
2+
import dotty.tools.dotc.quoted.Toolbox._
3+
4+
object Test {
5+
def main(args: Array[String]): Unit = {
6+
val q = '{ '(3) }
7+
println(q.show)
8+
}
9+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
val a: quoted.Expr[Int] = <special-ops>.'[Int](4)
3+
<special-ops>.'[Int](a.unary_~)
4+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import quoted._
2+
import dotty.tools.dotc.quoted.Toolbox._
3+
4+
object Test {
5+
def main(args: Array[String]): Unit = {
6+
val q = '{
7+
val a = '(4)
8+
'(~a)
9+
}
10+
11+
println(q.show)
12+
}
13+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
type T = String
3+
val x: String = "foo"
4+
val z: T = x
5+
()
6+
x: String
7+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import quoted._
2+
import dotty.tools.dotc.quoted.Toolbox._
3+
4+
object Test {
5+
def main(args: Array[String]): Unit = {
6+
7+
val q = '{
8+
type T = String
9+
val x = "foo"
10+
~{
11+
val y = '(x)
12+
'{ val z: T = ~y }
13+
}
14+
x
15+
}
16+
17+
println(q.show)
18+
}
19+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
val t: quoted.Type[String] = <special-ops>.type_'[String]
3+
t: quoted.Type[String]
4+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import quoted._
2+
import dotty.tools.dotc.quoted.Toolbox._
3+
4+
object Test {
5+
def main(args: Array[String]): Unit = {
6+
val q = '{
7+
val t = '[String]
8+
t
9+
}
10+
11+
println(q.show)
12+
}
13+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
val a: quoted.Expr[Int] = <special-ops>.'[Int](4)
3+
<special-ops>.'[Int](a.unary_~)
4+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import quoted._
2+
import dotty.tools.dotc.quoted.Toolbox._
3+
4+
object Test {
5+
def main(args: Array[String]): Unit = {
6+
val q = '{
7+
val a = '(4)
8+
~('{
9+
'(~a)
10+
})
11+
12+
}
13+
14+
println(q.show)
15+
}
16+
}

0 commit comments

Comments
 (0)