diff options
author | Eugene Burmako <xeno.by@gmail.com> | 2014-01-22 13:18:35 +0300 |
---|---|---|
committer | Eugene Burmako <xeno.by@gmail.com> | 2014-02-10 09:16:35 +0100 |
commit | a02e053a5dec134f7c7dc53a2c1091039218237d (patch) | |
tree | 13d71007d47b02b2dea80bcdc9d3609ad0aad9c6 /test/files/neg | |
parent | d2a1dd59c264947137669f4dbda20d89b26743af (diff) | |
download | scala-a02e053a5dec134f7c7dc53a2c1091039218237d.tar.gz scala-a02e053a5dec134f7c7dc53a2c1091039218237d.tar.bz2 scala-a02e053a5dec134f7c7dc53a2c1091039218237d.zip |
SI-5920 enables default and named args in macros
When producing an initial spec for macros two years ago, we sort of glossed
over named/default arguments in macro applications, leaving them for future work.
Once the aforementioned future has come, I’ve made several attempts at
making things operational (e.g. last summer), but it’s always been unclear
how to marry the quite complex desugaring that tryNamesDefaults performs
with the expectations of macro programmers to see unsugared trees
in macro impl parameters.
Here’s the list of problems that arise when trying to encode named/default
arguments of macro applications:
1) When inside macro impls we don’t really care about synthetic vals
that are typically introduced to preserve evaluation order in non-positional
method applications. When we inline those synthetics, we lose information
about evaluation order, which is something that we wouldn’t like to lose
in the general case.
2) More importantly, it’s also not very exciting to see invocations of
default getters that stand for unspecified default arguments. Ideally,
we would like to provide macro programmers with right-hand sides of those
default getters, but that is: a) impossible in the current implementation
of default parameters, b) would anyway bring scoping problems that we’re
not ready to deal with just yet.
Being constantly unhappy with potential solutions to the aforementioned
problems, I’ve been unable to nail this down until the last weekend,
when I realized that: 1) even though we can’t express potential twists in
evaluation order within linearly ordered macro impl params, we can use
c.macroApplication to store all the named arguments we want, 2) even though
we can’t get exactly what we want for default arguments, we can represent
them with EmptyTree’s, which is not ideal, but pretty workable. That’s
what has been put into life in this commit.
As a pleasant side-effect, now the macro engine doesn’t have to reinvent
the wheel wrt reporting errors about insufficient arg or arglist count.
Since this logic is intertwined with the tryNamesDefaults desugaring,
we previously couldn’t make use of it and had to roll our own logic
that checked that the number of arguments and parameters of macro applications
correspond to each other. Now it’s all deduplicated and consistent.
Diffstat (limited to 'test/files/neg')
-rw-r--r-- | test/files/neg/macro-argc-mismatch.check | 49 | ||||
-rw-r--r-- | test/files/neg/macro-argc-mismatch/Macros_1.scala | 16 | ||||
-rw-r--r-- | test/files/neg/macro-argc-mismatch/Test_2.scala | 19 | ||||
-rw-r--r-- | test/files/neg/macro-invalidusage-badargs.check | 5 | ||||
-rw-r--r-- | test/files/neg/macro-qmarkqmarkqmark.check | 2 | ||||
-rw-r--r-- | test/files/neg/t7157.check | 36 |
6 files changed, 112 insertions, 15 deletions
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 |