From da1032caa4ee4c780b5fff3056dd816623a53737 Mon Sep 17 00:00:00 2001 From: Eugene Burmako Date: Fri, 21 Feb 2014 22:18:09 +0100 Subject: prohibits polymorphic bundles It's not like they were inducing bugs, but I can't see how polymorphism can be useful for macro bundles, hence imho it's better to reduce the number of degrees of freedom of the system. --- .../scala/reflect/macros/compiler/Errors.scala | 2 +- .../scala/reflect/internal/Definitions.scala | 3 +- test/files/neg/macro-bundle-abstract.check | 2 +- test/files/neg/macro-bundle-overloaded.check | 2 +- test/files/neg/macro-bundle-polymorphic.check | 19 ++++++++++ test/files/neg/macro-bundle-polymorphic.scala | 43 ++++++++++++++++++++++ 6 files changed, 67 insertions(+), 4 deletions(-) create mode 100644 test/files/neg/macro-bundle-polymorphic.check create mode 100644 test/files/neg/macro-bundle-polymorphic.scala diff --git a/src/compiler/scala/reflect/macros/compiler/Errors.scala b/src/compiler/scala/reflect/macros/compiler/Errors.scala index 490ab3657a..cc4508e696 100644 --- a/src/compiler/scala/reflect/macros/compiler/Errors.scala +++ b/src/compiler/scala/reflect/macros/compiler/Errors.scala @@ -36,7 +36,7 @@ trait Errors extends Traces { def MacroBundleNonStaticError() = bundleRefError("macro bundles must be static") - def MacroBundleWrongShapeError() = bundleRefError("macro bundles must be concrete classes having a single constructor with a `val c: Context` parameter") + def MacroBundleWrongShapeError() = bundleRefError("macro bundles must be concrete monomorphic classes having a single constructor with a `val c: Context` parameter") trait Error { self: MacroImplRefCompiler => diff --git a/src/reflect/scala/reflect/internal/Definitions.scala b/src/reflect/scala/reflect/internal/Definitions.scala index f8f7673530..62e98829b7 100644 --- a/src/reflect/scala/reflect/internal/Definitions.scala +++ b/src/reflect/scala/reflect/internal/Definitions.scala @@ -618,10 +618,11 @@ trait Definitions extends api.StandardDefinitions { macroBundleParamInfo(tp) != NoType def isMacroBundleType(tp: Type) = { + val isMonomorphic = tp.typeSymbol.typeParams.isEmpty val isContextCompatible = macroBundleParamInfo(tp) != NoType val hasSingleConstructor = !tp.declaration(nme.CONSTRUCTOR).isOverloaded val nonAbstract = !tp.erasure.typeSymbol.isAbstractClass - isContextCompatible && hasSingleConstructor && nonAbstract + isMonomorphic && isContextCompatible && hasSingleConstructor && nonAbstract } def isBlackboxMacroBundleType(tp: Type) = { diff --git a/test/files/neg/macro-bundle-abstract.check b/test/files/neg/macro-bundle-abstract.check index 3afd079521..1e51a00d05 100644 --- a/test/files/neg/macro-bundle-abstract.check +++ b/test/files/neg/macro-bundle-abstract.check @@ -1,4 +1,4 @@ -macro-bundle-abstract.scala:10: error: macro bundles must be concrete classes having a single constructor with a `val c: Context` parameter +macro-bundle-abstract.scala:10: error: macro bundles must be concrete monomorphic classes having a single constructor with a `val c: Context` parameter def foo = macro Bundle.impl ^ one error found diff --git a/test/files/neg/macro-bundle-overloaded.check b/test/files/neg/macro-bundle-overloaded.check index fc94ff0000..499068aaa8 100644 --- a/test/files/neg/macro-bundle-overloaded.check +++ b/test/files/neg/macro-bundle-overloaded.check @@ -1,4 +1,4 @@ -macro-bundle-overloaded.scala:11: error: macro bundles must be concrete classes having a single constructor with a `val c: Context` parameter +macro-bundle-overloaded.scala:11: error: macro bundles must be concrete monomorphic classes having a single constructor with a `val c: Context` parameter def foo = macro Bundle.impl ^ one error found diff --git a/test/files/neg/macro-bundle-polymorphic.check b/test/files/neg/macro-bundle-polymorphic.check new file mode 100644 index 0000000000..dc6f540f77 --- /dev/null +++ b/test/files/neg/macro-bundle-polymorphic.check @@ -0,0 +1,19 @@ +macro-bundle-polymorphic.scala:36: error: macro bundles must be concrete monomorphic classes having a single constructor with a `val c: Context` parameter + def black1: Any = macro BlackboxBundle1.impl + ^ +macro-bundle-polymorphic.scala:37: error: not found: value BlackboxBundle2 + def black2: Any = macro BlackboxBundle2.impl + ^ +macro-bundle-polymorphic.scala:38: error: not found: value BlackboxBundle3 + def black3: Any = macro BlackboxBundle3.impl + ^ +macro-bundle-polymorphic.scala:40: error: macro bundles must be concrete monomorphic classes having a single constructor with a `val c: Context` parameter + def white1: Any = macro WhiteboxBundle1.impl + ^ +macro-bundle-polymorphic.scala:41: error: not found: value WhiteboxBundle2 + def white2: Any = macro WhiteboxBundle2.impl + ^ +macro-bundle-polymorphic.scala:42: error: not found: value WhiteboxBundle3 + def white3: Any = macro WhiteboxBundle3.impl + ^ +6 errors found diff --git a/test/files/neg/macro-bundle-polymorphic.scala b/test/files/neg/macro-bundle-polymorphic.scala new file mode 100644 index 0000000000..2ba91aa0c5 --- /dev/null +++ b/test/files/neg/macro-bundle-polymorphic.scala @@ -0,0 +1,43 @@ +import scala.language.experimental.macros +import scala.reflect.macros.blackbox.{Context => BlackboxContext} +import scala.reflect.macros.whitebox.{Context => WhiteboxContext} + +class BlackboxBundle1[T](val c: BlackboxContext) { + import c.universe._ + def impl = q"()" +} + +class BlackboxBundle2[T <: BlackboxContext](val c: T) { + import c.universe._ + def impl = q"()" +} + +class BlackboxBundle3[T <: BlackboxContext, U <: T](val c: U) { + import c.universe._ + def impl = q"()" +} + +class WhiteboxBundle1[T](val c: WhiteboxContext) { + import c.universe._ + def impl = q"()" +} + +class WhiteboxBundle2[T <: WhiteboxContext](val c: T) { + import c.universe._ + def impl = q"()" +} + +class WhiteboxBundle3[T <: WhiteboxContext, U <: T](val c: U) { + import c.universe._ + def impl = q"()" +} + +object Macros { + def black1: Any = macro BlackboxBundle1.impl + def black2: Any = macro BlackboxBundle2.impl + def black3: Any = macro BlackboxBundle3.impl + + def white1: Any = macro WhiteboxBundle1.impl + def white2: Any = macro WhiteboxBundle2.impl + def white3: Any = macro WhiteboxBundle3.impl +} \ No newline at end of file -- cgit v1.2.3