diff options
-rw-r--r-- | src/compiler/scala/reflect/macros/compiler/Errors.scala | 4 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala | 11 | ||||
-rw-r--r-- | src/reflect/scala/reflect/internal/Definitions.scala | 6 | ||||
-rw-r--r-- | test/files/neg/macro-quasiquotes.check | 7 | ||||
-rw-r--r-- | test/files/neg/macro-quasiquotes/Macros_1.scala | 15 | ||||
-rw-r--r-- | test/files/neg/macro-quasiquotes/Test_2.scala | 5 | ||||
-rw-r--r-- | test/files/run/macro-quasiquotes.check | 4 | ||||
-rw-r--r-- | test/files/run/macro-quasiquotes/Macros_1.scala | 15 | ||||
-rw-r--r-- | test/files/run/macro-quasiquotes/Test_2.scala | 5 |
9 files changed, 62 insertions, 10 deletions
diff --git a/src/compiler/scala/reflect/macros/compiler/Errors.scala b/src/compiler/scala/reflect/macros/compiler/Errors.scala index dd3142127e..a60a2c2306 100644 --- a/src/compiler/scala/reflect/macros/compiler/Errors.scala +++ b/src/compiler/scala/reflect/macros/compiler/Errors.scala @@ -60,8 +60,8 @@ trait Errors extends Traces { (rtpe, atpe) match { case _ if rtpe eq atpe => success() case (TypeRef(_, RepeatedParamClass, rtpe :: Nil), TypeRef(_, RepeatedParamClass, atpe :: Nil)) => check(rtpe, atpe) - case (ExprClassOf(_), TreeType()) => success() - case (TreeType(), ExprClassOf(_)) => success() + case (ExprClassOf(_), TreeType()) if rtpe.prefix =:= atpe.prefix => success() + case (SubtreeType(), ExprClassOf(_)) if rtpe.prefix =:= atpe.prefix => success() case _ => rtpe <:< atpe } } diff --git a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala index f2a77b4333..81f5545695 100644 --- a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala +++ b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala @@ -697,7 +697,7 @@ trait ContextErrors { protected def macroExpansionError(expandee: Tree, msg: String, pos: Position = NoPosition) = { def msgForLog = if (msg != null && (msg contains "exception during macro expansion")) msg.split(EOL).drop(1).headOption.getOrElse("?") else msg macroLogLite("macro expansion has failed: %s".format(msgForLog)) - if (msg != null) context.error(pos, msg) // issueTypeError(PosAndMsgTypeError(..)) won't work => swallows positions + if (msg != null) context.error(if (pos.isDefined) pos else expandee.pos, msg) // issueTypeError(PosAndMsgTypeError(..)) won't work => swallows positions setError(expandee) throw MacroExpansionException } @@ -782,13 +782,16 @@ trait ContextErrors { } def MacroExpansionHasInvalidTypeError(expandee: Tree, expanded: Any) = { + def isUnaffiliatedExpr = expanded.isInstanceOf[scala.reflect.api.Exprs#Expr[_]] + def isUnaffiliatedTree = expanded.isInstanceOf[scala.reflect.api.Trees#TreeApi] val expected = "expr or tree" - val isPathMismatch = expanded != null && expanded.isInstanceOf[scala.reflect.api.Exprs#Expr[_]] + val actual = if (isUnaffiliatedExpr) "an expr" else if (isUnaffiliatedTree) "a tree" else "unexpected" + val isPathMismatch = expanded != null && (isUnaffiliatedExpr || isUnaffiliatedTree) macroExpansionError(expandee, s"macro must return a compiler-specific $expected; returned value is " + ( if (expanded == null) "null" - else if (isPathMismatch) s" $expected, but it doesn't belong to this compiler" - else " of " + expanded.getClass + else if (isPathMismatch) s"$actual, but it doesn't belong to this compiler's universe" + else "of " + expanded.getClass )) } diff --git a/src/reflect/scala/reflect/internal/Definitions.scala b/src/reflect/scala/reflect/internal/Definitions.scala index d3b9c38ee1..6a9fa9a884 100644 --- a/src/reflect/scala/reflect/internal/Definitions.scala +++ b/src/reflect/scala/reflect/internal/Definitions.scala @@ -492,10 +492,8 @@ trait Definitions extends api.StandardDefinitions { lazy val TreesClass = getClassIfDefined("scala.reflect.api.Trees") // defined in scala-reflect.jar, so we need to be careful lazy val TreesTreeType = TreesClass.map(sym => getTypeMember(sym, tpnme.Tree)) - object TreeType { - def unapply(tpe: Type): Boolean = unapply(tpe.typeSymbol) - def unapply(sym: Symbol): Boolean = sym.overrideChain contains TreesTreeType - } + object TreeType { def unapply(tpe: Type): Boolean = tpe.typeSymbol.overrideChain contains TreesTreeType } + object SubtreeType { def unapply(tpe: Type): Boolean = tpe.typeSymbol.overrideChain exists (_.tpe <:< TreesTreeType.tpe) } lazy val ExprsClass = getClassIfDefined("scala.reflect.api.Exprs") // defined in scala-reflect.jar, so we need to be careful lazy val ExprClass = ExprsClass.map(sym => getMemberClass(sym, tpnme.Expr)) diff --git a/test/files/neg/macro-quasiquotes.check b/test/files/neg/macro-quasiquotes.check new file mode 100644 index 0000000000..a2d48723b5 --- /dev/null +++ b/test/files/neg/macro-quasiquotes.check @@ -0,0 +1,7 @@ +Macros_1.scala:14: error: macro implementation has wrong shape: + required: (x: Impls.this.c.Expr[Int]): Impls.this.c.Expr[Any] + found : (x: Impls.this.c.universe.Block): Impls.this.c.universe.Apply +type mismatch for parameter x: Impls.this.c.Expr[Int] does not conform to Impls.this.c.universe.Block + def m3(x: Int) = macro Impls.impl3 + ^ +one error found diff --git a/test/files/neg/macro-quasiquotes/Macros_1.scala b/test/files/neg/macro-quasiquotes/Macros_1.scala new file mode 100644 index 0000000000..17c1034720 --- /dev/null +++ b/test/files/neg/macro-quasiquotes/Macros_1.scala @@ -0,0 +1,15 @@ +import language.experimental.macros +import scala.reflect.macros.Macro + +trait Impls extends Macro { + import c.universe._ + def impl1(x: Expr[Int]) = q"println(x)" + def impl2(x: Tree) = q"println(x)" + def impl3(x: Block) = q"println(x)" +} + +object Macros { + def m1(x: Int) = macro Impls.impl1 + def m2(x: Int) = macro Impls.impl2 + def m3(x: Int) = macro Impls.impl3 +}
\ No newline at end of file diff --git a/test/files/neg/macro-quasiquotes/Test_2.scala b/test/files/neg/macro-quasiquotes/Test_2.scala new file mode 100644 index 0000000000..c7b8948d79 --- /dev/null +++ b/test/files/neg/macro-quasiquotes/Test_2.scala @@ -0,0 +1,5 @@ +object Test extends App { + Macros.m1 + Macros.m2 + Macros.m3 +} diff --git a/test/files/run/macro-quasiquotes.check b/test/files/run/macro-quasiquotes.check new file mode 100644 index 0000000000..94ebaf9001 --- /dev/null +++ b/test/files/run/macro-quasiquotes.check @@ -0,0 +1,4 @@ +1 +2 +3 +4 diff --git a/test/files/run/macro-quasiquotes/Macros_1.scala b/test/files/run/macro-quasiquotes/Macros_1.scala new file mode 100644 index 0000000000..b64eec8743 --- /dev/null +++ b/test/files/run/macro-quasiquotes/Macros_1.scala @@ -0,0 +1,15 @@ +import language.experimental.macros +import scala.reflect.macros.Macro + +trait Impls extends Macro { + import c.universe._ + def impl1 = q"println(1)" + def impl2 = q"{ println(2); println(3) }" + def impl3 = q"4" +} + +object Macros { + def m1 = macro Impls.impl1 + def m2 = macro Impls.impl2 + def m3 = macro Impls.impl3 +}
\ No newline at end of file diff --git a/test/files/run/macro-quasiquotes/Test_2.scala b/test/files/run/macro-quasiquotes/Test_2.scala new file mode 100644 index 0000000000..4be193938f --- /dev/null +++ b/test/files/run/macro-quasiquotes/Test_2.scala @@ -0,0 +1,5 @@ +object Test extends App { + Macros.m1 + Macros.m2 + println(Macros.m3) +} |