aboutsummaryrefslogtreecommitdiffstats
path: root/lisp
diff options
context:
space:
mode:
authorNoam Postavsky2017-11-13 12:46:13 -0500
committerNoam Postavsky2017-12-13 17:31:27 -0500
commite7b1111155b3116d0c7b137e0e1d312db0f1ca80 (patch)
tree30240245d971e634ed1ec0f60733fe6dde2e1421 /lisp
parent4cb8696e4754d815efd5fd5e26f2b6b2567a11fe (diff)
downloademacs-e7b1111155b3116d0c7b137e0e1d312db0f1ca80.tar.gz
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')
-rw-r--r--lisp/emacs-lisp/cl-macs.el38
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)."
281 (or (not optional) 281 (or (not optional)
282 ;; Optional args whose default is nil are simple. 282 ;; Optional args whose default is nil are simple.
283 (null (nth 1 (assq (car args) (cdr cl--bind-defs))))) 283 (null (nth 1 (assq (car args) (cdr cl--bind-defs)))))
284 (not (and (eq (car args) '&optional) (setq optional t) 284 (not (and (eq (car args) '&optional)
285 (car cl--bind-defs)))) 285 (progn
286 (when (memq (cadr args)
287 '(nil &rest &body &key &aux))
288 (error "Variable missing after &optional"))
289 (setq optional t)
290 (car cl--bind-defs)))))
286 (push (pop args) simple-args)) 291 (push (pop args) simple-args))
287 (when optional 292 (when optional
288 (if args (push '&optional args)) 293 (if args (push '&optional args))
@@ -534,14 +539,17 @@ its argument list allows full Common Lisp conventions."
534 arglist)))) 539 arglist))))
535 540
536(defun cl--do-&aux (args) 541(defun cl--do-&aux (args)
537 (while (and (eq (car args) '&aux) (pop args)) 542 (when (eq (car args) '&aux)
538 (while (and args (not (memq (car args) cl--lambda-list-keywords))) 543 (pop args)
539 (if (consp (car args)) 544 (when (null args)
540 (if (and cl--bind-enquote (cl-cadar args)) 545 (error "Variable missing after &aux")))
541 (cl--do-arglist (caar args) 546 (while (and args (not (memq (car args) cl--lambda-list-keywords)))
542 `',(cadr (pop args))) 547 (if (consp (car args))
543 (cl--do-arglist (caar args) (cadr (pop args)))) 548 (if (and cl--bind-enquote (cl-cadar args))
544 (cl--do-arglist (pop args) nil)))) 549 (cl--do-arglist (caar args)
550 `',(cadr (pop args)))
551 (cl--do-arglist (caar args) (cadr (pop args))))
552 (cl--do-arglist (pop args) nil)))
545 (if args (error "Malformed argument list ends with: %S" args))) 553 (if args (error "Malformed argument list ends with: %S" args)))
546 554
547(defun cl--do-arglist (args expr &optional num) ; uses cl--bind-* 555(defun cl--do-arglist (args expr &optional num) ; uses cl--bind-*
@@ -558,6 +566,9 @@ its argument list allows full Common Lisp conventions."
558 (keys nil) 566 (keys nil)
559 (laterarg nil) (exactarg nil) minarg) 567 (laterarg nil) (exactarg nil) minarg)
560 (or num (setq num 0)) 568 (or num (setq num 0))
569 (when (and restarg (or (null (cdr restarg))
570 (memq (cadr restarg) cl--lambda-list-keywords)))
571 (error "Variable missing after &rest"))
561 (setq restarg (if (listp (cadr restarg)) 572 (setq restarg (if (listp (cadr restarg))
562 (make-symbol "--cl-rest--") 573 (make-symbol "--cl-rest--")
563 (cadr restarg))) 574 (cadr restarg)))
@@ -609,7 +620,12 @@ its argument list allows full Common Lisp conventions."
609 `',cl--bind-block) 620 `',cl--bind-block)
610 (+ ,num (length ,restarg))))) 621 (+ ,num (length ,restarg)))))
611 cl--bind-forms))) 622 cl--bind-forms)))
612 (while (and (eq (car args) '&key) (pop args)) 623 (while (eq (car args) '&key)
624 (pop args)
625 (when (or (null args) (memq (car args) cl--lambda-list-keywords))
626 (error "Missing variable after &key"))
627 (when keys
628 (error "Multiple occurrences of &key"))
613 (while (and args (not (memq (car args) cl--lambda-list-keywords))) 629 (while (and args (not (memq (car args) cl--lambda-list-keywords)))
614 (let ((arg (pop args))) 630 (let ((arg (pop args)))
615 (or (consp arg) (setq arg (list arg))) 631 (or (consp arg) (setq arg (list arg)))