summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/compiler/scala/reflect/reify/codegen/GenUtils.scala4
-rw-r--r--src/compiler/scala/reflect/reify/phases/Reshape.scala26
-rw-r--r--src/reflect/scala/reflect/api/TypeTags.scala16
-rw-r--r--src/reflect/scala/reflect/internal/StdNames.scala2
-rw-r--r--src/reflect/scala/reflect/macros/Aliases.scala12
-rw-r--r--test/files/run/reify_typeof.check10
-rw-r--r--test/files/run/reify_typeof.scala14
-rw-r--r--test/files/run/typetags_typeof_x.check8
-rw-r--r--test/files/run/typetags_typeof_x.scala14
9 files changed, 101 insertions, 5 deletions
diff --git a/src/compiler/scala/reflect/reify/codegen/GenUtils.scala b/src/compiler/scala/reflect/reify/codegen/GenUtils.scala
index de9fec0df5..4512b2cb6f 100644
--- a/src/compiler/scala/reflect/reify/codegen/GenUtils.scala
+++ b/src/compiler/scala/reflect/reify/codegen/GenUtils.scala
@@ -5,6 +5,10 @@ trait GenUtils {
self: Reifier =>
import global._
+ import treeInfo._
+ import definitions._
+ private val runDefinitions = currentRun.runDefinitions
+ import runDefinitions._
def reifyList(xs: List[Any]): Tree =
mkList(xs map reify)
diff --git a/src/compiler/scala/reflect/reify/phases/Reshape.scala b/src/compiler/scala/reflect/reify/phases/Reshape.scala
index 6c073c0b4c..9a54632796 100644
--- a/src/compiler/scala/reflect/reify/phases/Reshape.scala
+++ b/src/compiler/scala/reflect/reify/phases/Reshape.scala
@@ -78,7 +78,7 @@ trait Reshape {
super.transform(preTyper)
}
- private def undoMacroExpansion(tree: Tree): Tree =
+ private def undoMacroExpansion(tree: Tree): Tree = {
tree.attachments.get[analyzer.MacroExpansionAttachment] match {
case Some(analyzer.MacroExpansionAttachment(original, _)) =>
def mkImplicitly(tp: Type) = atPos(tree.pos)(
@@ -96,8 +96,30 @@ trait Reshape {
case Apply(TypeApply(_, List(tt)), List(pre)) if sym == materializeTypeTag => mkImplicitly(typeRef(pre.tpe, TypeTagClass, List(tt.tpe)))
case _ => original
}
- case _ => tree
+ case None =>
+ // `typeOf[T]` calls get translated into `typeOf[T](Predef.implicitly)` by Reshape
+ // unfortunately, this doesn't work well with the recently introduced `def typeOf[T: TypeTag](x: T)` overload
+ // somehow the typechecker is now longer able to make sense of targless implicitly failing with:
+ // ambiguous implicit values:
+ // both value StringCanBuildFrom in object Predef of type => scala.collection.generic.CanBuildFrom[String,Char,String]
+ // and method conforms in object Predef of type [A]=> <:<[A,A]
+ // match expected type T
+ // could not find implicit value for parameter e: T
+ // overloaded method value typeOf with alternatives:
+ // (x: => List[Int])(implicit evidence$2: ru.TypeTag[List[Int]])ru.Type <and>
+ // (implicit ttag: ru.TypeTag[List[Int]])ru.Type
+ // cannot be applied to (Unit)
+ // therefore here we give the calls to `weakTypeOf` and `typeOf` a bit of extra helping
+ // erasing synthetic implicit arguments altogether, so that this weird tree shape doesn't appear in the reifee in the first place
+ def isTypeOf(sym: Symbol): Boolean = {
+ sym != null && (sym.name == nme.typeOf || sym.name == nme.weakTypeOf) && sym.owner == TypeTagsClass
+ }
+ tree match {
+ case Apply(fun, args) if !tree.tpe.isInstanceOf[MethodType] && isTypeOf(fun.symbol) => fun
+ case _ => tree
+ }
}
+ }
override def transformModifiers(mods: Modifiers) = {
val mods1 = toPreTyperModifiers(mods, currentSymbol)
diff --git a/src/reflect/scala/reflect/api/TypeTags.scala b/src/reflect/scala/reflect/api/TypeTags.scala
index be76758224..d6af68f923 100644
--- a/src/reflect/scala/reflect/api/TypeTags.scala
+++ b/src/reflect/scala/reflect/api/TypeTags.scala
@@ -326,13 +326,25 @@ trait TypeTags { self: Universe =>
* Shortcut for `implicitly[WeakTypeTag[T]].tpe`
* @group TypeTags
*/
- def weakTypeOf[T](implicit attag: WeakTypeTag[T]): Type = attag.tpe
+ def weakTypeOf[T](implicit attag: WeakTypeTag[T]): Type = if (attag != null) attag.tpe else typeOf[Null]
+
+ /**
+ * Type of `x` as derived from a weak type tag.
+ * @group TypeTags
+ */
+ def weakTypeOf[T: WeakTypeTag](x: => T): Type = weakTypeOf[T]
/**
* Shortcut for `implicitly[TypeTag[T]].tpe`
* @group TypeTags
*/
- def typeOf[T](implicit ttag: TypeTag[T]): Type = ttag.tpe
+ def typeOf[T](implicit ttag: TypeTag[T]): Type = if (ttag != null) ttag.tpe else typeOf[Null]
+
+ /**
+ * Type of `x` as derived from a type tag.
+ * @group TypeTags
+ */
+ def typeOf[T: TypeTag](x: => T): Type = typeOf[T]
}
private[scala] class SerializedTypeTag(var tpec: TypeCreator, var concrete: Boolean) extends Serializable {
diff --git a/src/reflect/scala/reflect/internal/StdNames.scala b/src/reflect/scala/reflect/internal/StdNames.scala
index 679186f938..71c4009a62 100644
--- a/src/reflect/scala/reflect/internal/StdNames.scala
+++ b/src/reflect/scala/reflect/internal/StdNames.scala
@@ -768,6 +768,7 @@ trait StdNames {
val tree : NameType = "tree"
val true_ : NameType = "true"
val typedProductIterator: NameType = "typedProductIterator"
+ val typeOf: NameType = "typeOf"
val TypeName: NameType = "TypeName"
val typeTagToManifest: NameType = "typeTagToManifest"
val unapply: NameType = "unapply"
@@ -782,6 +783,7 @@ trait StdNames {
val valueOf : NameType = "valueOf"
val values : NameType = "values"
val wait_ : NameType = "wait"
+ val weakTypeOf: NameType = "weakTypeOf"
val withFilter: NameType = "withFilter"
val zero: NameType = "zero"
diff --git a/src/reflect/scala/reflect/macros/Aliases.scala b/src/reflect/scala/reflect/macros/Aliases.scala
index d2b878d081..8651661c63 100644
--- a/src/reflect/scala/reflect/macros/Aliases.scala
+++ b/src/reflect/scala/reflect/macros/Aliases.scala
@@ -110,10 +110,20 @@ trait Aliases {
/**
* Shortcut for `implicitly[WeakTypeTag[T]].tpe`
*/
- def weakTypeOf[T](implicit attag: WeakTypeTag[T]): Type = attag.tpe
+ def weakTypeOf[T](implicit attag: WeakTypeTag[T]): Type = if (attag != null) attag.tpe else typeOf[Null]
+
+ /**
+ * Type of `x` as derived from a weak type tag.
+ */
+ def weakTypeOf[T: WeakTypeTag](x: => T): Type = weakTypeOf[T]
/**
* Shortcut for `implicitly[TypeTag[T]].tpe`
*/
def typeOf[T](implicit ttag: TypeTag[T]): Type = ttag.tpe
+
+ /**
+ * Type of `x` as derived from a type tag.
+ */
+ def typeOf[T: TypeTag](x: => T): Type = typeOf[T]
}
diff --git a/test/files/run/reify_typeof.check b/test/files/run/reify_typeof.check
new file mode 100644
index 0000000000..670f76faa4
--- /dev/null
+++ b/test/files/run/reify_typeof.check
@@ -0,0 +1,10 @@
+Expr[Unit]({
+ val ru = `package`.universe;
+ val tpe1: ru.Type = ru.typeOf[`package`.List[Int]];
+ Predef.println(tpe1);
+ val tpe2: ru.Type = ru.typeOf(List.apply(1, 2, 3));
+ Predef.println(tpe2)
+})
+scala.List[Int]
+List[Int]
+()
diff --git a/test/files/run/reify_typeof.scala b/test/files/run/reify_typeof.scala
new file mode 100644
index 0000000000..985c57b9ab
--- /dev/null
+++ b/test/files/run/reify_typeof.scala
@@ -0,0 +1,14 @@
+import scala.reflect.runtime.universe._
+import scala.tools.reflect.Eval
+
+object Test extends App {
+ val reified = reify {
+ val ru = scala.reflect.runtime.universe
+ val tpe1: ru.Type = ru.typeOf[List[Int]]
+ println(tpe1)
+ val tpe2: ru.Type = ru.typeOf(List(1, 2, 3))
+ println(tpe2)
+ }
+ println(reified)
+ println(reified.eval)
+} \ No newline at end of file
diff --git a/test/files/run/typetags_typeof_x.check b/test/files/run/typetags_typeof_x.check
new file mode 100644
index 0000000000..832a8bc63c
--- /dev/null
+++ b/test/files/run/typetags_typeof_x.check
@@ -0,0 +1,8 @@
+List[T]
+C
+Int
+List[Any]
+AnyRef{def x: Int}
+Null
+Nothing
+Null
diff --git a/test/files/run/typetags_typeof_x.scala b/test/files/run/typetags_typeof_x.scala
new file mode 100644
index 0000000000..08be6d4527
--- /dev/null
+++ b/test/files/run/typetags_typeof_x.scala
@@ -0,0 +1,14 @@
+import scala.reflect.runtime.universe._
+
+object Test extends App {
+ def foo[T](x: T) = weakTypeOf(List(x))
+ println(foo(2))
+ locally { class C; println(weakTypeOf(new C)) }
+
+ println(typeOf(2))
+ println(typeOf(List(1, "1")))
+ println(typeOf(new { def x = 2 }))
+ println(typeOf[Null])
+ println(typeOf[Nothing])
+ println(typeOf(null))
+} \ No newline at end of file