From 1dcb737405a7a299fe6d01a5d9bd0c79328920b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mattias=20Engdeg=C3=A5rd?= Date: Thu, 27 Apr 2023 12:38:58 +0200 Subject: [PATCH 1/4] 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 ++++++++++- test/lisp/emacs-lisp/bytecomp-tests.el | 10 ++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) 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)) diff --git a/test/lisp/emacs-lisp/bytecomp-tests.el b/test/lisp/emacs-lisp/bytecomp-tests.el index 9ade47331df..222065c2e4e 100644 --- a/test/lisp/emacs-lisp/bytecomp-tests.el +++ b/test/lisp/emacs-lisp/bytecomp-tests.el @@ -766,6 +766,16 @@ inner loops respectively." ((eq x 2) (setq y 'c))) (list x y))))) (mapcar fn (bytecomp-test-identity '(0 1 2 3 10 11)))) + + ;; `nconc' nil arg elimination + (nconc (list 1 2 3 4) nil) + (nconc (list 1 2 3 4) nil nil) + (let ((x (cons 1 (cons 2 (cons 3 4))))) + (nconc x nil)) + (let ((x (cons 1 (cons 2 (cons 3 4))))) + (nconc x nil nil)) + (let ((x (cons 1 (cons 2 (cons 3 4))))) + (nconc nil x nil (list 5 6) nil)) ) "List of expressions for cross-testing interpreted and compiled code.") From 5ead8c5f69b0a69bac4641d5003ee422d6b67038 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mattias=20Engdeg=C3=A5rd?= Date: Thu, 27 Apr 2023 13:52:57 +0200 Subject: [PATCH 2/4] Clarify `nconc` behaviour for dotted lists (bug#63103) * doc/lispref/lists.texi (Rearrangement): Explicitly say that dotted lists are valid args to `nconc` and give an example. --- doc/lispref/lists.texi | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/doc/lispref/lists.texi b/doc/lispref/lists.texi index a509325854f..22a5f7f1239 100644 --- a/doc/lispref/lists.texi +++ b/doc/lispref/lists.texi @@ -1224,7 +1224,15 @@ x @end example However, the other arguments (all but the last) should be mutable -lists. +lists. They can be dotted lists, whose last @sc{cdr}s are then +replaced with the next argument: + +@example +@group +(nconc (cons 1 2) (cons 3 (cons 4 5)) 'z) + @result{} (1 3 4 . z) +@end group +@end example A common pitfall is to use a constant list as a non-last argument to @code{nconc}. If you do this, the resulting behavior is undefined From 98006bfd09cf0bbec5ade924e1a60c48b16701a1 Mon Sep 17 00:00:00 2001 From: Michael Albinus Date: Thu, 27 Apr 2023 19:40:46 +0200 Subject: [PATCH 3/4] Fix Tramp bug#63102 * lisp/net/tramp.el (tramp-remote-path): Add ;;;###tramp-autoload cookie. (Bug#63102) --- lisp/net/tramp.el | 1 + 1 file changed, 1 insertion(+) diff --git a/lisp/net/tramp.el b/lisp/net/tramp.el index 81473404f0c..ca95b6b6971 100644 --- a/lisp/net/tramp.el +++ b/lisp/net/tramp.el @@ -1349,6 +1349,7 @@ let-bind this variable." ;; IRIX64: /usr/bin ;; QNAP QTS: --- ;; Hydra: /run/current-system/sw/bin:/bin:/usr/bin +;;;###tramp-autoload (defcustom tramp-remote-path '(tramp-default-remote-path "/bin" "/usr/bin" "/sbin" "/usr/sbin" "/usr/local/bin" "/usr/local/sbin" "/local/bin" "/local/freeware/bin" From dbd74657908e67e2a5001fbe440fb2a01a2f01af Mon Sep 17 00:00:00 2001 From: Michael Albinus Date: Thu, 27 Apr 2023 19:41:18 +0200 Subject: [PATCH 4/4] Fix thinko in tramp-gvfs-maybe-open-connection * lisp/net/tramp-gvfs.el (tramp-gvfs-maybe-open-connection): Use `assoc-default'. --- lisp/net/tramp-gvfs.el | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/lisp/net/tramp-gvfs.el b/lisp/net/tramp-gvfs.el index ad7b1ff054c..859f4870b80 100644 --- a/lisp/net/tramp-gvfs.el +++ b/lisp/net/tramp-gvfs.el @@ -2183,11 +2183,12 @@ connection if a previous connection has died for some reason." ;; Sanity check. (let ((method (tramp-file-name-method vec))) (unless (member - (or (rassoc method '(("smb" . "smb-share") - ("davs" . "dav") - ("nextcloud" . "dav") - ("afp". "afp-volume") - ("gdrive" . "google-drive"))) + (or (assoc-default + method '(("smb" . "smb-share") + ("davs" . "dav") + ("nextcloud" . "dav") + ("afp". "afp-volume") + ("gdrive" . "google-drive"))) method) tramp-gvfs-mounttypes) (tramp-error vec 'file-error "Method `%s' not supported by GVFS" method)))