diff options
| author | Mattias EngdegÄrd <mattiase@acm.org> | 2021-09-23 12:43:41 +0200 |
|---|---|---|
| committer | Mattias EngdegÄrd <mattiase@acm.org> | 2021-09-25 20:25:01 +0200 |
| commit | ed02b88bbae18caad650d76876940ffb58cab554 (patch) | |
| tree | 36512b017e92a76a37c63606821274bd35366924 /src | |
| parent | 80fddff5d64ff915651eb751685b7430de00c536 (diff) | |
Renege on anonymous &rest (bug#50268, bug#50720)
Allowing &rest without a variable name following turned out not to be
very useful, and it never worked properly. Disallow it.
* lisp/emacs-lisp/bytecomp.el (byte-compile-check-lambda-list):
* src/eval.c (funcall_lambda):
Signal error for &rest without variable name.
* doc/lispref/functions.texi (Argument List): Adjust manual.
* etc/NEWS (file): Announce.
* test/src/eval-tests.el (eval-tests--bugs-24912-and-24913):
Extend test, also checking with and without lexical binding.
(eval-tests-accept-empty-optional-rest): Reduce to...
(eval-tests-accept-empty-optional): ...this, again checking
with and without lexical binding.
Diffstat (limited to 'src')
| -rw-r--r-- | src/eval.c | 9 |
1 files changed, 6 insertions, 3 deletions
diff --git a/src/eval.c b/src/eval.c index 2bb7cfe6002..66d34808f82 100644 --- a/src/eval.c +++ b/src/eval.c @@ -3245,6 +3245,7 @@ funcall_lambda (Lisp_Object fun, ptrdiff_t nargs, emacs_abort (); i = optional = rest = 0; + bool previous_rest = false; for (; CONSP (syms_left); syms_left = XCDR (syms_left)) { maybe_quit (); @@ -3255,13 +3256,14 @@ funcall_lambda (Lisp_Object fun, ptrdiff_t nargs, if (EQ (next, Qand_rest)) { - if (rest) + if (rest || previous_rest) xsignal1 (Qinvalid_function, fun); rest = 1; + previous_rest = true; } else if (EQ (next, Qand_optional)) { - if (optional || rest) + if (optional || rest || previous_rest) xsignal1 (Qinvalid_function, fun); optional = 1; } @@ -3287,10 +3289,11 @@ funcall_lambda (Lisp_Object fun, ptrdiff_t nargs, else /* Dynamically bind NEXT. */ specbind (next, arg); + previous_rest = false; } } - if (!NILP (syms_left)) + if (!NILP (syms_left) || previous_rest) xsignal1 (Qinvalid_function, fun); else if (i < nargs) xsignal2 (Qwrong_number_of_arguments, fun, make_fixnum (nargs)); |
