From 1dcb737405a7a299fe6d01a5d9bd0c79328920b7 Mon Sep 17 00:00:00 2001 From: Mattias EngdegÄrd Date: Thu, 27 Apr 2023 12:38:58 +0200 Subject: Don't rewrite (nconc X nil) -> X for any X (bug#63103) Since the last cdr of a non-terminal argument to `nconc` is overwritten no matter its value: (nconc (cons 1 2) nil) => (1) a terminating nil arg cannot just be eliminated unconditionally. * lisp/emacs-lisp/byte-opt.el (byte-optimize-nconc): Only eliminate a terminal nil arg to `nconc` if preceded by a nonempty proper list. Right now we only bother to prove this for `(list ...)`, so that (nconc (list 1 2 3) nil) -> (list 1 2 3) * test/lisp/emacs-lisp/bytecomp-tests.el (bytecomp-tests--test-cases): Add test cases. --- lisp/emacs-lisp/byte-opt.el | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'lisp/emacs-lisp/byte-opt.el') diff --git a/lisp/emacs-lisp/byte-opt.el b/lisp/emacs-lisp/byte-opt.el index da997212eef..0f7a3cb2665 100644 --- a/lisp/emacs-lisp/byte-opt.el +++ b/lisp/emacs-lisp/byte-opt.el @@ -1531,7 +1531,16 @@ See Info node `(elisp) Integer Basics'." (prev (car newargs))) (cond ;; Elide null args. - ((null arg) (loop (cdr args) newargs)) + ((and (null arg) + ;; Don't elide a terminal nil unless preceded by + ;; a nonempty proper list, since that will have + ;; its last cdr forced to nil. + (or (cdr args) + ;; FIXME: prove the 'nonempty proper list' property + ;; for more forms than just `list', such as + ;; `append', `mapcar' etc. + (eq 'list (car-safe (car newargs))))) + (loop (cdr args) newargs)) ;; Merge consecutive `list' args. ((and (eq (car-safe arg) 'list) (eq (car-safe prev) 'list)) -- cgit v1.2.3