Skip to content

Commit fa91b17

Browse files
committed
SI-8200 provide an identity liftable for trees
This liftable hasn't been originally included in the set of standard liftables due to following contradiction: 1. On one hand we can have identity lifting that seems to be quite consistent with regular unquoting: q"..${List(1,2)}" <==> q"1; 2" q"${List(1,2)}" <==> q"s.c.i.List(1, 2)" q"..${List(q"a", q"b")}” <==> q"a; b" q"${List(q"a", q"b")}" <==> q"s.c.i.List(a, b)" This is also consistent with how lisp unquoting works although they get lifting for free thanks to homoiconicity: // scala scala> val x = List(q"a", q"b); q"f($x)" q"f(s.c.i.List(a, b))" // scheme > (let [(x (list a b))] `(f ,x)) '(f (list a b)) 2. On the other hand lifting is an operation that converts a value into a code that when evaluated turns into the same value. In this sense Liftable[Tree] means reification of a tree into a tree that represents it, i.e.: q"${List(q"a", q"b")}" <==> q"""s.c.i.List(Ident(TermName("a")), Ident(TermName("b")))""" But I belive that such lifting will be very confusing for everyone other than a few very advanced users. This commit introduces the first option as a default Liftable for trees.
1 parent bcf24ec commit fa91b17

File tree

5 files changed

+28
-5
lines changed

5 files changed

+28
-5
lines changed

bincompat-backward.whitelist.conf

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,11 @@ filter {
102102
matchName="scala.collection.mutable.ArrayOps#ofDouble.unzip3"
103103
problemName=IncompatibleMethTypeProblem
104104
},
105+
// see SI-8200
106+
{
107+
matchName="scala.reflect.api.StandardLiftables#StandardLiftableInstances.liftTree"
108+
problemName=MissingMethodProblem
109+
},
105110
// see SI-8331
106111
{
107112
matchName="scala.reflect.api.Internals#ReificationSupportApi#SyntacticTypeAppliedExtractor.unapply"

bincompat-forward.whitelist.conf

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,15 @@ filter {
102102
matchName="scala.collection.mutable.ArrayOps#ofDouble.unzip3"
103103
problemName=IncompatibleMethTypeProblem
104104
},
105+
// see SI-8200
106+
{
107+
matchName="scala.reflect.api.Liftables#Liftable.liftTree"
108+
problemName=MissingMethodProblem
109+
},
110+
{
111+
matchName="scala.reflect.api.StandardLiftables#StandardLiftableInstances.liftTree"
112+
problemName=MissingMethodProblem
113+
},
105114
// see SI-8331
106115
{
107116
matchName="scala.reflect.api.Internals#ReificationSupportApi.SyntacticSelectType"

src/reflect/scala/reflect/api/StandardLiftables.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ trait StandardLiftables { self: Universe =>
2727
callScala(stdnme.Symbol)(Literal(Constant(v.name)) :: Nil)
2828
}
2929

30+
implicit def liftTree[T <: Tree]: Liftable[T] = Liftable { identity }
3031
implicit def liftName[T <: Name]: Liftable[T] = Liftable { name => Ident(name) }
3132
implicit def liftExpr[T <: Expr[_]]: Liftable[T] = Liftable { expr => expr.tree }
3233
implicit def liftType[T <: Type]: Liftable[T] = Liftable { tpe => TypeTree(tpe) }

test/files/scalacheck/quasiquotes/ErrorProps.scala

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,10 @@ object ErrorProps extends QuasiquoteProperties("errors") {
99
""")
1010

1111
property("can't unquote with given rank") = fails(
12-
"Can't unquote List[reflect.runtime.universe.Ident], consider using ..",
12+
"Can't unquote List[StringBuilder], consider using .. or providing an implicit instance of Liftable[List[StringBuilder]]",
1313
"""
14-
val xs = List(q"x", q"x")
14+
import java.lang.StringBuilder
15+
val xs: List[StringBuilder] = Nil
1516
q"$xs"
1617
""")
1718

@@ -71,9 +72,10 @@ object ErrorProps extends QuasiquoteProperties("errors") {
7172
""")
7273

7374
property("use ... rank or provide liftable") = fails(
74-
"Can't unquote List[List[reflect.runtime.universe.Ident]], consider using ...",
75+
"Can't unquote List[List[StringBuilder]], consider using ... or providing an implicit instance of Liftable[List[List[StringBuilder]]]",
7576
"""
76-
val xs = List(List(q"x", q"x"))
77+
import java.lang.StringBuilder
78+
val xs: List[List[StringBuilder]] = Nil
7779
q"$xs"
7880
""")
7981

test/files/scalacheck/quasiquotes/LiftableProps.scala

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,16 +88,22 @@ object LiftableProps extends QuasiquoteProperties("liftable") {
8888
assert(q"$const" q"0")
8989
}
9090

91+
val immutable = q"$scalapkg.collection.immutable"
92+
9193
property("lift list variants") = test {
9294
val lst = List(1, 2)
93-
val immutable = q"$scalapkg.collection.immutable"
9495
assert(q"$lst" q"$immutable.List(1, 2)")
9596
assert(q"f(..$lst)" q"f(1, 2)")
9697
val llst = List(List(1), List(2))
9798
assert(q"f(..$llst)" q"f($immutable.List(1), $immutable.List(2))")
9899
assert(q"f(...$llst)" q"f(1)(2)")
99100
}
100101

102+
property("lift list of tree") = test {
103+
val lst = List(q"a", q"b")
104+
assert(q"$lst" q"$immutable.List(a, b)")
105+
}
106+
101107
property("lift tuple") = test {
102108
assert(q"${(1, 2)}" q"(1, 2)")
103109
assert(q"${(1, 2, 3)}" q"(1, 2, 3)")

0 commit comments

Comments
 (0)