aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Monnier2017-11-27 12:45:16 -0500
committerStefan Monnier2017-11-27 12:45:16 -0500
commitcea0bca54f1fa3635591e24eba1017742b04abd0 (patch)
treee8e0c6051b9b48a83d25548d91e4ef775b05120c
parente896320f0e0c50aa31712b7f1bda4c4a78ff0f82 (diff)
downloademacs-cea0bca54f1fa3635591e24eba1017742b04abd0.tar.gz
emacs-cea0bca54f1fa3635591e24eba1017742b04abd0.zip
* lisp/emacs-lisp/cl-macs.el: Fix &key with no key arg
* test/lisp/emacs-lisp/cl-lib-tests.el (cl-lib-empty-keyargs): New test. * lisp/emacs-lisp/cl-macs.el (cl--do-arglist): Fix it.
-rw-r--r--lisp/emacs-lisp/cl-macs.el44
-rw-r--r--test/lisp/emacs-lisp/cl-lib-tests.el4
2 files changed, 31 insertions, 17 deletions
diff --git a/lisp/emacs-lisp/cl-macs.el b/lisp/emacs-lisp/cl-macs.el
index e313af24975..4069db53c93 100644
--- a/lisp/emacs-lisp/cl-macs.el
+++ b/lisp/emacs-lisp/cl-macs.el
@@ -555,7 +555,7 @@ its argument list allows full Common Lisp conventions."
555 (if (memq '&environment args) (error "&environment used incorrectly")) 555 (if (memq '&environment args) (error "&environment used incorrectly"))
556 (let ((restarg (memq '&rest args)) 556 (let ((restarg (memq '&rest args))
557 (safety (if (cl--compiling-file) cl--optimize-safety 3)) 557 (safety (if (cl--compiling-file) cl--optimize-safety 3))
558 (keys nil) 558 (keys t)
559 (laterarg nil) (exactarg nil) minarg) 559 (laterarg nil) (exactarg nil) minarg)
560 (or num (setq num 0)) 560 (or num (setq num 0))
561 (setq restarg (if (listp (cadr restarg)) 561 (setq restarg (if (listp (cadr restarg))
@@ -610,6 +610,7 @@ its argument list allows full Common Lisp conventions."
610 (+ ,num (length ,restarg))))) 610 (+ ,num (length ,restarg)))))
611 cl--bind-forms))) 611 cl--bind-forms)))
612 (while (and (eq (car args) '&key) (pop args)) 612 (while (and (eq (car args) '&key) (pop args))
613 (unless (listp keys) (setq keys nil))
613 (while (and args (not (memq (car args) cl--lambda-list-keywords))) 614 (while (and args (not (memq (car args) cl--lambda-list-keywords)))
614 (let ((arg (pop args))) 615 (let ((arg (pop args)))
615 (or (consp arg) (setq arg (list arg))) 616 (or (consp arg) (setq arg (list arg)))
@@ -648,23 +649,32 @@ its argument list allows full Common Lisp conventions."
648 `'(nil ,(cl--const-expr-val def)) 649 `'(nil ,(cl--const-expr-val def))
649 `(list nil ,def)))))))) 650 `(list nil ,def))))))))
650 (push karg keys))))) 651 (push karg keys)))))
651 (setq keys (nreverse keys)) 652 (when (consp keys) (setq keys (nreverse keys)))
652 (or (and (eq (car args) '&allow-other-keys) (pop args)) 653 (or (and (eq (car args) '&allow-other-keys) (pop args))
653 (null keys) (= safety 0) 654 (= safety 0)
654 (let* ((var (make-symbol "--cl-keys--")) 655 (cond
655 (allow '(:allow-other-keys)) 656 ((eq keys t) nil) ;No &keys at all
656 (check `(while ,var 657 ((null keys) ;A &key but no actual keys specified.
657 (cond 658 (push `(when ,restarg
658 ((memq (car ,var) ',(append keys allow)) 659 (error ,(format "Keyword argument %%s not one of %s"
659 (setq ,var (cdr (cdr ,var)))) 660 keys)
660 ((car (cdr (memq (quote ,@allow) ,restarg))) 661 (car ,restarg)))
661 (setq ,var nil)) 662 cl--bind-forms))
662 (t 663 (t
663 (error 664 (let* ((var (make-symbol "--cl-keys--"))
664 ,(format "Keyword argument %%s not one of %s" 665 (allow '(:allow-other-keys))
665 keys) 666 (check `(while ,var
666 (car ,var))))))) 667 (cond
667 (push `(let ((,var ,restarg)) ,check) cl--bind-forms))) 668 ((memq (car ,var) ',(append keys allow))
669 (setq ,var (cdr (cdr ,var))))
670 ((car (cdr (memq (quote ,@allow) ,restarg)))
671 (setq ,var nil))
672 (t
673 (error
674 ,(format "Keyword argument %%s not one of %s"
675 keys)
676 (car ,var)))))))
677 (push `(let ((,var ,restarg)) ,check) cl--bind-forms)))))
668 (cl--do-&aux args) 678 (cl--do-&aux args)
669 nil))) 679 nil)))
670 680
diff --git a/test/lisp/emacs-lisp/cl-lib-tests.el b/test/lisp/emacs-lisp/cl-lib-tests.el
index 13c9af9bd6d..ed85f5a0f66 100644
--- a/test/lisp/emacs-lisp/cl-lib-tests.el
+++ b/test/lisp/emacs-lisp/cl-lib-tests.el
@@ -201,6 +201,10 @@
201 :b :a :a 42) 201 :b :a :a 42)
202 '(42 :a)))) 202 '(42 :a))))
203 203
204(ert-deftest cl-lib-empty-keyargs ()
205 (should-error (funcall (cl-function (lambda (&key) 1))
206 :b 1)))
207
204(cl-defstruct (mystruct 208(cl-defstruct (mystruct
205 (:constructor cl-lib--con-1 (&aux (abc 1))) 209 (:constructor cl-lib--con-1 (&aux (abc 1)))
206 (:constructor cl-lib--con-2 (&optional def) "Constructor docstring.")) 210 (:constructor cl-lib--con-2 (&optional def) "Constructor docstring."))