From c6bf11c281553121aaf0fc8686c75bd15dcb3a92 Mon Sep 17 00:00:00 2001
From: Stefan Monnier <monnier@iro.umontreal.ca>
Date: Wed, 8 Dec 2021 16:58:24 -0500
Subject: * test/lisp/emacs-lisp/subr-x-tests.el (subr-x-named-let): New test

---
 test/lisp/emacs-lisp/subr-x-tests.el | 20 +++++++++++++++++++-
 1 file changed, 19 insertions(+), 1 deletion(-)

(limited to 'test/lisp/emacs-lisp/subr-x-tests.el')

diff --git a/test/lisp/emacs-lisp/subr-x-tests.el b/test/lisp/emacs-lisp/subr-x-tests.el
index d8369506000..821b6770ba0 100644
--- a/test/lisp/emacs-lisp/subr-x-tests.el
+++ b/test/lisp/emacs-lisp/subr-x-tests.el
@@ -676,7 +676,7 @@
       (buffer-string))
     "foo\n")))
 
-(ert-deftest test-add-display-text-property ()
+(ert-deftest subr-x-test-add-display-text-property ()
   (with-temp-buffer
     (insert "Foo bar zot gazonk")
     (add-display-text-property 4 8 'height 2.0)
@@ -694,5 +694,23 @@
                    [(raise 0.5) (height 2.0)]))
     (should (equal (get-text-property 9 'display) '(raise 0.5)))))
 
+(ert-deftest subr-x-named-let ()
+  (let ((funs ()))
+    (named-let loop
+        ((rest '(1 42 3))
+         (sum 0))
+      (when rest
+        ;; Here, we make sure that the variables are distinct in every
+        ;; iteration, since a naive tail-call optimization would tend to end up
+        ;; with a single `sum' variable being shared by all the closures.
+        (push (lambda () sum) funs)
+        ;; Here we add a dummy `sum' variable which shadows the `sum' iteration
+        ;; variable since a naive tail-call optimization could also trip here
+        ;; thinking it can `(setq sum ...)' to set the iteration
+        ;; variable's value.
+        (let ((sum sum))
+          (loop (cdr rest) (+ sum (car rest))))))
+    (should (equal (mapcar #'funcall funs) '(43 1 0)))))
+
 (provide 'subr-x-tests)
 ;;; subr-x-tests.el ends here
-- 
cgit v1.2.3