summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEugene Burmako <xeno.by@gmail.com>2014-02-21 22:24:21 +0100
committerEugene Burmako <xeno.by@gmail.com>2014-02-21 22:24:32 +0100
commit64edb44fc6a4db0ba3ecee0555212d8112a17f1a (patch)
tree908712ca8bb1a03820fa0b6e1a407e6f34fc7bc3
parentda1032caa4ee4c780b5fff3056dd816623a53737 (diff)
downloadscala-64edb44fc6a4db0ba3ecee0555212d8112a17f1a.tar.gz
scala-64edb44fc6a4db0ba3ecee0555212d8112a17f1a.tar.bz2
scala-64edb44fc6a4db0ba3ecee0555212d8112a17f1a.zip
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.
-rw-r--r--src/reflect/scala/reflect/internal/Definitions.scala10
-rw-r--r--test/files/neg/macro-bundle-polymorphic.check8
-rw-r--r--test/files/neg/macro-bundle-wrongcontext-a.check2
-rw-r--r--test/files/neg/macro-bundle-wrongcontext-b.check2
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