Skip to content

Contextualize type splices #6958

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 3 additions & 4 deletions compiler/src/dotty/tools/dotc/transform/ReifyQuotes.scala
Original file line number Diff line number Diff line change
Expand Up @@ -239,11 +239,10 @@ class ReifyQuotes extends MacroTransform {
meth.appliedTo(pickledQuoteStrings, splicesList)
}

if (splices.nonEmpty) pickleAsTasty()
else if (isType) {
if (isType) {
def tag(tagName: String) = ref(defn.QuotedTypeModule).select(tagName.toTermName).appliedTo(qctx)
if (body.symbol.isPrimitiveValueClass) tag(s"${body.symbol.name}Tag")
else pickleAsTasty()
if (splices.isEmpty && body.symbol.isPrimitiveValueClass) tag(s"${body.symbol.name}Tag")
else pickleAsTasty().select(nme.apply).appliedTo(qctx)
}
else toValue(body) match {
case Some(value) => pickleAsValue(value)
Expand Down
3 changes: 2 additions & 1 deletion library/src/scala/runtime/quoted/Unpickler.scala
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,6 @@ object Unpickler {
/** Unpickle `repr` which represents a pickled `Type` tree,
* replacing splice nodes with `args`
*/
def unpickleType[T](repr: Pickled, args: Seq[Seq[Any] => Type[_]]): Type[T] = new TastyType[T](repr, args)
def unpickleType[T](repr: Pickled, args: Seq[Seq[Any] => Type[_]]): given QuoteContext => Type[T] = new TastyType[T](repr, args)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just curious, what's the recommended practice to use given: as parameters or contextual function types. Semantically the two are equivalent, and performance-wise they should be almost the same due to the optimization for implicit functions via direct methods.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here the desison was taken to have the symmetry between the quote and splices. The splice takes a contextual function, therefore the quote returns a contextual function. In this particular case, the alignment also helped to implement the quo/splice cancellation.


}
1 change: 1 addition & 0 deletions tests/pos/i4414.scala
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import scala.quoted._

object Test {
given as QuoteContext = ???
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not obvious to me why this is needed, given that all implicits are available and type check, and there are no quotes nor splices.

Copy link
Contributor Author

@nicolasstucki nicolasstucki Jul 31, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The calls to a and b synesize some quoted types '[...], those require a context.


def a[A: Type](): Unit = {
b[Expr[A]]()
Expand Down
10 changes: 3 additions & 7 deletions tests/run-with-compiler/i3947.check
Original file line number Diff line number Diff line change
@@ -1,12 +1,8 @@

scala.Predef.classOf[java.lang.Object].getCanonicalName()
java.lang.Object

scala.Predef.classOf[java.lang.Object].getCanonicalName()
java.lang.Object

scala.Predef.classOf[java.lang.Object].getCanonicalName()
java.lang.Object

scala.Predef.classOf[java.lang.Object].getCanonicalName()
java.lang.Object
java.lang.Object
java.lang.Object
java.lang.Object
17 changes: 9 additions & 8 deletions tests/run-with-compiler/i3947.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,22 @@ import scala.quoted._

object Test {

def main(args: Array[String]): Unit = {
implicit val toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make(getClass.getClassLoader)
def test[T: Type](clazz: java.lang.Class[T]): Unit = run {
implicit val toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make(getClass.getClassLoader)
def main(args: Array[String]): Unit = run {
def test[T: Type](clazz: java.lang.Class[T]) = {
val lclazz = clazz.toExpr
val name = '{ ($lclazz).getCanonicalName }
println()
println(name.show)
'{ println($name) }
}

// classOf[Object]
test(classOf[Object])
test(classOf[Any])
test(classOf[AnyRef])
test(classOf[AnyVal])
'{
${test(classOf[Object])}
${test(classOf[Any])}
${test(classOf[AnyRef])}
${test(classOf[AnyVal])}
}
}

}
7 changes: 2 additions & 5 deletions tests/run-with-compiler/i3947c.check
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@

scala.Predef.classOf[scala.runtime.Null].getCanonicalName()
scala.runtime.Null$

scala.Predef.classOf[scala.runtime.Nothing].getCanonicalName()
scala.runtime.Nothing$

scala.Predef.classOf[java.lang.String].getCanonicalName()
scala.runtime.Null$
scala.runtime.Nothing$
java.lang.String
15 changes: 8 additions & 7 deletions tests/run-with-compiler/i3947c.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,22 @@
import scala.quoted._

object Test {
implicit val toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make(getClass.getClassLoader)

def main(args: Array[String]): Unit = {
implicit val toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make(getClass.getClassLoader)
def test[T: Type](clazz: java.lang.Class[T]): Unit = run {
def main(args: Array[String]): Unit = run {
def test[T: Type](clazz: java.lang.Class[T]) = {
val lclazz = clazz.toExpr
val name = '{ ($lclazz).getCanonicalName }
println()
println(name.show)
'{ println($name) }
}

test(classOf[Null])
test(classOf[Nothing])
'{
${test(classOf[Null])}
${test(classOf[Nothing])}

test(classOf[String])
${test(classOf[String])}
}
}

}
7 changes: 2 additions & 5 deletions tests/run-with-compiler/i3947d.check
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@

scala.Predef.classOf[Foo].getCanonicalName()
Foo

scala.Predef.classOf[Foo#Bar].getCanonicalName()
Foo.Bar

scala.Predef.classOf[Foo.Baz].getCanonicalName()
Foo
Foo.Bar
Foo.Baz
15 changes: 8 additions & 7 deletions tests/run-with-compiler/i3947d.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,21 @@
import scala.quoted._

object Test {
implicit val toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make(getClass.getClassLoader)

def main(args: Array[String]): Unit = {
implicit val toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make(getClass.getClassLoader)
def test[T: Type](clazz: java.lang.Class[T]): Unit = run {
def main(args: Array[String]): Unit = run {
def test[T: Type](clazz: java.lang.Class[T]) = {
val lclazz = clazz.toExpr
val name = '{ ($lclazz).getCanonicalName }
println()
println(name.show)
'{ println($name) }
}

test(classOf[Foo])
test(classOf[Foo#Bar])
test(classOf[Foo.Baz])
'{
${test(classOf[Foo])}
${test(classOf[Foo#Bar])}
${test(classOf[Foo.Baz])}
}
}

}
Expand Down
7 changes: 2 additions & 5 deletions tests/run-with-compiler/i3947d2.check
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@

scala.Predef.classOf[foo.Foo].getCanonicalName()
foo.Foo

scala.Predef.classOf[foo.Foo#Bar].getCanonicalName()
foo.Foo.Bar

scala.Predef.classOf[foo.Foo.Baz].getCanonicalName()
foo.Foo
foo.Foo.Bar
foo.Foo.Baz
15 changes: 8 additions & 7 deletions tests/run-with-compiler/i3947d2.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,21 @@
import scala.quoted._

object Test {
implicit val toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make(getClass.getClassLoader)

def main(args: Array[String]): Unit = {
implicit val toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make(getClass.getClassLoader)
def test[T: Type](clazz: java.lang.Class[T]): Unit = run {
def main(args: Array[String]): Unit = run {
def test[T: Type](clazz: java.lang.Class[T]) = {
val lclazz = clazz.toExpr
val name = '{ ($lclazz).getCanonicalName }
println()
println(name.show)
'{ println($name) }
}

test(classOf[foo.Foo])
test(classOf[foo.Foo#Bar])
test(classOf[foo.Foo.Baz])
'{
${test(classOf[foo.Foo])}
${test(classOf[foo.Foo#Bar])}
${test(classOf[foo.Foo.Baz])}
}
}

}
Expand Down
7 changes: 2 additions & 5 deletions tests/run-with-compiler/i3947e.check
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@

scala.Predef.classOf[java.lang.Object].getCanonicalName()
java.lang.Object

scala.Predef.classOf[scala.Array[Foo]].getCanonicalName()
Foo[]

scala.Predef.classOf[scala.Array[scala.Array[Foo]]].getCanonicalName()
java.lang.Object
Foo[]
Foo[][]
21 changes: 11 additions & 10 deletions tests/run-with-compiler/i3947e.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,27 @@
import scala.quoted._

object Test {
implicit val toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make(getClass.getClassLoader)

def main(args: Array[String]): Unit = {
implicit val toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make(getClass.getClassLoader)
def main(args: Array[String]): Unit = run {

def test[T: Type](clazz: java.lang.Class[T]): Unit = run {
def test[T: Type](clazz: java.lang.Class[T]) = {
val lclazz = clazz.toExpr
val name = '{ ($lclazz).getCanonicalName }
println()
println(name.show)
'{ println($name) }
}

// class Object
test(classOf[Array[_]])
'{
// class Object
${test(classOf[Array[_]])}

// class Array[Foo]
test(classOf[Array[Foo]])
// class Array[Foo]
${test(classOf[Array[Foo]])}

// class Array[Array[Foo]]
test(classOf[Array[Array[Foo]]])
// class Array[Array[Foo]]
${test(classOf[Array[Array[Foo]]])}
}
}

}
Expand Down
10 changes: 3 additions & 7 deletions tests/run-with-compiler/i3947f.check
Original file line number Diff line number Diff line change
@@ -1,12 +1,8 @@

scala.Predef.classOf[scala.Array[java.lang.Object]].getCanonicalName()
java.lang.Object[]

scala.Predef.classOf[scala.Array[java.lang.Object]].getCanonicalName()
java.lang.Object[]

scala.Predef.classOf[scala.Array[java.lang.Object]].getCanonicalName()
java.lang.Object[]

scala.Predef.classOf[scala.Array[java.lang.Object]].getCanonicalName()
java.lang.Object[]
java.lang.Object[]
java.lang.Object[]
java.lang.Object[]
18 changes: 10 additions & 8 deletions tests/run-with-compiler/i3947f.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,23 @@ import scala.quoted._

object Test {

def main(args: Array[String]): Unit = {
implicit val toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make(getClass.getClassLoader)
def test[T: Type](clazz: java.lang.Class[T]): Unit = run {
implicit val toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make(getClass.getClassLoader)

def main(args: Array[String]): Unit = run {
def test[T: Type](clazz: java.lang.Class[T]) = {
val lclazz = clazz.toExpr
val name = '{ ($lclazz).getCanonicalName }
println()
println(name.show)
'{ println($name) }
}

// class Array[Object]
test(classOf[Array[Any]])
test(classOf[Array[AnyVal]])
test(classOf[Array[AnyRef]])
test(classOf[Array[Object]])
'{
${test(classOf[Array[Any]])}
${test(classOf[Array[AnyVal]])}
${test(classOf[Array[AnyRef]])}
${test(classOf[Array[Object]])}
}
}

}
Expand Down
10 changes: 3 additions & 7 deletions tests/run-with-compiler/i3947g.check
Original file line number Diff line number Diff line change
@@ -1,12 +1,8 @@

scala.Predef.classOf[scala.Array[scala.Boolean]].getCanonicalName()
boolean[]

scala.Predef.classOf[scala.Array[scala.Byte]].getCanonicalName()
byte[]

scala.Predef.classOf[scala.Array[scala.Char]].getCanonicalName()
char[]

scala.Predef.classOf[scala.Array[scala.Short]].getCanonicalName()
boolean[]
byte[]
char[]
short[]
18 changes: 9 additions & 9 deletions tests/run-with-compiler/i3947g.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,22 @@
import scala.quoted._

object Test {

def main(args: Array[String]): Unit = {
implicit val toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make(getClass.getClassLoader)
def test[T: Type](clazz: java.lang.Class[T]): Unit = run {
implicit val toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make(getClass.getClassLoader)
def main(args: Array[String]): Unit = run {
def test[T: Type](clazz: java.lang.Class[T]) = {
val lclazz = clazz.toExpr
val name = '{ ($lclazz).getCanonicalName }
println()
println(name.show)
'{ println($name) }
}

// primitive arrays
test(classOf[Array[Boolean]])
test(classOf[Array[Byte]])
test(classOf[Array[Char]])
test(classOf[Array[Short]])
'{
${test(classOf[Array[Boolean]])}
${test(classOf[Array[Byte]])}
${test(classOf[Array[Char]])}
${test(classOf[Array[Short]])}
}
}

}
10 changes: 3 additions & 7 deletions tests/run-with-compiler/i3947i.check
Original file line number Diff line number Diff line change
@@ -1,12 +1,8 @@

scala.Predef.classOf[scala.Array[scala.Int]].getCanonicalName()
int[]

scala.Predef.classOf[scala.Array[scala.Long]].getCanonicalName()
long[]

scala.Predef.classOf[scala.Array[scala.Float]].getCanonicalName()
float[]

scala.Predef.classOf[scala.Array[scala.Double]].getCanonicalName()
int[]
long[]
float[]
double[]
17 changes: 9 additions & 8 deletions tests/run-with-compiler/i3947i.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,23 @@
import scala.quoted._

object Test {
implicit val toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make(getClass.getClassLoader)

def main(args: Array[String]): Unit = {
implicit val toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make(getClass.getClassLoader)
def test[T: Type](clazz: java.lang.Class[T]): Unit = run {
def main(args: Array[String]): Unit = run {
def test[T: Type](clazz: java.lang.Class[T]) = {
val lclazz = clazz.toExpr
val name = '{ ($lclazz).getCanonicalName }
println()
println(name.show)
'{ println($name) }
}

// primitive arrays
test(classOf[Array[Int]])
test(classOf[Array[Long]])
test(classOf[Array[Float]])
test(classOf[Array[Double]])
'{
${test(classOf[Array[Int]])}
${test(classOf[Array[Long]])}
${test(classOf[Array[Float]])}
${test(classOf[Array[Double]])}
}
}

}
Loading