summaryrefslogtreecommitdiff
path: root/src/compiler/scala/reflect/macros
diff options
context:
space:
mode:
authorEugene Burmako <xeno.by@gmail.com>2013-12-08 16:28:41 +0100
committerEugene Burmako <xeno.by@gmail.com>2013-12-10 10:29:02 +0100
commit87979ad96f3a07354be4c15cdf35f71d1d4739cb (patch)
treeaca34d4bec9a31a44c1a81d18a4701ef8ceb4231 /src/compiler/scala/reflect/macros
parent75cc6cf256df9e152eaec771121ce0db9f7039f8 (diff)
downloadscala-87979ad96f3a07354be4c15cdf35f71d1d4739cb.tar.gz
scala-87979ad96f3a07354be4c15cdf35f71d1d4739cb.tar.bz2
scala-87979ad96f3a07354be4c15cdf35f71d1d4739cb.zip
deprecates macro def return type inference
With the new focus on quasiquotes in macro implementations, we now have to change the way how inference of macro def return types works. Previously, if the return type of a macro def wasn’t specified, we looked into the signature of its macro impl, took its return type (which could only be c.Expr[T]) and then assigned T to be the return type of the macro def. We also had a convenient special case which inferred Any in case when the body of the macro impl wasn’t an expr. That avoided reporting spurious errors if the macro impl had its body typed incorrectly (because in that case we would report a def/impl signature mismatch anyway) and also provided a convenience by letting macro impls end with `???`. However now we also allow macro impls to return c.Tree, which means that we are no longer able to do any meaningful type inference, because c.Tree could correspond to tree of any type. Unfortunately, when coupled with the type inference special case described above, this means that the users who migrate from exprs to quasiquotes are going to face an unpleasant surprise. If they haven’t provided explicit return types for their macro defs, those types are going to be silently inferred as `Any`! This commit plugs this loophole by prohibiting type inference from non-expr return types of macro impls (not counting Nothing). Moreover, it also deprecates c.Expr[T] => T inference in order to avoid confusion when switching between exprs and quasiquotes.
Diffstat (limited to 'src/compiler/scala/reflect/macros')
-rw-r--r--src/compiler/scala/reflect/macros/compiler/Validators.scala2
-rw-r--r--src/compiler/scala/reflect/macros/util/Helpers.scala8
2 files changed, 7 insertions, 3 deletions
diff --git a/src/compiler/scala/reflect/macros/compiler/Validators.scala b/src/compiler/scala/reflect/macros/compiler/Validators.scala
index 0a56aa45e3..5936b52890 100644
--- a/src/compiler/scala/reflect/macros/compiler/Validators.scala
+++ b/src/compiler/scala/reflect/macros/compiler/Validators.scala
@@ -155,7 +155,7 @@ trait Validators {
else mmap(macroDdef.vparamss)(param)
val macroDefRet =
if (!macroDdef.tpt.isEmpty) typer.typedType(macroDdef.tpt).tpe
- else computeMacroDefTypeFromMacroImplRef(macroDdef, macroImplRef)
+ else computeMacroDefTypeFromMacroImplRef(macroDdef, macroImplRef) orElse AnyTpe
val implReturnType = sigma(increaseMetalevel(ctxPrefix, macroDefRet))
object SigmaTypeMap extends TypeMap {
diff --git a/src/compiler/scala/reflect/macros/util/Helpers.scala b/src/compiler/scala/reflect/macros/util/Helpers.scala
index ff03696524..bddc42d1f9 100644
--- a/src/compiler/scala/reflect/macros/util/Helpers.scala
+++ b/src/compiler/scala/reflect/macros/util/Helpers.scala
@@ -77,7 +77,8 @@ trait Helpers {
/** Decreases metalevel of the type, i.e. transforms:
* * c.Expr[T] to T
- * * Anything else to Any
+ * * Nothing to Nothing
+ * * Anything else to NoType
*
* @see Metalevels.scala for more information and examples about metalevels
*/
@@ -86,7 +87,10 @@ trait Helpers {
import runDefinitions._
transparentShallowTransform(RepeatedParamClass, tp) {
case ExprClassOf(runtimeType) => runtimeType
- case _ => AnyTpe // so that macro impls with rhs = ??? don't screw up our inference
+ // special-casing Nothing here is a useful convention
+ // that enables no-hassle prototyping with `macro ???` and `macro { ...; ??? }`
+ case nothing if nothing =:= NothingTpe => NothingTpe
+ case _ => NoType
}
}
}