From: Mattias EngdegÄrd Date: Sat, 25 Sep 2021 10:15:21 +0000 (+0200) Subject: Fix byte-compiler crash for legal dynamic-binding code X-Git-Tag: emacs-28.0.90~627 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=45c32d7f00e225a78e6c8b2251de335e93e556e0;p=emacs.git Fix byte-compiler crash for legal dynamic-binding code This should really be taken care of by a syntax normalisation step in the frontend, but there is no such step for non-lexbind code yet. * lisp/emacs-lisp/byte-opt.el (byte-optimize-letX): Tolerate bindingsa without initialising expressions. * test/lisp/emacs-lisp/bytecomp-tests.el (bytecomp-tests--test-cases): Add test cases. --- diff --git a/lisp/emacs-lisp/byte-opt.el b/lisp/emacs-lisp/byte-opt.el index c8a96fa22a9..c8990f23531 100644 --- a/lisp/emacs-lisp/byte-opt.el +++ b/lisp/emacs-lisp/byte-opt.el @@ -1367,17 +1367,24 @@ See Info node `(elisp) Integer Basics'." (and (consp binding) (cadr binding))) bindings) ,const) - `(let* ,(butlast bindings) ,(cadar (last bindings)) ,const))) + `(let* ,(butlast bindings) + ,@(and (consp (car (last bindings))) + (cdar (last bindings))) + ,const))) ;; Body is last variable. - (`(,head ,bindings ,(and var (pred symbolp) (pred (not keywordp)) - (pred (not booleanp)) - (guard (eq var (caar (last bindings)))))) + (`(,head ,(and bindings + (let last-var (let ((last (car (last bindings)))) + (if (consp last) (car last) last)))) + ,(and last-var ; non-linear pattern + (pred symbolp) (pred (not keywordp)) (pred (not booleanp)))) (if (eq head 'let) `(progn ,@(mapcar (lambda (binding) (and (consp binding) (cadr binding))) bindings)) - `(let* ,(butlast bindings) ,(cadar (last bindings))))) + `(let* ,(butlast bindings) + ,@(and (consp (car (last bindings))) + (cdar (last bindings)))))) (_ form))) diff --git a/test/lisp/emacs-lisp/bytecomp-tests.el b/test/lisp/emacs-lisp/bytecomp-tests.el index ded6351c5ee..d56c60b1f1d 100644 --- a/test/lisp/emacs-lisp/bytecomp-tests.el +++ b/test/lisp/emacs-lisp/bytecomp-tests.el @@ -573,6 +573,14 @@ inner loops respectively." (let ((_a 1) (_b 2)) 'z) + (let (x y) + y) + (let* (x y) + y) + (let (x y) + 'a) + (let* (x y) + 'a) ;; Check empty-list optimisations. (mapcar (lambda (x) (member x nil)) '("a" 2 nil))