summaryrefslogtreecommitdiff
path: root/src/compiler
diff options
context:
space:
mode:
authorEugene Burmako <xeno.by@gmail.com>2013-12-03 13:53:25 +0000
committerEugene Burmako <xeno.by@gmail.com>2013-12-03 14:17:44 +0000
commit1d3ec4e708154ec05554f540d7d68ed55dc12426 (patch)
tree5e6d805791d042760ca0c16f0de1b5b5340e47b1 /src/compiler
parent6ff3c3fd6a238391d0c82599e25731c708bf0e03 (diff)
downloadscala-1d3ec4e708154ec05554f540d7d68ed55dc12426.tar.gz
scala-1d3ec4e708154ec05554f540d7d68ed55dc12426.tar.bz2
scala-1d3ec4e708154ec05554f540d7d68ed55dc12426.zip
better error messages for various macro definition errors
Diffstat (limited to 'src/compiler')
-rw-r--r--src/compiler/scala/reflect/macros/compiler/Errors.scala30
-rw-r--r--src/compiler/scala/reflect/macros/compiler/Validators.scala6
2 files changed, 26 insertions, 10 deletions
diff --git a/src/compiler/scala/reflect/macros/compiler/Errors.scala b/src/compiler/scala/reflect/macros/compiler/Errors.scala
index 9799428b40..4c30a9a85c 100644
--- a/src/compiler/scala/reflect/macros/compiler/Errors.scala
+++ b/src/compiler/scala/reflect/macros/compiler/Errors.scala
@@ -10,6 +10,7 @@ trait Errors extends Traces {
import global._
import analyzer._
import definitions._
+ import treeInfo._
import typer.TyperErrorGen._
import typer.infer.InferErrorGen._
private val runDefinitions = currentRun.runDefinitions
@@ -18,22 +19,39 @@ trait Errors extends Traces {
// sanity check errors
- private def implRefError(message: String) = abort(macroDdef.pos, message)
+ private def implRefError(message: String) = {
+ val Applied(culprit, _, _) = macroDdef.rhs
+ abort(culprit.pos, message)
+ }
+
+ private def bundleRefError(message: String) = {
+ val Applied(core, _, _) = macroDdef.rhs
+ val culprit = core match {
+ case Select(Applied(core, _, _), _) => core
+ case _ => core
+ }
+ abort(culprit.pos, message)
+ }
def MacroImplReferenceWrongShapeError() = implRefError(
"macro implementation reference has wrong shape. required:\n"+
"macro [<static object>].<method name>[[<type args>]] or\n" +
"macro [<macro bundle>].<method name>[[<type args>]]")
+ def MacroImplWrongNumberOfTypeArgumentsError() = {
+ val diagnostic = if (macroImpl.typeParams.length > targs.length) "has too few type arguments" else "has too many arguments"
+ implRefError(s"macro implementation reference $diagnostic for " + treeSymTypeMsg(macroImplRef))
+ }
+
def MacroImplNotPublicError() = implRefError("macro implementation must be public")
def MacroImplOverloadedError() = implRefError("macro implementation cannot be overloaded")
- def MacroImplWrongNumberOfTypeArgumentsError() = implRefError(TypedApplyWrongNumberOfTpeParametersErrorMessage(macroImplRef))
+ def MacroImplNonTagImplicitParameters(params: List[Symbol]) = implRefError("macro implementations cannot have implicit parameters other than WeakTypeTag evidences")
- def MacroBundleNonStaticError() = implRefError("macro bundles must be static")
+ def MacroBundleNonStaticError() = bundleRefError("macro bundles must be static")
- def MacroBundleWrongShapeError() = implRefError("macro bundles must be monomorphic traits extending either BlackboxMacro or WhiteboxMacro and not implementing their `val c: BlackboxContext/WhiteboxContext` member")
+ def MacroBundleWrongShapeError() = bundleRefError("macro bundles must be monomorphic traits extending either BlackboxMacro or WhiteboxMacro and not implementing their `val c: BlackboxContext/WhiteboxContext` member")
// compatibility errors
@@ -91,14 +109,12 @@ trait Errors extends Traces {
private def compatibilityError(message: String) =
implRefError(
- "macro implementation has wrong shape:"+
+ "macro implementation has incompatible shape:"+
"\n required: " + showMeth(rparamss, rret, abbreviate = true, untype = false) +
"\n or : " + showMeth(rparamss, rret, abbreviate = true, untype = true) +
"\n found : " + showMeth(aparamss, aret, abbreviate = false, untype = false) +
"\n" + message)
- def MacroImplNonTagImplicitParameters(params: List[Symbol]) = compatibilityError("macro implementations cannot have implicit parameters other than WeakTypeTag evidences")
-
def MacroImplParamssMismatchError() = compatibilityError("number of parameter sections differ")
def MacroImplExtraParamsError(aparams: List[Symbol], rparams: List[Symbol]) = compatibilityError(lengthMsg("value", "found", aparams(rparams.length)))
diff --git a/src/compiler/scala/reflect/macros/compiler/Validators.scala b/src/compiler/scala/reflect/macros/compiler/Validators.scala
index e77c129c51..0a56aa45e3 100644
--- a/src/compiler/scala/reflect/macros/compiler/Validators.scala
+++ b/src/compiler/scala/reflect/macros/compiler/Validators.scala
@@ -21,9 +21,11 @@ trait Validators {
private def sanityCheck() = {
if (!macroImpl.isMethod) MacroImplReferenceWrongShapeError()
+ if (macroImpl.typeParams.length != targs.length) MacroImplWrongNumberOfTypeArgumentsError()
if (!macroImpl.isPublic) MacroImplNotPublicError()
if (macroImpl.isOverloaded) MacroImplOverloadedError()
- if (macroImpl.typeParams.length != targs.length) MacroImplWrongNumberOfTypeArgumentsError()
+ val implicitParams = aparamss.flatten filter (_.isImplicit)
+ if (implicitParams.nonEmpty) MacroImplNonTagImplicitParameters(implicitParams)
val declaredInStaticObject = isImplMethod && (macroImplOwner.isStaticOwner || macroImplOwner.moduleClass.isStaticOwner)
val declaredInTopLevelClass = isImplBundle && macroImplOwner.owner.isPackageClass
if (!declaredInStaticObject && !declaredInTopLevelClass) MacroImplReferenceWrongShapeError()
@@ -35,8 +37,6 @@ trait Validators {
// we only check strict correspondence between value parameterss
// type parameters of macro defs and macro impls don't have to coincide with each other
- val implicitParams = aparamss.flatten filter (_.isImplicit)
- if (implicitParams.nonEmpty) MacroImplNonTagImplicitParameters(implicitParams)
if (aparamss.length != rparamss.length) MacroImplParamssMismatchError()
map2(aparamss, rparamss)((aparams, rparams) => {
if (aparams.length < rparams.length) MacroImplMissingParamsError(aparams, rparams)