aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lisp/emacs-lisp/cl-macs.el32
-rw-r--r--test/lisp/emacs-lisp/cl-macs-tests.el8
2 files changed, 33 insertions, 7 deletions
diff --git a/lisp/emacs-lisp/cl-macs.el b/lisp/emacs-lisp/cl-macs.el
index 9af014cf8e9..43eb4261162 100644
--- a/lisp/emacs-lisp/cl-macs.el
+++ b/lisp/emacs-lisp/cl-macs.el
@@ -892,7 +892,7 @@ This is compatible with Common Lisp, but note that `defun' and
892(defvar cl--loop-name) 892(defvar cl--loop-name)
893(defvar cl--loop-result) (defvar cl--loop-result-explicit) 893(defvar cl--loop-result) (defvar cl--loop-result-explicit)
894(defvar cl--loop-result-var) (defvar cl--loop-steps) 894(defvar cl--loop-result-var) (defvar cl--loop-steps)
895(defvar cl--loop-symbol-macs) 895(defvar cl--loop-symbol-macs) (defvar cl--loop-guard-cond)
896 896
897(defun cl--loop-set-iterator-function (kind iterator) 897(defun cl--loop-set-iterator-function (kind iterator)
898 (if cl--loop-iterator-function 898 (if cl--loop-iterator-function
@@ -961,7 +961,7 @@ For more details, see Info node `(cl)Loop Facility'.
961 (cl--loop-accum-var nil) (cl--loop-accum-vars nil) 961 (cl--loop-accum-var nil) (cl--loop-accum-vars nil)
962 (cl--loop-initially nil) (cl--loop-finally nil) 962 (cl--loop-initially nil) (cl--loop-finally nil)
963 (cl--loop-iterator-function nil) (cl--loop-first-flag nil) 963 (cl--loop-iterator-function nil) (cl--loop-first-flag nil)
964 (cl--loop-symbol-macs nil)) 964 (cl--loop-symbol-macs nil) (cl--loop-guard-cond nil))
965 ;; Here is more or less how those dynbind vars are used after looping 965 ;; Here is more or less how those dynbind vars are used after looping
966 ;; over cl--parse-loop-clause: 966 ;; over cl--parse-loop-clause:
967 ;; 967 ;;
@@ -996,7 +996,24 @@ For more details, see Info node `(cl)Loop Facility'.
996 (list (or cl--loop-result-explicit 996 (list (or cl--loop-result-explicit
997 cl--loop-result)))) 997 cl--loop-result))))
998 (ands (cl--loop-build-ands (nreverse cl--loop-body))) 998 (ands (cl--loop-build-ands (nreverse cl--loop-body)))
999 (while-body (nconc (cadr ands) (nreverse cl--loop-steps))) 999 (while-body
1000 (nconc
1001 (cadr ands)
1002 (if (or (not cl--loop-guard-cond) (not cl--loop-first-flag))
1003 (nreverse cl--loop-steps)
1004 ;; Right after update the loop variable ensure that the loop
1005 ;; condition, i.e. (car ands), is still satisfied; otherwise,
1006 ;; set `cl--loop-first-flag' nil and skip the remaining
1007 ;; body forms (#Bug#29799).
1008 ;;
1009 ;; (last cl--loop-steps) updates the loop var
1010 ;; (car (butlast cl--loop-steps)) sets `cl--loop-first-flag' nil
1011 ;; (nreverse (cdr (butlast cl--loop-steps))) are the
1012 ;; remaining body forms.
1013 (append (last cl--loop-steps)
1014 `((and ,(car ands)
1015 ,@(nreverse (cdr (butlast cl--loop-steps)))))
1016 `(,(car (butlast cl--loop-steps)))))))
1000 (body (append 1017 (body (append
1001 (nreverse cl--loop-initially) 1018 (nreverse cl--loop-initially)
1002 (list (if cl--loop-iterator-function 1019 (list (if cl--loop-iterator-function
@@ -1506,10 +1523,11 @@ For more details, see Info node `(cl)Loop Facility'.
1506 ,(cl--loop-let (nreverse loop-for-sets) 'setq ands) 1523 ,(cl--loop-let (nreverse loop-for-sets) 'setq ands)
1507 t) 1524 t)
1508 cl--loop-body)) 1525 cl--loop-body))
1509 (if loop-for-steps 1526 (when loop-for-steps
1510 (push (cons (if ands 'cl-psetq 'setq) 1527 (setq cl--loop-guard-cond t)
1511 (apply 'append (nreverse loop-for-steps))) 1528 (push (cons (if ands 'cl-psetq 'setq)
1512 cl--loop-steps)))) 1529 (apply 'append (nreverse loop-for-steps)))
1530 cl--loop-steps))))
1513 1531
1514 ((eq word 'repeat) 1532 ((eq word 'repeat)
1515 (let ((temp (make-symbol "--cl-var--"))) 1533 (let ((temp (make-symbol "--cl-var--")))
diff --git a/test/lisp/emacs-lisp/cl-macs-tests.el b/test/lisp/emacs-lisp/cl-macs-tests.el
index f0bde7af397..edb1530cad5 100644
--- a/test/lisp/emacs-lisp/cl-macs-tests.el
+++ b/test/lisp/emacs-lisp/cl-macs-tests.el
@@ -497,4 +497,12 @@ collection clause."
497 vconcat (vector (1+ x))) 497 vconcat (vector (1+ x)))
498 [2 3 4 5 6]))) 498 [2 3 4 5 6])))
499 499
500
501(ert-deftest cl-macs-loop-for-as-equals-and ()
502 "Test for https://debbugs.gnu.org/29799 ."
503 (let ((arr (make-vector 3 0)))
504 (should (equal '((0 0) (1 1) (2 2))
505 (cl-loop for k below 3 for x = k and z = (elt arr k)
506 collect (list k x))))))
507
500;;; cl-macs-tests.el ends here 508;;; cl-macs-tests.el ends here