diff options
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/StdAttachments.scala | 4 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Typers.scala | 9 | ||||
-rw-r--r-- | test/files/run/t7777.check | 7 | ||||
-rw-r--r-- | test/files/run/t7777/Macros_1.scala | 17 | ||||
-rw-r--r-- | test/files/run/t7777/Test_2.scala | 6 |
5 files changed, 40 insertions, 3 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/StdAttachments.scala b/src/compiler/scala/tools/nsc/typechecker/StdAttachments.scala index 54c665fe56..86bf846f1c 100644 --- a/src/compiler/scala/tools/nsc/typechecker/StdAttachments.scala +++ b/src/compiler/scala/tools/nsc/typechecker/StdAttachments.scala @@ -50,6 +50,10 @@ trait StdAttachments { case _ => false } + /** Returns the original tree of the macro expansion if the argument is a macro expansion or EmptyTree otherwise. + */ + def macroExpandee(tree: Tree): Tree = tree.attachments.get[MacroExpansionAttachment].map(_.expandee).getOrElse(EmptyTree) + /** After macro expansion is completed, links the expandee and the expansion result by annotating them both with a `MacroExpansionAttachment`. * The `expanded` parameter is of type `Any`, because macros can expand both into trees and into annotations. */ diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index 5e89440bc0..7ff9e854b1 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -3953,9 +3953,12 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper def mkInvoke(cxTree: Tree, tree: Tree, qual: Tree, name: Name): Option[Tree] = { debuglog(s"dyna.mkInvoke($cxTree, $tree, $qual, $name)") val treeInfo.Applied(treeSelection, _, _) = tree - def isDesugaredApply = treeSelection match { - case Select(`qual`, nme.apply) => true - case _ => false + def isDesugaredApply = { + val protoQual = macroExpandee(qual) orElse qual + treeSelection match { + case Select(`protoQual`, nme.apply) => true + case _ => false + } } acceptsApplyDynamicWithType(qual, name) map { tp => // If tp == NoType, pass only explicit type arguments to applyXXX. Not used at all diff --git a/test/files/run/t7777.check b/test/files/run/t7777.check new file mode 100644 index 0000000000..162ff2d2a2 --- /dev/null +++ b/test/files/run/t7777.check @@ -0,0 +1,7 @@ +foo(1, 2) +bar(4, 5) +foo(3) +bar(7) +apply(6) +apply(9) +foo(8) diff --git a/test/files/run/t7777/Macros_1.scala b/test/files/run/t7777/Macros_1.scala new file mode 100644 index 0000000000..459ab3edbb --- /dev/null +++ b/test/files/run/t7777/Macros_1.scala @@ -0,0 +1,17 @@ +import scala.language.experimental.macros +import scala.language.dynamics +import scala.reflect.macros.WhiteboxContext + +class DynMacro extends Dynamic { + def applyDynamic(s: String)(xs: Any*): DynMacro = + macro DynMacro.applyDynamicMacro +} + +object DynMacro extends DynMacro { + def applyDynamicMacro(c: WhiteboxContext)(s: c.Expr[String])(xs: c.Expr[Any]*): c.Expr[DynMacro] = { + import c.universe._ + val Literal(Constant(n: String)) = s.tree + val args = xs.map(_.tree.toString).mkString("(", ", ", ")") + c.Expr(q"println(${ n + args }); ${c.prefix.tree}") + } +}
\ No newline at end of file diff --git a/test/files/run/t7777/Test_2.scala b/test/files/run/t7777/Test_2.scala new file mode 100644 index 0000000000..1fe8b63bab --- /dev/null +++ b/test/files/run/t7777/Test_2.scala @@ -0,0 +1,6 @@ +object Test extends App { + DynMacro.foo(1, 2) // prints "foo(1, 2)" + DynMacro.foo(3).bar(4, 5) // prints "bar(4, 5)", then "foo(3)" + DynMacro(6).bar(7) // prints "bar(7)", then "apply(6)" + DynMacro.foo(8)(9) // Fails! +}
\ No newline at end of file |