diff --git a/lisp/emacs-lisp/let-alist.el b/lisp/emacs-lisp/let-alist.el index 3507a395436..d7069174c1b 100644 --- a/lisp/emacs-lisp/let-alist.el +++ b/lisp/emacs-lisp/let-alist.el @@ -76,6 +76,11 @@ symbol, and each cdr is the same symbol without the `.'." ;; with other results in the clause below. (list (cons data (intern (replace-match "" nil nil name))))))) ((not (consp data)) nil) + ((eq (car data) 'let-alist) + ;; For nested ‘let-alist’ forms, ignore symbols appearing in the + ;; inner body because they don’t refer to the alist currently + ;; being processed. See Bug#24641. + (let-alist--deep-dot-search (cadr data))) (t (append (let-alist--deep-dot-search (car data)) (let-alist--deep-dot-search (cdr data)))))) diff --git a/test/lisp/emacs-lisp/let-alist-tests.el b/test/lisp/emacs-lisp/let-alist-tests.el index 80d418cabbe..657a27a67dc 100644 --- a/test/lisp/emacs-lisp/let-alist-tests.el +++ b/test/lisp/emacs-lisp/let-alist-tests.el @@ -88,4 +88,12 @@ '(cdr (assq 'baz (cdr (assq 'bar (cdr (assq 'foo var)))))))) (should (equal (let-alist--access-sexp '..foo.bar.baz 'var) '.foo.bar.baz))) +(ert-deftest let-alist--deep-dot-search--nested () + "Check that nested `let-alist' forms don't generate spurious bindings. +See Bug#24641." + (should (equal (let-alist--deep-dot-search '(foo .bar (baz .qux))) + '((.bar . bar) (.qux . qux)))) + (should (equal (let-alist--deep-dot-search '(foo .bar (let-alist .qux .baz))) + '((.bar . bar) (.qux . qux))))) ; no .baz + ;;; let-alist.el ends here