summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Macros.scala27
-rw-r--r--test/files/run/macro-impl-relaxed.check4
-rw-r--r--test/files/run/macro-impl-relaxed/Macros_1.scala14
-rw-r--r--test/files/run/macro-impl-relaxed/Test_2.scala6
5 files changed, 42 insertions, 11 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala
index fe1607c631..7fa199afaf 100644
--- a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala
@@ -782,7 +782,7 @@ trait ContextErrors {
}
def MacroExpansionHasInvalidTypeError(expandee: Tree, expanded: Any) = {
- val expected = "expr"
+ val expected = "expr or tree"
val isPathMismatch = expanded != null && expanded.isInstanceOf[scala.reflect.api.Exprs#Expr[_]]
macroExpansionError(expandee,
s"macro must return a compiler-specific $expected; returned value is " + (
diff --git a/src/compiler/scala/tools/nsc/typechecker/Macros.scala b/src/compiler/scala/tools/nsc/typechecker/Macros.scala
index 6c4d1e20aa..86ba3d2164 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Macros.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Macros.scala
@@ -92,11 +92,12 @@ trait Macros extends FastTrack with MacroRuntimes with Traces with Helpers {
methName: String,
// flattens the macro impl's parameter lists having symbols replaced with their fingerprints
// currently fingerprints are calculated solely from types of the symbols:
- // * c.Expr[T] => IMPLPARAM_EXPR
- // * c.WeakTypeTag[T] => index of the type parameter corresponding to that type tag
- // * everything else (e.g. scala.reflect.macros.Context) => IMPLPARAM_OTHER
+ // * c.Expr[T] => LiftedTyped
+ // * c.Tree => LiftedUntyped
+ // * c.WeakTypeTag[T] => Tagged(index of the type parameter corresponding to that type tag)
+ // * everything else (e.g. scala.reflect.macros.Context) => Other
// f.ex. for: def impl[T: WeakTypeTag, U, V: WeakTypeTag](c: Context)(x: c.Expr[T], y: c.Tree): (U, V) = ???
- // `signature` will be equal to List(List(Other), List(Lifted, Other), List(Tagged(0), Tagged(2)))
+ // `signature` will be equal to List(List(Other), List(LiftedTyped, LiftedUntyped), List(Tagged(0), Tagged(2)))
signature: List[List[Fingerprint]],
// type arguments part of a macro impl ref (the right-hand side of a macro definition)
// these trees don't refer to a macro impl, so we can pickle them as is
@@ -124,7 +125,7 @@ trait Macros extends FastTrack with MacroRuntimes with Traces with Helpers {
* "className" = "Macros$"))
*/
object MacroImplBinding {
- val versionFormat = 4.0
+ val versionFormat = 5.0
def pickleAtom(obj: Any): Tree =
obj match {
@@ -164,7 +165,8 @@ trait Macros extends FastTrack with MacroRuntimes with Traces with Helpers {
def signature: List[List[Fingerprint]] = {
def fingerprint(tpe: Type): Fingerprint = tpe.dealiasWiden match {
case TypeRef(_, RepeatedParamClass, underlying :: Nil) => fingerprint(underlying)
- case ExprClassOf(_) => Lifted
+ case ExprClassOf(_) => LiftedTyped
+ case TreeType() => LiftedUntyped
case _ => Other
}
@@ -388,7 +390,8 @@ trait Macros extends FastTrack with MacroRuntimes with Traces with Helpers {
val wrappedArgs = mapWithIndex(args)((arg, j) => {
val fingerprint = implParams(min(j, implParams.length - 1))
fingerprint match {
- case Lifted => context.Expr[Nothing](arg)(TypeTag.Nothing) // TODO: SI-5752
+ case LiftedTyped => context.Expr[Nothing](arg)(TypeTag.Nothing) // TODO: SI-5752
+ case LiftedUntyped => arg
case _ => abort(s"unexpected fingerprint $fingerprint in $binding with paramss being $paramss " +
s"corresponding to arg $arg in $argss")
}
@@ -690,6 +693,7 @@ trait Macros extends FastTrack with MacroRuntimes with Traces with Helpers {
}
expanded match {
case expanded: Expr[_] if expandee.symbol.isTermMacro => validateResultingTree(expanded.tree)
+ case expanded: Tree if expandee.symbol.isTermMacro => validateResultingTree(expanded)
case _ => MacroExpansionHasInvalidTypeError(expandee, expanded)
}
} catch {
@@ -804,10 +808,12 @@ class Fingerprint(val value: Int) extends AnyVal {
def paramPos = { assert(isTag, this); value }
def isTag = value >= 0
def isOther = this == Other
- def isExpr = this == Lifted
+ def isExpr = this == LiftedTyped
+ def isTree = this == LiftedUntyped
override def toString = this match {
case Other => "Other"
- case Lifted => "Expr"
+ case LiftedTyped => "Expr"
+ case LiftedUntyped => "Tree"
case _ => s"Tag($value)"
}
}
@@ -815,5 +821,6 @@ class Fingerprint(val value: Int) extends AnyVal {
object Fingerprint {
def Tagged(tparamPos: Int) = new Fingerprint(tparamPos)
val Other = new Fingerprint(-1)
- val Lifted = new Fingerprint(-2)
+ val LiftedTyped = new Fingerprint(-2)
+ val LiftedUntyped = new Fingerprint(-3)
}
diff --git a/test/files/run/macro-impl-relaxed.check b/test/files/run/macro-impl-relaxed.check
new file mode 100644
index 0000000000..487b116534
--- /dev/null
+++ b/test/files/run/macro-impl-relaxed.check
@@ -0,0 +1,4 @@
+2
+2
+2
+2
diff --git a/test/files/run/macro-impl-relaxed/Macros_1.scala b/test/files/run/macro-impl-relaxed/Macros_1.scala
new file mode 100644
index 0000000000..af62646b4e
--- /dev/null
+++ b/test/files/run/macro-impl-relaxed/Macros_1.scala
@@ -0,0 +1,14 @@
+import language.experimental.macros
+import scala.reflect.macros.Context
+
+object Macros {
+ def implUU(c: Context)(x: c.Tree): c.Tree = x
+ def implTU(c: Context)(x: c.Expr[Int]): c.Tree = x.tree
+ def implUT(c: Context)(x: c.Tree): c.Expr[Int] = c.Expr[Int](x)
+ def implTT(c: Context)(x: c.Expr[Int]): c.Expr[Int] = x
+
+ def fooUU(x: Int): Int = macro implUU
+ def fooTU(x: Int): Int = macro implTU
+ def fooUT(x: Int): Int = macro implUT
+ def fooTT(x: Int): Int = macro implTT
+} \ No newline at end of file
diff --git a/test/files/run/macro-impl-relaxed/Test_2.scala b/test/files/run/macro-impl-relaxed/Test_2.scala
new file mode 100644
index 0000000000..2eaeef0fd0
--- /dev/null
+++ b/test/files/run/macro-impl-relaxed/Test_2.scala
@@ -0,0 +1,6 @@
+object Test extends App {
+ println(Macros.fooUU(2))
+ println(Macros.fooTU(2))
+ println(Macros.fooUT(2))
+ println(Macros.fooTT(2))
+} \ No newline at end of file