summaryrefslogtreecommitdiff
path: root/src/compiler/scala
diff options
context:
space:
mode:
authorEugene Burmako <xeno.by@gmail.com>2013-12-07 15:20:47 +0100
committerEugene Burmako <xeno.by@gmail.com>2013-12-30 19:07:05 +0300
commit0019bc2c4b7d89b61c71f18177823afdcd27bb78 (patch)
tree26cc6229d3c818a2d56f1603dcef2e3fea658439 /src/compiler/scala
parent68b8e23585b5bbf7ff40d585634a7f07680c278b (diff)
downloadscala-0019bc2c4b7d89b61c71f18177823afdcd27bb78.tar.gz
scala-0019bc2c4b7d89b61c71f18177823afdcd27bb78.tar.bz2
scala-0019bc2c4b7d89b61c71f18177823afdcd27bb78.zip
humane reporting of macro impl binding version errors
Macro defs are linked to macro impls by the virtue of MacroImplBinding structures that are persisted between compilation runs serialized within instances of macroImpl annotations. Along with the evolution of our macro engine, we sometimes have to evolve the format of MacroImplBinding, which means that it has to be versioned. Version mismatches are checked upon every macro expansion, ensuring that macros that we expand were compiled with exactly the same version of the macro engine that we’re running. That’s all really cool apart from the fact that version mismatches result in aborting the entire compilation with an obscure message without giving a hint about the culprits. This commit improves the situation by providing pretty per-expansion compilation errors that tell the programmer what macro expansions are at fault and what macro engines were used to compile them.
Diffstat (limited to 'src/compiler/scala')
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala5
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Macros.scala21
2 files changed, 15 insertions, 11 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala
index 719d04a7f9..352ae6c8b0 100644
--- a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala
@@ -730,6 +730,11 @@ trait ContextErrors {
issueNormalTypeError(expandee, s"macro in $role role can only expand into $allowedExpansions")
}
+ def MacroIncompatibleEngineError(macroEngine: String) = {
+ val message = s"macro cannot be expanded, because it was compiled by an incompatible macro engine $macroEngine"
+ issueNormalTypeError(lastTreeToTyper, message)
+ }
+
case object MacroExpansionException extends Exception with scala.util.control.ControlThrowable
protected def macroExpansionError(expandee: Tree, msg: String, pos: Position = NoPosition) = {
diff --git a/src/compiler/scala/tools/nsc/typechecker/Macros.scala b/src/compiler/scala/tools/nsc/typechecker/Macros.scala
index 72783a3a61..105e975c86 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Macros.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Macros.scala
@@ -123,16 +123,15 @@ trait Macros extends FastTrack with MacroRuntimes with Traces with Helpers {
*
* @scala.reflect.macros.internal.macroImpl(
* `macro`(
+ * "macroEngine" = <current macro engine>,
* "isBundle" = false,
* "isBlackbox" = true,
* "signature" = List(Other),
* "methodName" = "impl",
- * "versionFormat" = <current version format>,
* "className" = "Macros$"))
*/
+ def macroEngine = "v7.0 (implemented in Scala 2.11.0-M8)"
object MacroImplBinding {
- val versionFormat = 6.0
-
def pickleAtom(obj: Any): Tree =
obj match {
case list: List[_] => Apply(Ident(ListModule), list map pickleAtom)
@@ -183,12 +182,12 @@ trait Macros extends FastTrack with MacroRuntimes with Traces with Helpers {
}
val payload = List[(String, Any)](
- "versionFormat" -> versionFormat,
- "isBundle" -> isBundle,
- "isBlackbox" -> isBlackbox,
- "className" -> className,
- "methodName" -> macroImpl.name.toString,
- "signature" -> signature
+ "macroEngine" -> macroEngine,
+ "isBundle" -> isBundle,
+ "isBlackbox" -> isBlackbox,
+ "className" -> className,
+ "methodName" -> macroImpl.name.toString,
+ "signature" -> signature
)
// the shape of the nucleus is chosen arbitrarily. it doesn't carry any payload.
@@ -237,8 +236,8 @@ trait Macros extends FastTrack with MacroRuntimes with Traces with Helpers {
raw.asInstanceOf[T]
}
- val pickleVersionFormat = unpickle("versionFormat", classOf[Double])
- if (versionFormat != pickleVersionFormat) fail(s"expected version format $versionFormat, actual $pickleVersionFormat")
+ val macroEngine = unpickle("macroEngine", classOf[String])
+ if (self.macroEngine != macroEngine) typer.TyperErrorGen.MacroIncompatibleEngineError(macroEngine)
val isBundle = unpickle("isBundle", classOf[Boolean])
val isBlackbox = unpickle("isBlackbox", classOf[Boolean])