From 64edb44fc6a4db0ba3ecee0555212d8112a17f1a Mon Sep 17 00:00:00 2001 From: Eugene Burmako Date: Fri, 21 Feb 2014 22:24:21 +0100 Subject: more helpful bundle error messages At the moment, bundle selection mechanism is pretty picky. If a candidate bundle's parameter isn't either blackbox.Context, whitebox.Context or PrefixType refinement thereof, then it's not a bundle and the user will get a generic error. However we can be a bit more helpful and admit classes that are almost like bundles (looksLikeMacroBundleType), have them fail isMacroBundleType, and then emit a much prettier error message to the user that would tell them that bundles must be monomorphic and their sole parameter should not just be any subtype of blackbox.Context or whitebox.Context. --- src/reflect/scala/reflect/internal/Definitions.scala | 10 +++++++--- test/files/neg/macro-bundle-polymorphic.check | 8 ++++---- test/files/neg/macro-bundle-wrongcontext-a.check | 2 +- test/files/neg/macro-bundle-wrongcontext-b.check | 2 +- 4 files changed, 13 insertions(+), 9 deletions(-) diff --git a/src/reflect/scala/reflect/internal/Definitions.scala b/src/reflect/scala/reflect/internal/Definitions.scala index 62e98829b7..558e1aa611 100644 --- a/src/reflect/scala/reflect/internal/Definitions.scala +++ b/src/reflect/scala/reflect/internal/Definitions.scala @@ -609,8 +609,12 @@ trait Definitions extends api.StandardDefinitions { private def macroBundleParamInfo(tp: Type) = { val ctor = tp.erasure.typeSymbol.primaryConstructor ctor.paramss match { - case List(List(c)) => if (isMacroContextType(c.info)) c.info else NoType - case _ => NoType + case List(List(c)) => + val sym = c.info.typeSymbol + val isContextCompatible = sym.isNonBottomSubClass(BlackboxContextClass) || sym.isNonBottomSubClass(WhiteboxContextClass) + if (isContextCompatible) c.info else NoType + case _ => + NoType } } @@ -619,7 +623,7 @@ trait Definitions extends api.StandardDefinitions { def isMacroBundleType(tp: Type) = { val isMonomorphic = tp.typeSymbol.typeParams.isEmpty - val isContextCompatible = macroBundleParamInfo(tp) != NoType + val isContextCompatible = isMacroContextType(macroBundleParamInfo(tp)) val hasSingleConstructor = !tp.declaration(nme.CONSTRUCTOR).isOverloaded val nonAbstract = !tp.erasure.typeSymbol.isAbstractClass isMonomorphic && isContextCompatible && hasSingleConstructor && nonAbstract diff --git a/test/files/neg/macro-bundle-polymorphic.check b/test/files/neg/macro-bundle-polymorphic.check index dc6f540f77..60a4d59119 100644 --- a/test/files/neg/macro-bundle-polymorphic.check +++ b/test/files/neg/macro-bundle-polymorphic.check @@ -1,19 +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 +macro-bundle-polymorphic.scala:37: error: macro bundles must be concrete monomorphic classes having a single constructor with a `val c: Context` parameter def black2: Any = macro BlackboxBundle2.impl ^ -macro-bundle-polymorphic.scala:38: error: not found: value BlackboxBundle3 +macro-bundle-polymorphic.scala:38: error: macro bundles must be concrete monomorphic classes having a single constructor with a `val c: Context` parameter 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 +macro-bundle-polymorphic.scala:41: error: macro bundles must be concrete monomorphic classes having a single constructor with a `val c: Context` parameter def white2: Any = macro WhiteboxBundle2.impl ^ -macro-bundle-polymorphic.scala:42: error: not found: value WhiteboxBundle3 +macro-bundle-polymorphic.scala:42: error: macro bundles must be concrete monomorphic classes having a single constructor with a `val c: Context` parameter def white3: Any = macro WhiteboxBundle3.impl ^ 6 errors found diff --git a/test/files/neg/macro-bundle-wrongcontext-a.check b/test/files/neg/macro-bundle-wrongcontext-a.check index 7a48dbfd3a..10aadb0035 100644 --- a/test/files/neg/macro-bundle-wrongcontext-a.check +++ b/test/files/neg/macro-bundle-wrongcontext-a.check @@ -1,4 +1,4 @@ -macro-bundle-wrongcontext-a.scala:12: error: not found: value Bundle +macro-bundle-wrongcontext-a.scala:12: error: macro bundles must be concrete monomorphic classes having a single constructor with a `val c: Context` parameter def foo: Any = macro Bundle.impl ^ one error found diff --git a/test/files/neg/macro-bundle-wrongcontext-b.check b/test/files/neg/macro-bundle-wrongcontext-b.check index 9c94c3bc34..e9700d379e 100644 --- a/test/files/neg/macro-bundle-wrongcontext-b.check +++ b/test/files/neg/macro-bundle-wrongcontext-b.check @@ -1,4 +1,4 @@ -macro-bundle-wrongcontext-b.scala:10: error: not found: value Bundle +macro-bundle-wrongcontext-b.scala:10: error: macro bundles must be concrete monomorphic classes having a single constructor with a `val c: Context` parameter def foo: Any = macro Bundle.impl ^ one error found -- cgit v1.2.3