diff options
| author | Noam Postavsky | 2018-01-20 11:27:23 -0500 |
|---|---|---|
| committer | Noam Postavsky | 2018-03-25 07:56:35 -0400 |
| commit | 1d47d777ef24c0be9153b0a1c8ba21918fa1025a (patch) | |
| tree | 7593519d0bd65a885f8daeaaa3f15b2b9eb58301 /test/src | |
| parent | d73d1384aa6d647a930b4dfe3e91505da4ffee21 (diff) | |
| download | emacs-1d47d777ef24c0be9153b0a1c8ba21918fa1025a.tar.gz emacs-1d47d777ef24c0be9153b0a1c8ba21918fa1025a.zip | |
Allow `&rest' or `&optional' without following variable (Bug#29165)
This is sometimes convenient when writing macros, so that the empty
variable case doesn't need to be handled specially. Older versions of
Emacs accepted this in some cases (especially the interpreter in Emacs
25 and below was very accepting).
| interpreted/compiled |
| arglist | 25 & earlier | 26 | 27 |
|---------------------------+--------------+-----+-----|
| (&rest) | y/n | n/n | y/y |
| (&rest &rest) | y/n | n/n | n/n |
| (&rest &rest x) | y/n | n/n | n/n |
| (&rest x &rest) | y/n | n/n | n/n |
| (&rest x &rest y) | y/n | n/n | n/n |
|---------------------------+--------------+-----+-----|
| (&optional) | y/n | n/n | y/y |
| (&optional &optional) | y/n | n/n | n/n |
| (&optional x &optional) | y/n | n/n | n/n |
| (&optional x &optional y) | y/y | n/n | n/n |
|---------------------------+--------------+-----+-----|
| (&optional &rest) | y/n | n/n | y/y |
| (&optional x &rest) | y/n | n/n | y/y |
| (&optional &rest y) | y/y | n/n | y/y |
|---------------------------+--------------+-----+-----|
| (&rest &optional) | y/n | n/n | n/n |
| (&rest &optional y) | y/n | n/n | n/n |
| (&rest x &optional y) | y/n | n/n | n/n |
The values in the table above can be produced with the following code:
(with-current-buffer (get-buffer-create "*ck-args*")
(erase-buffer)
(dolist (arglist '((&rest)
(&rest &rest)
(&rest &rest x)
(&rest x &rest)
(&rest x &rest y)
(&optional)
(&optional &optional)
(&optional x &optional)
(&optional x &optional y)
(&optional &rest)
(&optional x &rest)
(&optional &rest y)
(&rest &optional)
(&rest &optional y)
(&rest x &optional y)))
(insert
(format "%c/%c\n"
(condition-case err
(progn (funcall `(lambda ,arglist 'ok))
?y)
(error ?n))
(condition-case err
(progn (byte-compile-check-lambda-list arglist)
?y)
(error ?n))))
(display-buffer (current-buffer))))
* src/eval.c (funcall_lambda):
* lisp/emacs-lisp/bytecomp.el (byte-compile-check-lambda-list): Don't
check for missing variables after `&rest' and `&optional'.
* test/src/eval-tests.el (eval-tests--bugs-24912-and-24913)
(eval-tests-accept-empty-optional-rest): Update tests accordingly.
* etc/NEWS: Update announcement accordingly.
* doc/lispref/functions.texi (Argument List): Update manual to
indicate that variable names are optional.
Diffstat (limited to 'test/src')
| -rw-r--r-- | test/src/eval-tests.el | 20 |
1 files changed, 17 insertions, 3 deletions
diff --git a/test/src/eval-tests.el b/test/src/eval-tests.el index e68fd136113..59da6b7cc30 100644 --- a/test/src/eval-tests.el +++ b/test/src/eval-tests.el | |||
| @@ -37,8 +37,7 @@ | |||
| 37 | (ert-deftest eval-tests--bugs-24912-and-24913 () | 37 | (ert-deftest eval-tests--bugs-24912-and-24913 () |
| 38 | "Check that Emacs doesn't accept weird argument lists. | 38 | "Check that Emacs doesn't accept weird argument lists. |
| 39 | Bug#24912 and Bug#24913." | 39 | Bug#24912 and Bug#24913." |
| 40 | (dolist (args '((&optional) (&rest) (&optional &rest) (&rest &optional) | 40 | (dolist (args '((&rest &optional) |
| 41 | (&optional &rest a) (&optional a &rest) | ||
| 42 | (&rest a &optional) (&rest &optional a) | 41 | (&rest a &optional) (&rest &optional a) |
| 43 | (&optional &optional) (&optional &optional a) | 42 | (&optional &optional) (&optional &optional a) |
| 44 | (&optional a &optional b) | 43 | (&optional a &optional b) |
| @@ -47,7 +46,22 @@ Bug#24912 and Bug#24913." | |||
| 47 | (should-error (eval `(funcall (lambda ,args)) t) :type 'invalid-function) | 46 | (should-error (eval `(funcall (lambda ,args)) t) :type 'invalid-function) |
| 48 | (should-error (byte-compile-check-lambda-list args)) | 47 | (should-error (byte-compile-check-lambda-list args)) |
| 49 | (let ((byte-compile-debug t)) | 48 | (let ((byte-compile-debug t)) |
| 50 | (should-error (eval `(byte-compile (lambda ,args)) t))))) | 49 | (ert-info ((format "bytecomp: args = %S" args)) |
| 50 | (should-error (eval `(byte-compile (lambda ,args)) t)))))) | ||
| 51 | |||
| 52 | (ert-deftest eval-tests-accept-empty-optional-rest () | ||
| 53 | "Check that Emacs accepts empty &optional and &rest arglists. | ||
| 54 | Bug#24912." | ||
| 55 | (dolist (args '((&optional) (&rest) (&optional &rest) | ||
| 56 | (&optional &rest a) (&optional a &rest))) | ||
| 57 | (let ((fun `(lambda ,args 'ok))) | ||
| 58 | (ert-info ("eval") | ||
| 59 | (should (eq (funcall (eval fun t)) 'ok))) | ||
| 60 | (ert-info ("byte comp check") | ||
| 61 | (byte-compile-check-lambda-list args)) | ||
| 62 | (ert-info ("bytecomp") | ||
| 63 | (let ((byte-compile-debug t)) | ||
| 64 | (should (eq (funcall (byte-compile fun)) 'ok))))))) | ||
| 51 | 65 | ||
| 52 | 66 | ||
| 53 | (dolist (form '(let let*)) | 67 | (dolist (form '(let let*)) |