summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala28
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Macros.scala93
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/StdAttachments.scala3
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala19
-rw-r--r--src/reflect/scala/reflect/internal/TreeInfo.scala11
-rw-r--r--test/files/neg/macro-argc-mismatch.check49
-rw-r--r--test/files/neg/macro-argc-mismatch/Macros_1.scala16
-rw-r--r--test/files/neg/macro-argc-mismatch/Test_2.scala19
-rw-r--r--test/files/neg/macro-invalidusage-badargs.check5
-rw-r--r--test/files/neg/macro-qmarkqmarkqmark.check2
-rw-r--r--test/files/neg/t7157.check36
-rw-r--r--test/files/run/macro-expand-default-named.check56
-rw-r--r--test/files/run/macro-expand-default-named/Impls_1.scala37
-rw-r--r--test/files/run/macro-expand-default-named/Macros_Test_2.scala71
-rw-r--r--test/files/run/macro-expand-ownerchain-a.check2
-rw-r--r--test/files/run/macro-expand-ownerchain-a/Macros_1.scala11
-rw-r--r--test/files/run/macro-expand-ownerchain-a/Test_2.scala4
-rw-r--r--test/files/run/macro-invalidusage-partialapplication-with-tparams.check2
-rw-r--r--test/files/run/macro-invalidusage-partialapplication.check2
-rw-r--r--test/files/run/reify-repl-fail-gracefully.check2
-rw-r--r--test/pending/run/macro-expand-default.flags1
-rw-r--r--test/pending/run/macro-expand-default/Impls_1.scala10
-rw-r--r--test/pending/run/macro-expand-default/Macros_Test_2.scala8
-rw-r--r--test/pending/run/macro-expand-named.flags1
-rw-r--r--test/pending/run/macro-expand-named/Impls_1.scala10
-rw-r--r--test/pending/run/macro-expand-named/Macros_Test_2.scala5
26 files changed, 384 insertions, 119 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala
index 2043eb5d5d..40b97394f2 100644
--- a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala
@@ -501,10 +501,6 @@ trait ContextErrors {
}
// doTypeApply
- //tryNamesDefaults
- def NamedAndDefaultArgumentsNotSupportedForMacros(tree: Tree, fun: Tree) =
- NormalTypeError(tree, "macro applications do not support named and/or default arguments")
-
def TooManyArgsNamesDefaultsError(tree: Tree, fun: Tree) =
NormalTypeError(tree, "too many arguments for "+treeSymTypeMsg(fun))
@@ -603,12 +599,11 @@ trait ContextErrors {
//adapt
def MissingArgsForMethodTpeError(tree: Tree, meth: Symbol) = {
+ val errorExplanation = "missing arguments for " + meth.fullLocationString
+ val suggestPartialApplication = ";\nfollow this method with `_' if you want to treat it as a partially applied function"
val message =
- if (meth.isMacro) MacroTooFewArgumentListsMessage
- else "missing arguments for " + meth.fullLocationString + (
- if (meth.isConstructor) ""
- else ";\nfollow this method with `_' if you want to treat it as a partially applied function"
- )
+ if (meth.isMacro || meth.isConstructor) errorExplanation
+ else errorExplanation + suggestPartialApplication
issueNormalTypeError(tree, message)
setError(tree)
}
@@ -748,15 +743,12 @@ trait ContextErrors {
throw MacroExpansionException
}
- private def MacroTooFewArgumentListsMessage = "too few argument lists for macro invocation"
- def MacroTooFewArgumentListsError(expandee: Tree) = macroExpansionError2(expandee, MacroTooFewArgumentListsMessage)
-
- private def MacroTooManyArgumentListsMessage = "too many argument lists for macro invocation"
- def MacroTooManyArgumentListsError(expandee: Tree) = macroExpansionError2(expandee, MacroTooManyArgumentListsMessage)
-
- def MacroTooFewArgumentsError(expandee: Tree) = macroExpansionError2(expandee, "too few arguments for macro invocation")
-
- def MacroTooManyArgumentsError(expandee: Tree) = macroExpansionError2(expandee, "too many arguments for macro invocation")
+ def MacroFastTrackFailed(expandee: Tree) = {
+ // here we speculate that the reason why FastTrackEntry.validate failed is the lack arguments for a given method
+ // that's not ideal, but on the other hand this allows us to keep FastTrack simple without hooking errorgen into it
+ MissingArgsForMethodTpeError(expandee, expandee.symbol)
+ throw MacroExpansionException
+ }
def MacroGeneratedAbort(expandee: Tree, ex: AbortMacroException) = {
// errors have been reported by the macro itself, so we do nothing here
diff --git a/src/compiler/scala/tools/nsc/typechecker/Macros.scala b/src/compiler/scala/tools/nsc/typechecker/Macros.scala
index cf82d6baac..29b3ec7f3e 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Macros.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Macros.scala
@@ -353,7 +353,7 @@ trait Macros extends FastTrack with MacroRuntimes with Traces with Helpers {
new {
val universe: self.global.type = self.global
val callsiteTyper: universe.analyzer.Typer = typer.asInstanceOf[global.analyzer.Typer]
- val expandee = universe.analyzer.macroExpanderAttachment(expandeeTree).original orElse duplicateAndKeepPositions(expandeeTree)
+ val expandee = universe.analyzer.macroExpanderAttachment(expandeeTree).desugared orElse duplicateAndKeepPositions(expandeeTree)
} with UnaffiliatedMacroContext {
val prefix = Expr[Nothing](prefixTree)(TypeTag.Nothing)
override def toString = "MacroContext(%s@%s +%d)".format(expandee.symbol.name, expandee.pos, enclosingMacros.length - 1 /* exclude myself */)
@@ -371,7 +371,15 @@ trait Macros extends FastTrack with MacroRuntimes with Traces with Helpers {
def standardMacroArgs(typer: Typer, expandee: Tree): MacroArgs = {
val macroDef = expandee.symbol
val paramss = macroDef.paramss
- val treeInfo.Applied(core, targs, argss) = expandee
+ val treeInfo.Applied(core, targs, maybeNamedArgss) = expandee
+ val argss = map2(maybeNamedArgss, paramss)((args, params) => {
+ if (args.exists(_.isInstanceOf[AssignOrNamedArg])) {
+ val sorted = ListBuffer.fill(params.length)(EmptyTree: Tree)
+ args foreach { case AssignOrNamedArg(Ident(name), arg) => sorted(params.indexWhere(_.name == name)) = arg }
+ sorted.toList
+ } else if (params.length == args.length) args
+ else args ++ List.fill(params.length - args.length)(EmptyTree)
+ })
val prefix = core match { case Select(qual, _) => qual; case _ => EmptyTree }
val context = expandee.attachments.get[MacroRuntimeAttachment].flatMap(_.macroContext).getOrElse(macroContext(typer, prefix, expandee))
@@ -383,16 +391,11 @@ trait Macros extends FastTrack with MacroRuntimes with Traces with Helpers {
|paramss: $paramss
""".trim)
- import typer.TyperErrorGen._
- val isNullaryArgsEmptyParams = argss.isEmpty && paramss == ListOfNil
- if (paramss.length < argss.length) MacroTooManyArgumentListsError(expandee)
- if (paramss.length > argss.length && !isNullaryArgsEmptyParams) MacroTooFewArgumentListsError(expandee)
-
val macroImplArgs: List[Any] =
if (fastTrack contains macroDef) {
// Take a dry run of the fast track implementation
if (fastTrack(macroDef) validate expandee) argss.flatten
- else MacroTooFewArgumentListsError(expandee)
+ else typer.TyperErrorGen.MacroFastTrackFailed(expandee)
}
else {
def calculateMacroArgs(binding: MacroImplBinding) = {
@@ -403,14 +406,6 @@ trait Macros extends FastTrack with MacroRuntimes with Traces with Helpers {
// wrap argss in c.Expr if necessary (i.e. if corresponding macro impl param is of type c.Expr[T])
// expand varargs (nb! varargs can apply to any parameter section, not necessarily to the last one)
val trees = map3(argss, paramss, signature)((args, defParams, implParams) => {
- val isVarargs = isVarArgsList(defParams)
- if (isVarargs) {
- if (defParams.length > args.length + 1) MacroTooFewArgumentsError(expandee)
- } else {
- if (defParams.length < args.length) MacroTooManyArgumentsError(expandee)
- if (defParams.length > args.length) MacroTooFewArgumentsError(expandee)
- }
-
val wrappedArgs = mapWithIndex(args)((arg, j) => {
val fingerprint = implParams(min(j, implParams.length - 1))
fingerprint match {
@@ -421,7 +416,7 @@ trait Macros extends FastTrack with MacroRuntimes with Traces with Helpers {
}
})
- if (isVarargs) {
+ if (isVarArgsList(defParams)) {
val (normal, varargs) = wrappedArgs splitAt (defParams.length - 1)
normal :+ varargs // pack all varargs into a single Seq argument (varargs Scala style)
} else wrappedArgs
@@ -529,9 +524,11 @@ trait Macros extends FastTrack with MacroRuntimes with Traces with Helpers {
* the expandee with an error marker set if there has been an error
*/
abstract class MacroExpander(val typer: Typer, val expandee: Tree) {
+ val symbol = expandee match { case Block(_, expr) => expr.symbol; case tree => tree.symbol }
+
def onSuccess(expanded: Tree): Tree
def onFallback(expanded: Tree): Tree
- def onSuppressed(expandee: Tree): Tree = expandee
+ def onSuppressed(expanded: Tree): Tree = expanded
def onDelayed(expanded: Tree): Tree = expanded
def onSkipped(expanded: Tree): Tree = expanded
def onFailure(expanded: Tree): Tree = { typer.infer.setError(expandee); expandee }
@@ -551,15 +548,15 @@ trait Macros extends FastTrack with MacroRuntimes with Traces with Helpers {
if (Statistics.canEnable) Statistics.incCounter(macroExpandCount)
try {
withInfoLevel(nodePrinters.InfoLevel.Quiet) { // verbose printing might cause recursive macro expansions
- if (expandee.symbol.isErroneous || (expandee exists (_.isErroneous))) {
- val reason = if (expandee.symbol.isErroneous) "not found or incompatible macro implementation" else "erroneous arguments"
+ if (symbol.isErroneous || (expandee exists (_.isErroneous)) || (desugared exists (_.isErroneous))) {
+ val reason = if (symbol.isErroneous) "not found or incompatible macro implementation" else "erroneous arguments"
macroLogVerbose(s"cancelled macro expansion because of $reason: $expandee")
onFailure(typer.infer.setError(expandee))
} else try {
val expanded = {
- val runtime = macroRuntime(expandee)
- if (runtime != null) macroExpandWithRuntime(typer, expandee, runtime)
- else macroExpandWithoutRuntime(typer, expandee)
+ val runtime = macroRuntime(desugared)
+ if (runtime != null) macroExpandWithRuntime(typer, desugared, runtime)
+ else macroExpandWithoutRuntime(typer, desugared)
}
expanded match {
case Success(expanded) =>
@@ -591,7 +588,7 @@ trait Macros extends FastTrack with MacroRuntimes with Traces with Helpers {
extends MacroExpander(typer, expandee) {
lazy val innerPt = {
val tp = if (isNullaryInvocation(expandee)) expandee.tpe.finalResultType else expandee.tpe
- if (isBlackbox(expandee)) tp
+ if (isBlackbox(symbol)) tp
else {
// approximation is necessary for whitebox macros to guide type inference
// read more in the comments for onDelayed below
@@ -599,6 +596,50 @@ trait Macros extends FastTrack with MacroRuntimes with Traces with Helpers {
deriveTypeWithWildcards(undetparams)(tp)
}
}
+ override protected def expand(desugared: Tree) = {
+ // SI-5940 in order for a macro expansion that involves named or default arguments
+ // to see the actual prefix and arguments being passed by the user instead of their desugarings
+ // we need to inline synthetics in case when `fun` is actually a macro
+ // underlying macro implementation is going to get explicitly passed arguments in correct order
+ // and the rest (defaults filled in by the vanilla part of `tryNamesDefaults`) will become empty trees
+ // in order for the macro to be able to account for evaluation order, the original is provided in `c.macroApplication`
+ // of course, ideally we would like to provide the impl with right-hand sides of those default arguments
+ // but currently that is flat out impossible because of the difference in scopes
+ // anyway this is already an improvement over the former status quo when named/default invocations were outright prohibited
+ def undoNamesDefaults(tree: Tree): Tree = {
+ val (qualsym, qual, vdefs0, app @ Applied(_, _, argss)) = tree match {
+ case Block((qualdef @ ValDef(_, name, _, qual)) +: vdefs, app) if name.startsWith(nme.QUAL_PREFIX) => (qualdef.symbol, qual, vdefs, app)
+ case Block(vdefs, app) => (NoSymbol, EmptyTree, vdefs, app)
+ case tree => (NoSymbol, EmptyTree, Nil, tree)
+ }
+ val vdefs = vdefs0.map{ case vdef: ValDef => vdef }
+ def hasNamesDefaults(args: List[Tree]) = {
+ args.exists(arg => isDefaultGetter(arg) || vdefs.exists(_.symbol == arg.symbol))
+ }
+ def undoNamesDefaults(args: List[Tree], depth: Int) = {
+ def extractRhs(vdef: ValDef) = vdef.rhs.changeOwner(vdef.symbol -> typer.context.owner)
+ case class Arg(tree: Tree, ipos: Int, inamed: Int) { val param = app.symbol.paramss(depth)(ipos) }
+ val indexed = args.map(arg => arg -> vdefs.indexWhere(_.symbol == arg.symbol)).zipWithIndex.flatMap({
+ /* default */ case ((arg, _), _) if isDefaultGetter(arg) => None
+ /* positional */ case ((arg, -1), ipos) => Some(Arg(arg, ipos, -1))
+ /* default+named */ case ((_, inamed), _) if isDefaultGetter(extractRhs(vdefs(inamed))) => None
+ /* named */ case ((arg, inamed), ipos) => Some(Arg(extractRhs(vdefs(inamed)), ipos, inamed))
+ })
+ if (indexed.forall(_.inamed == -1)) indexed.map(_.tree)
+ else indexed.sortBy(_.inamed).map(arg => AssignOrNamedArg(Ident(arg.param.name), arg.tree))
+ }
+ def loop(tree: Tree, depth: Int): Tree = tree match {
+ case Apply(fun, args) if hasNamesDefaults(args) => treeCopy.Apply(tree, loop(fun, depth - 1), undoNamesDefaults(args, depth))
+ case Apply(fun, args) => treeCopy.Apply(tree, loop(fun, depth - 1), args)
+ case TypeApply(core, targs) => treeCopy.TypeApply(tree, core, targs)
+ case Select(core, name) if qualsym != NoSymbol && core.symbol == qualsym => treeCopy.Select(tree, qual, name)
+ case core => core
+ }
+ if (app.symbol == null || app.symbol == NoSymbol || app.exists(_.isErroneous)) tree
+ else loop(app, depth = argss.length - 1)
+ }
+ super.expand(undoNamesDefaults(desugared))
+ }
override def onSuccess(expanded0: Tree) = {
// prematurely annotate the tree with a macro expansion attachment
// so that adapt called indirectly by typer.typed knows that it needs to apply the existential fixup
@@ -616,7 +657,7 @@ trait Macros extends FastTrack with MacroRuntimes with Traces with Helpers {
}
}
- if (isBlackbox(expandee)) {
+ if (isBlackbox(symbol)) {
val expanded1 = atPos(enclosingMacroPosition.makeTransparent)(Typed(expanded0, TypeTree(innerPt)))
typecheck("blackbox typecheck", expanded1, outerPt)
} else {
@@ -676,7 +717,7 @@ trait Macros extends FastTrack with MacroRuntimes with Traces with Helpers {
// Thanks to that the materializer can take a look at what's going on and react accordingly.
val shouldInstantiate = typer.context.undetparams.nonEmpty && !mode.inPolyMode
if (shouldInstantiate) {
- if (isBlackbox(expandee)) typer.instantiatePossiblyExpectingUnit(delayed, mode, outerPt)
+ if (isBlackbox(symbol)) typer.instantiatePossiblyExpectingUnit(delayed, mode, outerPt)
else {
forced += delayed
typer.infer.inferExprInstance(delayed, typer.context.extractUndetparams(), outerPt, keepNothings = false)
diff --git a/src/compiler/scala/tools/nsc/typechecker/StdAttachments.scala b/src/compiler/scala/tools/nsc/typechecker/StdAttachments.scala
index 57f27a05fd..1a6d2f0011 100644
--- a/src/compiler/scala/tools/nsc/typechecker/StdAttachments.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/StdAttachments.scala
@@ -85,6 +85,7 @@ trait StdAttachments {
tree match {
// see the comment to `isMacroExpansionSuppressed` to learn why we need
// a special traversal strategy here
+ case Block(_, expr) => unsuppressMacroExpansion(expr)
case Apply(fn, _) => unsuppressMacroExpansion(fn)
case TypeApply(fn, _) => unsuppressMacroExpansion(fn)
case _ => // do nothing
@@ -101,6 +102,8 @@ trait StdAttachments {
// we have to account for the fact that during typechecking an expandee might become wrapped,
// i.e. surrounded by an inferred implicit argument application or by an inferred type argument application.
// in that case the expandee itself will no longer be suppressed and we need to look at the core
+ // upd. we also need to allow for blocks, because that's what names and defaults are often desugared to
+ case Block(_, expr) => isMacroExpansionSuppressed(expr)
case Apply(fn, _) => isMacroExpansionSuppressed(fn)
case TypeApply(fn, _) => isMacroExpansionSuppressed(fn)
case _ => false
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index 10fe530445..020d26c712 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -1155,7 +1155,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
case mt: MethodType if mode.typingExprNotFunNotLhs && mt.isImplicit => // (4.1)
adaptToImplicitMethod(mt)
- case mt: MethodType if mode.typingExprNotFunNotLhs && !hasUndetsInMonoMode && !treeInfo.isMacroApplicationOrBlock(tree) =>
+ case mt: MethodType if mode.typingExprNotFunNotLhs && !hasUndetsInMonoMode =>
instantiateToMethodType(mt)
case _ =>
vanillaAdapt(tree)
@@ -3292,12 +3292,6 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
*/
def tryNamesDefaults: Tree = {
val lencmp = compareLengths(args, formals)
-
- def checkNotMacro() = {
- if (treeInfo.isMacroApplication(fun))
- tryTupleApply orElse duplErrorTree(NamedAndDefaultArgumentsNotSupportedForMacros(tree, fun))
- }
-
if (mt.isErroneous) duplErrTree
else if (mode.inPatternMode) {
// #2064
@@ -3316,18 +3310,15 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
else if (allArgsArePositional(argPos) && !isNamedApplyBlock(fun)) {
// if there's no re-ordering, and fun is not transformed, no need to transform
// more than an optimization, e.g. important in "synchronized { x = update-x }"
- checkNotMacro()
doTypedApply(tree, fun, namelessArgs, mode, pt)
} else {
- checkNotMacro()
- transformNamedApplication(Typer.this, mode, pt)(
- treeCopy.Apply(tree, fun, namelessArgs), argPos)
+ unsuppressMacroExpansion(transformNamedApplication(Typer.this, mode, pt)(
+ treeCopy.Apply(tree, suppressMacroExpansion(fun), namelessArgs), argPos))
}
} else {
// defaults are needed. they are added to the argument list in named style as
// calls to the default getters. Example:
// foo[Int](a)() ==> foo[Int](a)(b = foo$qual.foo$default$2[Int](a))
- checkNotMacro()
// SI-8111 transformNamedApplication eagerly shuffles around the application to preserve
// evaluation order. During this process, it calls `changeOwner` on symbols that
@@ -3350,7 +3341,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
symsOwnedByContextOwner foreach (_.owner = context.owner)
}
- val fun1 = transformNamedApplication(Typer.this, mode, pt)(fun, x => x)
+ val fun1 = transformNamedApplication(Typer.this, mode, pt)(suppressMacroExpansion(fun), x => x)
if (fun1.isErroneous) duplErrTree
else {
assert(isNamedApplyBlock(fun1), fun1)
@@ -3376,7 +3367,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
// useful when a default doesn't match parameter type, e.g. def f[T](x:T="a"); f[Int]()
val note = "Error occurred in an application involving default arguments."
if (!(context.diagnostic contains note)) context.diagnostic = note :: context.diagnostic
- doTypedApply(tree, if (blockIsEmpty) fun else fun1, allArgs, mode, pt)
+ unsuppressMacroExpansion(doTypedApply(tree, if (blockIsEmpty) fun else fun1, allArgs, mode, pt))
} else {
rollbackNamesDefaultsOwnerChanges()
tryTupleApply orElse duplErrorTree(NotEnoughArgsError(tree, fun, missing))
diff --git a/src/reflect/scala/reflect/internal/TreeInfo.scala b/src/reflect/scala/reflect/internal/TreeInfo.scala
index 1eb0743bc8..7ff482d021 100644
--- a/src/reflect/scala/reflect/internal/TreeInfo.scala
+++ b/src/reflect/scala/reflect/internal/TreeInfo.scala
@@ -852,13 +852,8 @@ abstract class TreeInfo {
case _ => false
})
- def isMacroApplication(tree: Tree): Boolean = !tree.isDef && {
- val sym = tree.symbol
- sym != null && sym.isTermMacro && !sym.isErroneous
- }
-
- def isMacroApplicationOrBlock(tree: Tree): Boolean = tree match {
- case Block(_, expr) => isMacroApplicationOrBlock(expr)
- case tree => isMacroApplication(tree)
+ def isMacroApplication(tree: Tree): Boolean = tree match {
+ case Block(_, expr) => isMacroApplication(expr)
+ case tree => !tree.isDef && tree.symbol != null && tree.symbol.isTermMacro && !tree.symbol.isErroneous
}
}
diff --git a/test/files/neg/macro-argc-mismatch.check b/test/files/neg/macro-argc-mismatch.check
new file mode 100644
index 0000000000..617daa890c
--- /dev/null
+++ b/test/files/neg/macro-argc-mismatch.check
@@ -0,0 +1,49 @@
+Test_2.scala:4: error: missing arguments for macro method one in object Macros
+ one
+ ^
+Test_2.scala:5: error: not enough arguments for macro method one: (x: Int)Unit.
+Unspecified value parameter x.
+ one()
+ ^
+Test_2.scala:6: error: too many arguments for macro method one: (x: Int)Unit
+ one(2, 3)
+ ^
+Test_2.scala:7: error: not enough arguments for macro method one: (x: Int)Unit.
+Unspecified value parameter x.
+ one()()
+ ^
+Test_2.scala:8: error: Unit does not take parameters
+ one(1)()
+ ^
+Test_2.scala:10: error: missing arguments for macro method two in object Macros
+ two
+ ^
+Test_2.scala:11: error: not enough arguments for macro method two: (x: Int)(y: Int)Unit.
+Unspecified value parameter x.
+ two()
+ ^
+Test_2.scala:12: error: too many arguments for macro method two: (x: Int)(y: Int)Unit
+ two(2, 3)
+ ^
+Test_2.scala:13: error: not enough arguments for macro method two: (x: Int)(y: Int)Unit.
+Unspecified value parameter x.
+ two()()
+ ^
+Test_2.scala:14: error: missing arguments for macro method two in object Macros
+ two(1)
+ ^
+Test_2.scala:15: error: not enough arguments for macro method two: (y: Int)Unit.
+Unspecified value parameter y.
+ two(1)()
+ ^
+Test_2.scala:16: error: too many arguments for macro method two: (y: Int)Unit
+ two(1)(2, 3)
+ ^
+Test_2.scala:17: error: not enough arguments for macro method two: (y: Int)Unit.
+Unspecified value parameter y.
+ two(1)()()
+ ^
+Test_2.scala:18: error: Unit does not take parameters
+ two(1)(1)()
+ ^
+14 errors found
diff --git a/test/files/neg/macro-argc-mismatch/Macros_1.scala b/test/files/neg/macro-argc-mismatch/Macros_1.scala
new file mode 100644
index 0000000000..4dca644172
--- /dev/null
+++ b/test/files/neg/macro-argc-mismatch/Macros_1.scala
@@ -0,0 +1,16 @@
+import scala.language.experimental.macros
+import scala.reflect.macros.blackbox.Context
+
+object Macros {
+ def one(x: Int): Unit = macro oneImpl
+ def oneImpl(c: Context)(x: c.Tree) = {
+ import c.universe._
+ q"()"
+ }
+
+ def two(x: Int)(y: Int): Unit = macro twoImpl
+ def twoImpl(c: Context)(x: c.Tree)(y: c.Tree) = {
+ import c.universe._
+ q"()"
+ }
+}
diff --git a/test/files/neg/macro-argc-mismatch/Test_2.scala b/test/files/neg/macro-argc-mismatch/Test_2.scala
new file mode 100644
index 0000000000..28f9c35654
--- /dev/null
+++ b/test/files/neg/macro-argc-mismatch/Test_2.scala
@@ -0,0 +1,19 @@
+import Macros._
+
+object Test extends App {
+ one
+ one()
+ one(2, 3)
+ one()()
+ one(1)()
+
+ two
+ two()
+ two(2, 3)
+ two()()
+ two(1)
+ two(1)()
+ two(1)(2, 3)
+ two(1)()()
+ two(1)(1)()
+} \ No newline at end of file
diff --git a/test/files/neg/macro-invalidusage-badargs.check b/test/files/neg/macro-invalidusage-badargs.check
index 4c1115418b..3fd3c53691 100644
--- a/test/files/neg/macro-invalidusage-badargs.check
+++ b/test/files/neg/macro-invalidusage-badargs.check
@@ -3,13 +3,14 @@ Macros_Test_2.scala:5: error: type mismatch;
required: Int
foo("42")
^
-Macros_Test_2.scala:6: error: too few argument lists for macro invocation
+Macros_Test_2.scala:6: error: missing arguments for macro method foo in object Macros
foo
^
Macros_Test_2.scala:7: error: Int does not take parameters
foo(4)(2)
^
-Macros_Test_2.scala:8: error: macro applications do not support named and/or default arguments
+Macros_Test_2.scala:8: error: not enough arguments for macro method foo: (x: Int)Int.
+Unspecified value parameter x.
foo()
^
Macros_Test_2.scala:9: error: too many arguments for macro method foo: (x: Int)Int
diff --git a/test/files/neg/macro-qmarkqmarkqmark.check b/test/files/neg/macro-qmarkqmarkqmark.check
index bc3e25edaf..b4f8ea905f 100644
--- a/test/files/neg/macro-qmarkqmarkqmark.check
+++ b/test/files/neg/macro-qmarkqmarkqmark.check
@@ -1,7 +1,7 @@
macro-qmarkqmarkqmark.scala:5: error: macro implementation is missing
foo1
^
-macro-qmarkqmarkqmark.scala:8: error: too few argument lists for macro invocation
+macro-qmarkqmarkqmark.scala:8: error: missing arguments for macro method foo2 in object Macros
foo2
^
macro-qmarkqmarkqmark.scala:9: error: macro implementation is missing
diff --git a/test/files/neg/t7157.check b/test/files/neg/t7157.check
index c6a7af9a23..3988460d4b 100644
--- a/test/files/neg/t7157.check
+++ b/test/files/neg/t7157.check
@@ -7,7 +7,8 @@ Test_2.scala:6: error: too many arguments for macro method m1_0_0: ()Unit
Test_2.scala:7: error: too many arguments for macro method m1_0_0: ()Unit
m1_0_0(1, 2, 3)
^
-Test_2.scala:9: error: macro applications do not support named and/or default arguments
+Test_2.scala:9: error: not enough arguments for macro method m1_1_1: (x: Int)Unit.
+Unspecified value parameter x.
m1_1_1()
^
Test_2.scala:11: error: too many arguments for macro method m1_1_1: (x: Int)Unit
@@ -16,22 +17,27 @@ Test_2.scala:11: error: too many arguments for macro method m1_1_1: (x: Int)Unit
Test_2.scala:12: error: too many arguments for macro method m1_1_1: (x: Int)Unit
m1_1_1(1, 2, 3)
^
-Test_2.scala:14: error: macro applications do not support named and/or default arguments
+Test_2.scala:14: error: not enough arguments for macro method m1_2_2: (x: Int, y: Int)Unit.
+Unspecified value parameters x, y.
m1_2_2()
^
-Test_2.scala:15: error: macro applications do not support named and/or default arguments
+Test_2.scala:15: error: not enough arguments for macro method m1_2_2: (x: Int, y: Int)Unit.
+Unspecified value parameter y.
m1_2_2(1)
^
Test_2.scala:17: error: too many arguments for macro method m1_2_2: (x: Int, y: Int)Unit
m1_2_2(1, 2, 3)
^
-Test_2.scala:24: error: macro applications do not support named and/or default arguments
+Test_2.scala:24: error: not enough arguments for macro method m1_1_inf: (x: Int, y: Int*)Unit.
+Unspecified value parameters x, y.
m1_1_inf()
^
-Test_2.scala:29: error: macro applications do not support named and/or default arguments
+Test_2.scala:29: error: not enough arguments for macro method m1_2_inf: (x: Int, y: Int, z: Int*)Unit.
+Unspecified value parameters x, y, z.
m1_2_inf()
^
-Test_2.scala:30: error: macro applications do not support named and/or default arguments
+Test_2.scala:30: error: not enough arguments for macro method m1_2_inf: (x: Int, y: Int, z: Int*)Unit.
+Unspecified value parameters y, z.
m1_2_inf(1)
^
Test_2.scala:35: error: too many arguments for macro method m2_0_0: ()Unit
@@ -43,7 +49,8 @@ Test_2.scala:36: error: too many arguments for macro method m2_0_0: ()Unit
Test_2.scala:37: error: too many arguments for macro method m2_0_0: ()Unit
m2_0_0()(1, 2, 3)
^
-Test_2.scala:39: error: macro applications do not support named and/or default arguments
+Test_2.scala:39: error: not enough arguments for macro method m2_1_1: (x: Int)Unit.
+Unspecified value parameter x.
m2_1_1()()
^
Test_2.scala:41: error: too many arguments for macro method m2_1_1: (x: Int)Unit
@@ -52,22 +59,27 @@ Test_2.scala:41: error: too many arguments for macro method m2_1_1: (x: Int)Unit
Test_2.scala:42: error: too many arguments for macro method m2_1_1: (x: Int)Unit
m2_1_1()(1, 2, 3)
^
-Test_2.scala:44: error: macro applications do not support named and/or default arguments
+Test_2.scala:44: error: not enough arguments for macro method m2_2_2: (x: Int, y: Int)Unit.
+Unspecified value parameters x, y.
m2_2_2()()
^
-Test_2.scala:45: error: macro applications do not support named and/or default arguments
+Test_2.scala:45: error: not enough arguments for macro method m2_2_2: (x: Int, y: Int)Unit.
+Unspecified value parameter y.
m2_2_2()(1)
^
Test_2.scala:47: error: too many arguments for macro method m2_2_2: (x: Int, y: Int)Unit
m2_2_2()(1, 2, 3)
^
-Test_2.scala:54: error: macro applications do not support named and/or default arguments
+Test_2.scala:54: error: not enough arguments for macro method m2_1_inf: (x: Int, y: Int*)Unit.
+Unspecified value parameters x, y.
m2_1_inf()()
^
-Test_2.scala:59: error: macro applications do not support named and/or default arguments
+Test_2.scala:59: error: not enough arguments for macro method m2_2_inf: (x: Int, y: Int, z: Int*)Unit.
+Unspecified value parameters x, y, z.
m2_2_inf()()
^
-Test_2.scala:60: error: macro applications do not support named and/or default arguments
+Test_2.scala:60: error: not enough arguments for macro method m2_2_inf: (x: Int, y: Int, z: Int*)Unit.
+Unspecified value parameters y, z.
m2_2_inf()(1)
^
24 errors found
diff --git a/test/files/run/macro-expand-default-named.check b/test/files/run/macro-expand-default-named.check
new file mode 100644
index 0000000000..2d75772572
--- /dev/null
+++ b/test/files/run/macro-expand-default-named.check
@@ -0,0 +1,56 @@
+Test.this.one(2, -40) = 42
+Test.this.one(y = -40, x = 2) = 42
+Test.this.one(2, -40) = 42
+Test.this.one(100) = 140
+Test.this.one(y = 100) = -98
+Test.this.one(100) = 140
+Test.this.one() = 42
+Test.this.qualone.one(2, -40) = 42
+Test.this.qualone.one(y = -40, x = 2) = 42
+Test.this.qualone.one(2, -40) = 42
+Test.this.qualone.one(x = 100) = 140
+Test.this.qualone.one(y = 100) = -98
+Test.this.qualone.one(x = 100) = 140
+Test.this.qualone.one() = 42
+Test.this.onezero(2, -40)(1, 2) = 41
+Test.this.onezero(y = -40, x = 2)(z = 3, w = 4) = 41
+Test.this.onezero(2, -40)(5, 6) = 41
+Test.this.onezero(100)(7, 8) = 139
+Test.this.onezero(y = 100)(z = 9, w = 10) = -99
+Test.this.onezero(100)(11, 12) = 139
+Test.this.onezero()(13, 14) = 41
+Test.this.qualonezero.onezero(2, -40)(15, 16) = 41
+Test.this.qualonezero.onezero(y = -40, x = 2)(z = 17, w = 18) = 41
+Test.this.qualonezero.onezero(2, -40)(19, 20) = 41
+Test.this.qualonezero.onezero(x = 100)(z = 21, w = 22) = 139
+Test.this.qualonezero.onezero(y = 100)(z = 23, w = 24) = -99
+Test.this.qualonezero.onezero(x = 100)(z = 25, w = 26) = 139
+Test.this.qualonezero.onezero()(z = 27, w = 28) = 41
+Test.this.zeroone(1, 2)(2, -40) = 41
+Test.this.zeroone(x = 3, y = 4)(w = -40, z = 2) = 41
+Test.this.zeroone(5, 6)(2, -40) = 41
+Test.this.zeroone(x = 7, y = 8)(z = 100) = 139
+Test.this.zeroone(x = 9, y = 10)(w = 100) = -99
+Test.this.zeroone(x = 11, y = 12)(z = 100) = 139
+Test.this.zeroone(x = 13, y = 14)() = 41
+Test.this.qualzeroone.zeroone(15, 16)(2, -40) = 41
+Test.this.qualzeroone.zeroone(x = 17, y = 18)(w = -40, z = 2) = 41
+Test.this.qualzeroone.zeroone(19, 20)(2, -40) = 41
+Test.this.qualzeroone.zeroone(x = 21, y = 22)(z = 100) = 139
+Test.this.qualzeroone.zeroone(x = 23, y = 24)(w = 100) = -99
+Test.this.qualzeroone.zeroone(x = 25, y = 26)(z = 100) = 139
+Test.this.qualzeroone.zeroone(x = 27, y = 28)() = 41
+Test.this.oneone(2, -40)(2, -40) = 84
+Test.this.oneone(y = -40, x = 2)(w = -40, z = 2) = 84
+Test.this.oneone(2, -40)(2, -40) = 84
+Test.this.oneone(x = 100)(z = 100) = 280
+Test.this.oneone(y = 100)(w = 100) = -196
+Test.this.oneone(x = 100)(z = 100) = 280
+Test.this.oneone()() = 84
+Test.this.qualoneone.oneone(2, -40)(2, -40) = 84
+Test.this.qualoneone.oneone(y = -40, x = 2)(w = -40, z = 2) = 84
+Test.this.qualoneone.oneone(2, -40)(2, -40) = 84
+Test.this.qualoneone.oneone(x = 100)(z = 100) = 280
+Test.this.qualoneone.oneone(y = 100)(w = 100) = -196
+Test.this.qualoneone.oneone(x = 100)(z = 100) = 280
+Test.this.qualoneone.oneone()() = 84
diff --git a/test/files/run/macro-expand-default-named/Impls_1.scala b/test/files/run/macro-expand-default-named/Impls_1.scala
new file mode 100644
index 0000000000..73774cd56a
--- /dev/null
+++ b/test/files/run/macro-expand-default-named/Impls_1.scala
@@ -0,0 +1,37 @@
+import scala.reflect.macros.blackbox.Context
+
+object Impls {
+ def one(c: Context)(x: c.Tree, y: c.Tree) = {
+ import c.universe._
+ val x1 = x orElse q"2"
+ val y1 = y orElse q"-40"
+ q"println(${c.macroApplication.toString + " = "} + ($x1 - $y1))"
+ }
+
+ def onezero(c: Context)(x: c.Tree, y: c.Tree)(z: c.Tree, w: c.Tree) = {
+ import c.universe._
+ val x1 = x orElse q"2"
+ val y1 = y orElse q"-40"
+ val z1 = z
+ val w1 = w
+ q"println(${c.macroApplication.toString + " = "} + ($x1 - $y1 + $z1 - $w1))"
+ }
+
+ def zeroone(c: Context)(x: c.Tree, y: c.Tree)(z: c.Tree, w: c.Tree) = {
+ import c.universe._
+ val x1 = x
+ val y1 = y
+ val z1 = z orElse q"2"
+ val w1 = w orElse q"-40"
+ q"println(${c.macroApplication.toString + " = "} + ($x1 - $y1 + $z1 - $w1))"
+ }
+
+ def oneone(c: Context)(x: c.Tree, y: c.Tree)(z: c.Tree, w: c.Tree) = {
+ import c.universe._
+ val x1 = x orElse q"2"
+ val y1 = y orElse q"-40"
+ val z1 = z orElse q"2"
+ val w1 = w orElse q"-40"
+ q"println(${c.macroApplication.toString + " = "} + ($x1 - $y1 + $z1 - $w1))"
+ }
+} \ No newline at end of file
diff --git a/test/files/run/macro-expand-default-named/Macros_Test_2.scala b/test/files/run/macro-expand-default-named/Macros_Test_2.scala
new file mode 100644
index 0000000000..e58eddd9a3
--- /dev/null
+++ b/test/files/run/macro-expand-default-named/Macros_Test_2.scala
@@ -0,0 +1,71 @@
+import scala.language.experimental.macros
+
+object Test extends App {
+ def one(x: Int = 2, y: Int = -40): Unit = macro Impls.one
+ one(2, -40)
+ one(y = -40, x = 2)
+ one(x = 2, y = -40)
+ one(x = 100)
+ one(y = 100)
+ one(100)
+ one()
+ var qualone = this
+ qualone.one(2, -40)
+ qualone.one(y = -40, x = 2)
+ qualone.one(x = 2, y = -40)
+ qualone.one(x = 100)
+ qualone.one(y = 100)
+ qualone.one(100)
+ qualone.one()
+
+ def onezero(x: Int = 2, y: Int = -40)(z: Int, w: Int): Unit = macro Impls.onezero
+ onezero(2, -40)(1, 2)
+ onezero(y = -40, x = 2)(3, 4)
+ onezero(x = 2, y = -40)(5, 6)
+ onezero(x = 100)(7, 8)
+ onezero(y = 100)(9, 10)
+ onezero(100)(11, 12)
+ onezero()(13, 14)
+ var qualonezero = this
+ qualonezero.onezero(2, -40)(15, 16)
+ qualonezero.onezero(y = -40, x = 2)(17, 18)
+ qualonezero.onezero(x = 2, y = -40)(19, 20)
+ qualonezero.onezero(x = 100)(21, 22)
+ qualonezero.onezero(y = 100)(23, 24)
+ qualonezero.onezero(100)(25, 26)
+ qualonezero.onezero()(27, 28)
+
+ def zeroone(x: Int, y: Int)(z: Int = 2, w: Int = -40): Unit = macro Impls.zeroone
+ zeroone(1, 2)(2, -40)
+ zeroone(3, 4)(w = -40, z = 2)
+ zeroone(5, 6)(z = 2, w = -40)
+ zeroone(7, 8)(z = 100)
+ zeroone(9, 10)(w = 100)
+ zeroone(11, 12)(100)
+ zeroone(13, 14)()
+ var qualzeroone = this
+ qualzeroone.zeroone(15, 16)(2, -40)
+ qualzeroone.zeroone(17, 18)(w = -40, z = 2)
+ qualzeroone.zeroone(19, 20)(z = 2, w = -40)
+ qualzeroone.zeroone(21, 22)(z = 100)
+ qualzeroone.zeroone(23, 24)(w = 100)
+ qualzeroone.zeroone(25, 26)(100)
+ qualzeroone.zeroone(27, 28)()
+
+ def oneone(x: Int = 2, y: Int = -40)(z: Int = 2, w: Int = -40): Unit = macro Impls.oneone
+ oneone(2, -40)(2, -40)
+ oneone(y = -40, x = 2)(w = -40, z = 2)
+ oneone(x = 2, y = -40)(z = 2, w = -40)
+ oneone(x = 100)(z = 100)
+ oneone(y = 100)(w = 100)
+ oneone(100)(100)
+ oneone()()
+ var qualoneone = this
+ qualoneone.oneone(2, -40)(2, -40)
+ qualoneone.oneone(y = -40, x = 2)(w = -40, z = 2)
+ qualoneone.oneone(x = 2, y = -40)(z = 2, w = -40)
+ qualoneone.oneone(x = 100)(z = 100)
+ qualoneone.oneone(y = 100)(w = 100)
+ qualoneone.oneone(100)(100)
+ qualoneone.oneone()()
+} \ No newline at end of file
diff --git a/test/files/run/macro-expand-ownerchain-a.check b/test/files/run/macro-expand-ownerchain-a.check
new file mode 100644
index 0000000000..51993f072d
--- /dev/null
+++ b/test/files/run/macro-expand-ownerchain-a.check
@@ -0,0 +1,2 @@
+2
+2
diff --git a/test/files/run/macro-expand-ownerchain-a/Macros_1.scala b/test/files/run/macro-expand-ownerchain-a/Macros_1.scala
new file mode 100644
index 0000000000..0d11c24ad1
--- /dev/null
+++ b/test/files/run/macro-expand-ownerchain-a/Macros_1.scala
@@ -0,0 +1,11 @@
+import scala.reflect.macros.whitebox._
+import scala.language.experimental.macros
+
+object Macros {
+ def impl(c: Context)(x: c.Tree, y: c.Tree) = {
+ import c.universe._
+ q"println($x)"
+ }
+
+ def foo(x: Int, y: Int): Unit = macro impl
+} \ No newline at end of file
diff --git a/test/files/run/macro-expand-ownerchain-a/Test_2.scala b/test/files/run/macro-expand-ownerchain-a/Test_2.scala
new file mode 100644
index 0000000000..738afc75df
--- /dev/null
+++ b/test/files/run/macro-expand-ownerchain-a/Test_2.scala
@@ -0,0 +1,4 @@
+object Test extends App {
+ Macros.foo(y = 1, x = ((x: Int) => x)(2))
+ Macros.foo(y = 1, x = {val x = 2; x})
+} \ No newline at end of file
diff --git a/test/files/run/macro-invalidusage-partialapplication-with-tparams.check b/test/files/run/macro-invalidusage-partialapplication-with-tparams.check
index 6cbcb9e5af..f1061e00f7 100644
--- a/test/files/run/macro-invalidusage-partialapplication-with-tparams.check
+++ b/test/files/run/macro-invalidusage-partialapplication-with-tparams.check
@@ -1,3 +1,3 @@
reflective compilation has failed:
-too few argument lists for macro invocation
+missing arguments for macro method foo in object Macros
diff --git a/test/files/run/macro-invalidusage-partialapplication.check b/test/files/run/macro-invalidusage-partialapplication.check
index 6cbcb9e5af..f1061e00f7 100644
--- a/test/files/run/macro-invalidusage-partialapplication.check
+++ b/test/files/run/macro-invalidusage-partialapplication.check
@@ -1,3 +1,3 @@
reflective compilation has failed:
-too few argument lists for macro invocation
+missing arguments for macro method foo in object Macros
diff --git a/test/files/run/reify-repl-fail-gracefully.check b/test/files/run/reify-repl-fail-gracefully.check
index 29ccee3cc6..c78d95dbed 100644
--- a/test/files/run/reify-repl-fail-gracefully.check
+++ b/test/files/run/reify-repl-fail-gracefully.check
@@ -10,7 +10,7 @@ import scala.reflect.runtime.universe._
scala>
scala> reify
-<console>:12: error: too few argument lists for macro invocation
+<console>:12: error: missing arguments for macro method reify in class Universe
reify
^
diff --git a/test/pending/run/macro-expand-default.flags b/test/pending/run/macro-expand-default.flags
deleted file mode 100644
index cd66464f2f..0000000000
--- a/test/pending/run/macro-expand-default.flags
+++ /dev/null
@@ -1 +0,0 @@
--language:experimental.macros \ No newline at end of file
diff --git a/test/pending/run/macro-expand-default/Impls_1.scala b/test/pending/run/macro-expand-default/Impls_1.scala
deleted file mode 100644
index fd5d8d7f18..0000000000
--- a/test/pending/run/macro-expand-default/Impls_1.scala
+++ /dev/null
@@ -1,10 +0,0 @@
-import scala.reflect.macros.blackbox.Context
-
-object Impls {
- def foo(c: Context)(x: c.Expr[Int], y: c.Expr[Int]) = {
- import c.universe._
- val sum = Apply(Select(x.tree, TermName("$minus")), List(y.tree))
- val body = Apply(Select(Ident(definitions.PredefModule), TermName("println")), List(sum))
- Expr[Unit](body)
- }
-} \ No newline at end of file
diff --git a/test/pending/run/macro-expand-default/Macros_Test_2.scala b/test/pending/run/macro-expand-default/Macros_Test_2.scala
deleted file mode 100644
index 92fe84d04a..0000000000
--- a/test/pending/run/macro-expand-default/Macros_Test_2.scala
+++ /dev/null
@@ -1,8 +0,0 @@
-object Test extends App {
- def foo(x: Int = 2, y: Int = -40) = macro Impls.foo
- foo(y = -40, x = 2)
- foo(x = 2, y = -40)
- foo(x = 100)
- foo(y = 100)
- foo()
-} \ No newline at end of file
diff --git a/test/pending/run/macro-expand-named.flags b/test/pending/run/macro-expand-named.flags
deleted file mode 100644
index cd66464f2f..0000000000
--- a/test/pending/run/macro-expand-named.flags
+++ /dev/null
@@ -1 +0,0 @@
--language:experimental.macros \ No newline at end of file
diff --git a/test/pending/run/macro-expand-named/Impls_1.scala b/test/pending/run/macro-expand-named/Impls_1.scala
deleted file mode 100644
index fd5d8d7f18..0000000000
--- a/test/pending/run/macro-expand-named/Impls_1.scala
+++ /dev/null
@@ -1,10 +0,0 @@
-import scala.reflect.macros.blackbox.Context
-
-object Impls {
- def foo(c: Context)(x: c.Expr[Int], y: c.Expr[Int]) = {
- import c.universe._
- val sum = Apply(Select(x.tree, TermName("$minus")), List(y.tree))
- val body = Apply(Select(Ident(definitions.PredefModule), TermName("println")), List(sum))
- Expr[Unit](body)
- }
-} \ No newline at end of file
diff --git a/test/pending/run/macro-expand-named/Macros_Test_2.scala b/test/pending/run/macro-expand-named/Macros_Test_2.scala
deleted file mode 100644
index abebcf8448..0000000000
--- a/test/pending/run/macro-expand-named/Macros_Test_2.scala
+++ /dev/null
@@ -1,5 +0,0 @@
-object Test extends App {
- def foo(x: Int, y: Int) = macro Impls.foo
- foo(y = -40, x = 2)
- foo(x = 2, y = -40)
-} \ No newline at end of file