diff options
8 files changed, 73 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]) diff --git a/test/files/neg/macro-incompatible-macro-engine.check b/test/files/neg/macro-incompatible-macro-engine.check new file mode 100644 index 0000000000..1d582e5ed6 --- /dev/null +++ b/test/files/neg/macro-incompatible-macro-engine.check @@ -0,0 +1,7 @@ +Test_3.scala:2: error: macro cannot be expanded, because it was compiled by an incompatible macro engine vxxx (implemented in the incompatibleMacroEngine plugin) + Macros.foo + ^ +Test_3.scala:3: error: macro cannot be expanded, because it was compiled by an incompatible macro engine vxxx (implemented in the incompatibleMacroEngine plugin) + Macros.foo + ^ +two errors found diff --git a/test/files/neg/macro-incompatible-macro-engine/Macros_2.flags b/test/files/neg/macro-incompatible-macro-engine/Macros_2.flags new file mode 100644 index 0000000000..966df731d0 --- /dev/null +++ b/test/files/neg/macro-incompatible-macro-engine/Macros_2.flags @@ -0,0 +1 @@ +-Xplugin:.
\ No newline at end of file diff --git a/test/files/neg/macro-incompatible-macro-engine/Macros_2.scala b/test/files/neg/macro-incompatible-macro-engine/Macros_2.scala new file mode 100644 index 0000000000..ad57a3cb36 --- /dev/null +++ b/test/files/neg/macro-incompatible-macro-engine/Macros_2.scala @@ -0,0 +1,7 @@ +import scala.language.experimental.macros +import scala.reflect.macros.BlackboxContext + +object Macros { + def impl(c: BlackboxContext) = c.universe.Literal(c.universe.Constant(())) + def foo: Unit = macro impl +}
\ No newline at end of file diff --git a/test/files/neg/macro-incompatible-macro-engine/Plugin_1.scala b/test/files/neg/macro-incompatible-macro-engine/Plugin_1.scala new file mode 100644 index 0000000000..a450573755 --- /dev/null +++ b/test/files/neg/macro-incompatible-macro-engine/Plugin_1.scala @@ -0,0 +1,35 @@ +package incompatibleMacroEngine + +import scala.tools.nsc.Global +import scala.tools.nsc.plugins.{Plugin => NscPlugin} + +class Plugin(val global: Global) extends NscPlugin { + import global._ + import analyzer._ + + val name = "incompatibleMacroEngine" + val description = "A sample analyzer plugin that crafts a macro impl binding with a non-standard macro engine." + val components = Nil + addMacroPlugin(MacroPlugin) + + object MacroPlugin extends MacroPlugin { + def fixupBinding(tree: Tree) = new Transformer { + override def transform(tree: Tree) = { + tree match { + case Literal(const @ Constant(x)) if tree.tpe == null => tree setType ConstantType(const) + case _ if tree.tpe == null => tree setType NoType + case _ => ; + } + super.transform(tree) + } + }.transform(tree) + + override def pluginsTypedMacroBody(typer: Typer, ddef: DefDef): Option[Tree] = { + val result = typedMacroBody(typer, ddef) + val List(AnnotationInfo(atp, List(Apply(nucleus, _ :: others)), Nil)) = ddef.symbol.annotations + val updatedBinding = Apply(nucleus, Assign(Literal(Constant("macroEngine")), Literal(Constant("vxxx (implemented in the incompatibleMacroEngine plugin)"))) :: others) + ddef.symbol.setAnnotations(List(AnnotationInfo(atp, List(fixupBinding(updatedBinding)), Nil))) + Some(result) + } + } +}
\ No newline at end of file diff --git a/test/files/neg/macro-incompatible-macro-engine/Test_3.scala b/test/files/neg/macro-incompatible-macro-engine/Test_3.scala new file mode 100644 index 0000000000..7e4fae5236 --- /dev/null +++ b/test/files/neg/macro-incompatible-macro-engine/Test_3.scala @@ -0,0 +1,4 @@ +object Test extends App { + Macros.foo + Macros.foo +}
\ No newline at end of file diff --git a/test/files/neg/macro-incompatible-macro-engine/scalac-plugin.xml b/test/files/neg/macro-incompatible-macro-engine/scalac-plugin.xml new file mode 100644 index 0000000000..42b9cdd75d --- /dev/null +++ b/test/files/neg/macro-incompatible-macro-engine/scalac-plugin.xml @@ -0,0 +1,4 @@ +<plugin> + <name>incompatible-macro-engine</name> + <classname>incompatibleMacroEngine.Plugin</classname> +</plugin>
\ No newline at end of file |