diff options
author | Noam Postavsky <npostavs@gmail.com> | 2017-11-13 12:46:13 -0500 |
---|---|---|
committer | Noam Postavsky <npostavs@gmail.com> | 2017-12-13 17:31:27 -0500 |
commit | e7b1111155b3116d0c7b137e0e1d312db0f1ca80 (patch) | |
tree | 30240245d971e634ed1ec0f60733fe6dde2e1421 /lisp/emacs-lisp | |
parent | 4cb8696e4754d815efd5fd5e26f2b6b2567a11fe (diff) | |
download | emacs-e7b1111155b3116d0c7b137e0e1d312db0f1ca80.tar.gz emacs-e7b1111155b3116d0c7b137e0e1d312db0f1ca80.tar.bz2 emacs-e7b1111155b3116d0c7b137e0e1d312db0f1ca80.zip |
Mention new strictness for &optional, &rest in arglists (Bug#29165)
* etc/NEWS: Explain that '&optional' not followed by a variable is now
an error.
* lisp/emacs-lisp/cl-macs.el (cl--transform-lambda, cl--do-&aux)
(cl--do-arglist): Also reject '&optional', '&rest', or '&aux' not
followed by a variable for consistency.
* test/lisp/emacs-lisp/cl-macs-tests.el (cl-macs-bad-arglist): New
test.
Diffstat (limited to 'lisp/emacs-lisp')
-rw-r--r-- | lisp/emacs-lisp/cl-macs.el | 38 |
1 files changed, 27 insertions, 11 deletions
diff --git a/lisp/emacs-lisp/cl-macs.el b/lisp/emacs-lisp/cl-macs.el index 5535100d4ae..6aed060cb50 100644 --- a/lisp/emacs-lisp/cl-macs.el +++ b/lisp/emacs-lisp/cl-macs.el @@ -281,8 +281,13 @@ FORM is of the form (ARGS . BODY)." (or (not optional) ;; Optional args whose default is nil are simple. (null (nth 1 (assq (car args) (cdr cl--bind-defs))))) - (not (and (eq (car args) '&optional) (setq optional t) - (car cl--bind-defs)))) + (not (and (eq (car args) '&optional) + (progn + (when (memq (cadr args) + '(nil &rest &body &key &aux)) + (error "Variable missing after &optional")) + (setq optional t) + (car cl--bind-defs))))) (push (pop args) simple-args)) (when optional (if args (push '&optional args)) @@ -534,14 +539,17 @@ its argument list allows full Common Lisp conventions." arglist)))) (defun cl--do-&aux (args) - (while (and (eq (car args) '&aux) (pop args)) - (while (and args (not (memq (car args) cl--lambda-list-keywords))) - (if (consp (car args)) - (if (and cl--bind-enquote (cl-cadar args)) - (cl--do-arglist (caar args) - `',(cadr (pop args))) - (cl--do-arglist (caar args) (cadr (pop args)))) - (cl--do-arglist (pop args) nil)))) + (when (eq (car args) '&aux) + (pop args) + (when (null args) + (error "Variable missing after &aux"))) + (while (and args (not (memq (car args) cl--lambda-list-keywords))) + (if (consp (car args)) + (if (and cl--bind-enquote (cl-cadar args)) + (cl--do-arglist (caar args) + `',(cadr (pop args))) + (cl--do-arglist (caar args) (cadr (pop args)))) + (cl--do-arglist (pop args) nil))) (if args (error "Malformed argument list ends with: %S" args))) (defun cl--do-arglist (args expr &optional num) ; uses cl--bind-* @@ -558,6 +566,9 @@ its argument list allows full Common Lisp conventions." (keys nil) (laterarg nil) (exactarg nil) minarg) (or num (setq num 0)) + (when (and restarg (or (null (cdr restarg)) + (memq (cadr restarg) cl--lambda-list-keywords))) + (error "Variable missing after &rest")) (setq restarg (if (listp (cadr restarg)) (make-symbol "--cl-rest--") (cadr restarg))) @@ -609,7 +620,12 @@ its argument list allows full Common Lisp conventions." `',cl--bind-block) (+ ,num (length ,restarg))))) cl--bind-forms))) - (while (and (eq (car args) '&key) (pop args)) + (while (eq (car args) '&key) + (pop args) + (when (or (null args) (memq (car args) cl--lambda-list-keywords)) + (error "Missing variable after &key")) + (when keys + (error "Multiple occurrences of &key")) (while (and args (not (memq (car args) cl--lambda-list-keywords))) (let ((arg (pop args))) (or (consp arg) (setq arg (list arg))) |