bug#39823: 26.3; update-directory-autoloads regression from Emacs 26 to Emacs 27

classic Classic list List threaded Threaded
15 messages Options
Reply | Threaded
Open this post in threaded view
|

bug#39823: 26.3; update-directory-autoloads regression from Emacs 26 to Emacs 27

Maxim Cournoyer
Hello!

After passing from Emacs 26 to Emacs 27, the following snippet of code
doesn't behave the same:

--8<---------------cut here---------------start------------->8---
emacs --quick --batch --eval "(progn
 ;(require 'autoload)
 (let ((backup-inhibited t)
       (generated-autoload-file \"/tmp/toto\"))
   (update-directory-autoloads \"/tmp\")))"
--8<---------------cut here---------------end--------------->8---

Works on Emacs 26.3, but fails on Emacs 27.0.50, with the error message:

Wrong type argument: stringp, nil

If uncommenting the require line, like:

--8<---------------cut here---------------start------------->8---
emacs --quick --batch --eval "(progn
 (require 'autoload)
 (let ((backup-inhibited t)
       (generated-autoload-file \"/tmp/toto\"))
   (update-directory-autoloads \"/tmp\")))"
--8<---------------cut here---------------end--------------->8---

It now proceeds with the following output:

  INFO     Scraping files for toto...
  INFO     Scraping files for toto...done


I've isolated the autoload file containing the
update-directory-autoloads definition to be
/gnu/store/zpmsyn471y4hpgsbz652h4szyskzc2bm-profile/share/emacs/27.0.50/lisp/emacs-lisp/autoload.elc,
using:

--8<---------------cut here---------------start------------->8---
strace emacs --quick --batch --eval "(progn
 ;(require 'autoload)
 (let ((backup-inhibited t)
       (generated-autoload-file \"/tmp/toto\"))
   (update-directory-autoloads \"/tmp\")))" |& grep -E 'autoload.elc.* = 0'
stat("/gnu/store/zpmsyn471y4hpgsbz652h4szyskzc2bm-profile/share/emacs/27.0.50/lisp/emacs-lisp/autoload.elc", {st_mode=S_IFREG|0444, st_size=29029, ...}) = 0--8<---------------cut here---------------end--------------->8---


Its content is copied below:
--8<---------------cut here---------------start------------->8---
cat /gnu/store/zpmsyn471y4hpgsbz652h4szyskzc2bm-profile/share/emacs/27.0.50/lisp/emacs-lisp/autoload.elc
;ELC
;;; Compiled
;;; in Emacs version 27.0.50
;;; with all optimizations.

;;; This file uses dynamic docstrings, first added in Emacs 19.29.

;;; This file does not contain utf-8 non-ASCII characters,
;;; and so can be loaded in Emacs versions earlier than 23.

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


(byte-code "\300\301!\210\300\302!\207" [require lisp-mode lisp-mnt] 2)
#@481 File into which to write autoload definitions.
A Lisp file can set this in its local variables section to make
its autoloads go somewhere else.

If this is a relative file name, the directory is determined as
follows:
 - If a Lisp file defined `generated-autoload-file' as a
   file-local variable, use its containing directory.
 - Otherwise use the "lisp" subdirectory of `source-directory'.

The autoload file is assumed to contain a trailer starting with a
FormFeed character.
(defvar generated-autoload-file nil (#$ . 484))
(put 'generated-autoload-file 'safe-local-variable 'stringp)
#@270 Load name for `autoload' statements generated from autoload cookies.
If nil, this defaults to the file name, sans extension.
Typically, you need to set this when the directory containing the file
is not in `load-path'.
This also affects the generated cus-load.el file.
(defvar generated-autoload-load-name nil (#$ . 1080))
(put 'generated-autoload-load-name 'safe-local-variable 'stringp)
#@447 Magic comment indicating the following form should be autoloaded.
Used by \[update-file-autoloads].  This string should be
meaningless to Lisp (e.g., a comment).

This string is used:

;;;###autoload
(defun function-to-be-autoloaded () ...)

If this string appears alone on a line, the following form will be
read and an autoload made for it.  If there is further text on the line,
that text will be copied verbatim to `generated-autoload-file'.
(defvar generate-autoload-cookie ";;;###autoload" (#$ . 1476))
#@68 If non-nil, list of absolute file names not to scan for autoloads.
(defvar autoload-excludes nil (#$ . 1991))
#@75 String that marks the form at the start of a new file's autoload section.
(defconst generate-autoload-section-header "\f\n;;;### " (#$ . 2107))
#@72 String which indicates the end of the section of autoloads for a file.
(defconst generate-autoload-section-trailer "\n;;;***\n" (#$ . 2257))
#@64 String to add on each continuation of the section header form.
(defconst generate-autoload-section-continuation ";;;;;; " (#$ . 2404))
#@52 Value to insert when `autoload-timestamps' is nil.
(defconst autoload--non-timestamp '(0 0 0 0) (#$ . 2545))
#@892 Non-nil means insert a timestamp for each input file into the output.
We use these in incremental updates of the output file to decide
if we need to rescan an input file.  If you set this to nil,
then we use the timestamp of the output file instead.  As a result:
 - for fixed inputs, the output will be the same every time
 - incremental updates of the output file might not be correct if:
   i) the timestamp of the output file cannot be trusted (at least
     relative to that of the input files)
   ii) any of the input files can be modified during the time it takes
      to create the output
   iii) only a subset of the input files are scanned
   These issues are unlikely to happen in practice, and would arguably
   represent bugs in the build system.  Item iii) will happen if you
   use a command like `update-file-autoloads', though, since it only
   checks a single input file.
(defvar autoload-timestamps nil (#$ . 2661))
#@343 Turn FORM into an autoload or defvar for source file FILE.
Returns nil if FORM is not a special autoload form (i.e. a function definition
or macro definition or a defcustom).
If EXPANSION is non-nil, we're processing the macro expansion of an
expression, in which case we want to handle forms differently.

(fn FORM FILE &optional EXPANSION)
(defalias 'make-autoload #[770 "C\211\242\242\301\203\207\302=\203\207\242A\211A\211@A\211\303:\203t@\211\304\267\202dA\211:\203\346\211@\211:\203\%\262\202\261\240\f\30106A\211:\203\266\211@\211\306=\203\245A\211\204\224A\211:\203\203\211@A\211\204r\n\307%\202~\n\301%\266\202\202\217
             \301\f%\262\202\301\n\301
\301    %\262\202\361\f\30%\262\202oA\211:\203T\211@\211:\203D\211@\211\306=\2034AA\211\204#
                                                                                            \307%\202/
\301    %\262\202_\f\30%\262\202o                                                                     \301\f%\266\202\202?      \301\n%\262\202O
\"\322\"\323\324%\242A\"\"\211\205\306\325B\262\262\202\372\326>\203\366\327!\203\366\330\242!)\211\262\203\366\211@\331>\203\366\332\333#\202\372\334\267\202\352\335>\242A@\336\267\202\337\2428\202\340\202\301\202\307\341\342\"\206!\343\242\233\211@;\2051\211A\262\242<\203<\344\"\262\345<\203F\202I\305D
           \n\346>\203W\307\202\\@\242\347=     \205b\350\257\266\205\202\372\242A@\337\2428\351\2428\352\305D\305D\n\257\266\203\202\372\242\243\242\242\243\243\242\242\243\243\243\242\325\353F\354\305D
                                                        \3551\262\356
                                                                     \242>A@?0\202\264\210\301FE\266\203\202\372\242A@\357\360\361\305D\362BBDC\363\364\305\nD\365BB\301\366\305D\367\370\305D\371BBFFE\262\202\372\203\371\242:\203\371\242\202\372\301\266\202\207" [load-file-name nil defalias #[1285 "\211\242\300>\205\n\211A@\301:\203Z@\211\302=\203HA\211:\2036\211@A



                                                                        &\266\202\202C                          \303\211&\262\\303\211&\262\202g\211\303\211&\207" ['function #[1542 "\242;\203
                                            @\202\242;\205@:\205l@\211:\203M\211@\211\300=\203+\301\202HA\211:\205F\211@\211:\205D\211@\211\300=\205B\301\262\262\262\262\202jA\211:\205h\211@\211:\205f\211@\211\300=\205d\301\262\262\262\262:\203w\302\"\262\30\242A@   \257\207" [interactive t help-add-fundoc-usage autoload] 14 "\n\n(fn FORM FILE REST TYPE BODY ARGS)"] lambda t] 18 "\n\n(fn FORM FILE REST TYPE FUN)"] #s(hash-table size 2 test eq rehash-size 1.5 rehash-threshold 0.8125 purecopy t data (cons 41 quote 246)) quote macro t (progn prog1) :autoload-end copy-sequence delq mapcar make-byte-code 257 "\302\300\301#\207" vconcat vector [make-autoload] 5 "\n\n(fn FORM)" progn (easy-mmode-define-global-mode define-global-minor-mode define-globalized-minor-mode defun defmacro easy-mmode-define-minor-mode define-minor-mode define-inline cl-defun cl-defmacro cl-defgeneric cl-defstruct pcase-defmacro) macrop macroexpand (progn prog1 defalias) make-autoload expansion #s(hash-table size 17 test eq rehash-size 1.5 rehash-threshold 0.8125 purecopy t data (define-skeleton 508 define-derived-mode 508 define-compilation-mode 508 define-generic-mode 508 easy-mmode-define-global-mode 508 define-global-minor-mode 508 define-globalized-minor-mode 508 easy-mmode-define-minor-mode 508 define-minor-mode 508 cl-defun 508 defun* 508 cl-defmacro 508 defmacro* 508 define-overloadable-function 508 defclass 617 defcustom 646 defgroup 699)) (defmacro cl-defmacro defmacro*) #s(hash-table size 11 test eq rehash-size 1.5 rehash-threshold 0.8125 purecopy t data (define-overloadable-function 521 cl-defmacro 521 cl-defun 521 defmacro* 521 defun* 521 defmacro 521 defun 521 define-skeleton 528 define-compilation-mode 532 define-derived-mode 532 define-generic-mode 532)) 2 (&optional str arg) function-get doc-string-elt 3 help-add-fundoc-usage autoload (define-skeleton define-derived-mode define-generic-mode easy-mmode-define-global-mode define-global-minor-mode define-globalized-minor-mode easy-mmode-define-minor-mode define-minor-mode) interactive 'macro 4 eieio-defclass-autoload defvar custom-autoload (error) :set let loads get ('custom-loads) if member (loads) put 'custom-loads cons (loads)] 29 (#$ . 3604)])
#@72 Visit the autoload file for the current buffer, and return its buffer.
(defalias 'autoload-find-generated-file #[0 "\303\304\305\306 r\307\310!!q\210\311 \312U\203!\313\304\305#c\210p,\207" [delay-mode-hooks enable-local-eval enable-local-variables :safe nil t autoload-generated-file find-file-noselect autoload-ensure-file-writeable buffer-size 0 autoload-rubric] 8 (#$ . 8148)])
#@165 Return `generated-autoload-file' as an absolute name.
If local to the current buffer, expand using the default directory;
otherwise, using `source-directory'/lisp.
\302\304s 'autol\"\"\207" [generated-autoload-file source-directory expand-file-name local-variable-p "lisp"] 5 (#$ . 8546)])
#@174 Read a section header form.
Since continuation lines have been marked as comments,
we must copy the text of the form and remove those comment
markers before we call `read'.
(defalias 'autoload-read-section-header #[0 "\301 \302\303\304\305\306!\307\"\310$\216`\311\312y\210\31!\203\312y\210\202`{\262r\314\315!q\210\316 \210\211c\210eb\210\31\311\320#\203B\321\322!\210\2023eb\210\323p!)\266\202)\207" [generate-autoload-section-continuation match-data make-byte-code 0 "\301\300\302\"\207" vconcat vector [set-match-data evaporate] 3 nil 1 looking-at get-buffer-create " *autoload*" erase-buffer search-forward t replace-match " " read] 7 (#$ . 8897)])
#@56 Buffer which gets the output of `autoload-print-form'.
(defvar autoload-print-form-outbuf nil (#$ . 9570))
#@159 Print FORM such that `make-docfile' will find the docstrings.
The variable `autoload-print-form-outbuf' specifies the buffer to
put the output in.

(fn FORM)
\306\307A\"\207\2119\203\310\207\311\242\312\\203\2548;\203\254S\233\211A\310\241\210\313\314\"\210\315\211\211\211211\203V\211@\316\"\210\313\317\"\210A\266\202\202=\210,\313\320\"\210rq\210`)\313\321\322@!\323\"\"\210rq\210\212\324\325\315#\203\204\323u\210\326c\210\202s*A\204\222\313\327\"\210\202\242\313\317\"\210\313\321\322A!\323\"\"\210\330!\262\266\202\202\271\315\211\211\211331\",\207" [autoload-print-form-outbuf print-escape-nonascii print-quoted print-escape-control-characters print-escape-newlines progn mapcar autoload-print-form nil function-get doc-string-elt princ "\n(" t prin1 " " "\"\\\n" substring prin1-to-string 1 re-search-backward "\n[[(]" "\\" ")" terpri print] 10 (#$ . 9684)])
#@430 Return a string giving the appropriate autoload rubric for FILE.
TYPE (default "autoloads") is a string stating the type of
information contained in FILE.  TYPE "package" acts like the default,
but adds an extra line to the output to modify `load-path'.

If FEATURE is non-nil, FILE will provide a feature.  FEATURE may
be a string naming the feature, otherwise it will be based on
FILE's name.

(fn FILE &optional TYPE FEATURE)
\302\211\262\303\304\206\302\305\205\306\307232\\2054\310\311
                                                             ;\203/
                                                                   \2023\312
                                                                            !\"\313\n\314\260
                                                                                             \207" [file-name-nondirectory "package" "autoloads" ";;; " " --- automatically extracted " "\n;;\n;;; Code:\n\n" "(add-to-list 'load-path (directory-file-name\n                         (or (file-name-directory #$) (car load-path))))\n\n" "\f\n" format "(provide '%s)\n" file-name-sans-extension ";; Local Variables:\n;; version-control: never\n;; no-byte-compile: t\n;; no-update-autoloads: t\n;; coding: utf-8\n;; End:\n;;; " " ends here\n"] 16 (#$ . 10666)])
#@76 Non-nil means `autoload-find-generated-file' makes existing file writable.
(defvar autoload-ensure-writable nil (#$ . 11728))
(put 'autoload-ensure-writable 'risky-local-variable t)
#@13

(fn FILE)
(defalias 'autoload-ensure-file-writeable #[257 \203)\301!\211\203(\302\303\"\304U\203(\3051#\306\307\303\"\"0\202'\210\202(\210\210\207" [autoload-ensure-writable file-modes logand 128 0 (error) set-file-modes logior] 7 (#$ . 11916)])
#@138 Insert the section-header line,
which lists the file name and which functions are in it, etc.

(fn OUTBUF AUTOLOADS LOAD-NAME FILE TIME)
(defalias 'autoload-insert-section-header #[1285 c\210\302\303!\211\203\304\305!!\202\306\307\25\"\266\310!\210rq\210\212\311y\210l?\205H\312\313!\210\314\315w\210l\204/\316      \261\210\202/*\207" [generate-autoload-section-header generate-autoload-section-continuation getenv "SOURCE_DATE_EPOCH" seconds-to-time string-to-number prin1 autoloads terpri -1 move-to-column 64 "^ \n" nil "\n"] 13 (#$ . 12183)])
#@72 Fetch file and put it in a temp buffer.  Return the buffer.

(fn FILE)
(defalias 'autoload-find-file #[257 "\306!\262r\307\310!q\210\311 \210\312 \210\313\314\315\302!\210\313\316 \210)\317!\320\314\"\210\321\314\322 \210*p)\207" [buffer-undo-list buffer-read-only delay-mode-hooks default-directory enable-local-eval enable-local-variables expand-file-name get-buffer-create " *autoload-file*" kill-all-local-variables erase-buffer t nil make-local-variable emacs-lisp-mode file-name-directory insert-file-contents :safe hack-local-variables] 4 (#$ . 12758)])
#@73 File local variable to prevent scanning this file for autoload cookies.
(defvar no-update-autoloads nil (#$ . 13335))
#@61 Compute the name that will be used to load FILE.

(fn FILE)
\204VA\2045@\262\202%\307\310\311\"!\203L\310\211A\262\242\"\262\202%\312\313\314#\262\202%\315\316\"\203f\317\320\211\224#\202g\207" [default-value generated-autoload-file file-relative-name file-name-directory nil directory-file-name file-name-nondirectory file-exists-p expand-file-name "subdirs.el" mapconcat identity "/" string-match "\\.elc?\\(\\.\\|\\'\\)" substring 0] 9 (#$ . 13459)])
#@315 Insert at point a loaddefs autoload section for FILE.
Autoloads are generated for defuns and defmacros in FILE
marked by `generate-autoload-cookie' (which see).
If FILE is being visited in a buffer, the contents of the buffer
are used.
Return non-nil in the case where no autoloads were added at point.

(fn FILE)
(defalias 'generate-file-autoloads #[257 \302p\")\207" [buffer-file-name generated-autoload-file autoload-generate-file-autoloads] 4 (#$ . 14064) "fGenerate autoloads for file: "])
#@276 If non-nil, autoload will add code to register the prefixes used in a file.
Standard prefixes won't be registered anyway.  I.e. if a file "foo.el" defines
variables or functions that use "foo-" as prefix, that will not be registered.
But all other prefixes will be included.
(defvar autoload-compute-prefixes t (#$ . 14570))
(put 'autoload-compute-prefixes 'safe 'booleanp)
#@305 Target length of the list of definition prefixes per file.
If set too small, the prefixes will be too generic (i.e. they'll use little
memory, we'll end up looking in too many files when we need a particular
prefix), and if set too large, they will be too specific (i.e. they will
cost more memory use).
(defconst autoload-def-prefixes-max-entries 5 (#$ . 14951))
#@100 Target size of definition prefixes.
Don't try to split prefixes that are already longer than that.
(defconst autoload-def-prefixes-max-length 12 (#$ . 15322))
(require 'radix-tree)
#@18

(fn DEFS FILE)
(defalias 'autoload--make-defs-autoload #[514 \211\203\211@\301\302#\262A\266\202\202\210\211\262\303C\304\305\306\307\310\311!\312\"\313\314%\"\210\211\242\303\240\210\211\203}\211@\211@\211G\315V\203H\211\316\230\203W\317\320\"\204W\321A\322\"\203a\242B\240\210\202u\304A\305\306\323\310\311\\"\312\"\313\314%\"\210\210A\266\202\2023\210\211\242\205\247\324\305\325\326\310\31!\327\"\330\331%\242\"\332\333\334\335\336\337\30\"\340\"DEE\262\207" [radix-tree-empty radix-tree-insert t nil radix-tree-iter-subtrees make-byte-code 514 "\300B\300\242B\240\207" vconcat vector #1=[] 5 "\n\n(fn PREFIX SUBTREE)" 2 "def" string-match ".[[:punct:]]\\'" radix-tree-lookup "" "\300\301PB\300\242B\240\207" mapcar 257 "\211@\211G\301V\204\211G\301=\203302\303\"\203211\202<\304C\305A\306\307\310\311\3\"\313\"\314\315%\"\210\316\317\300\242$\210\304\262\207" [2 string-match "[[:punct:]]" nil radix-tree-iter-mappings make-byte-code 514 "\301\300P\301\242B\240\207" vconcat vector #1# 5 "\n\n(fn S _)" message "Not registering prefix \"%s\" from %s.  Affects: %S"] 12 "\n\n(fn X)" if (fboundp 'register-definition-prefixes) register-definition-prefixes quote sort delq string<] 16 (#$ . 15509)])
#@42

(fn OTHERBUF OUTBUF ABSFILE LOAD-NAME)
(defalias 'autoload--setup-output #[1028 "\20\206\300\"\206\301\302\"r\211q\210\303 )\207" [autoload-find-destination throw done point-marker] 7 (#$ . 16789)])
#@36

(fn OUTPUT-START LOAD-NAME FILE)
(defalias 'autoload--print-cookie-text #[771 "\303!\304 !\210\305\306w\210l\203C\30715\310p!n\204\311y\210\312\"\211\204)\26\313!)\266\2020\202Z\314\315\316e`\"$\262\202Z\317\320\306x\210`Tf\321U\203S\311u\210`\311y\210`{!)\207" [standard-output generate-autoload-cookie autoload-print-form-outbuf marker-buffer search-forward "      " nil (debug error) read 1 make-autoload autoload-print-form message "Autoload cookie error in %s:%s %S" count-lines princ " \f    " 32] 10 (#$ . 17008)])
(defvar autoload-builtin-package-versions nil)
#@164 List of strings naming definitions to ignore for prefixes.
More specifically those definitions will not be considered for the
`register-definition-prefixes' call.
(defvar autoload-ignored-definitions '("define-obsolete-function-alias" "define-obsolete-variable-alias" "define-category" "define-key" "defgroup" "defface" "defadvice" "def-edebug-spec" "define-widget" "define-erc-module" "define-erc-response-handler" "defun-rcirc-command") (#$ . 17600))
#@758 Insert an autoload section for FILE in the appropriate buffer.
Autoloads are generated for defuns and defmacros in FILE
marked by `generate-autoload-cookie' (which see).
If FILE is being visited in a buffer, the contents of the buffer are used.
OUTBUF is the buffer in which the autoload statements should be inserted.
If OUTBUF is nil, it will be determined by `autoload-generated-file'.

If provided, OUTFILE is expected to be the file name of OUTBUF.
If OUTFILE is non-nil and FILE specifies a `generated-autoload-file'
different from OUTFILE, then OUTBUF is ignored.

Return non-nil if and only if FILE adds no autoloads to OUTFILE
(or OUTBUF if OUTFILE is nil).  The actual return value is
FILE's modification time.

(fn FILE &optional OUTBUF OUTFILE)
(defalias 'autoload-generate-file-autoloads #[769 "\3061<\307\211\211\211\310!\307\311  !\307\211\3122,r\206(\313\f!q\210
\202D\316!\262          \203g@\317>\203\\       \227\320 \227\232\202a  \320 \232\204g\321\262\212\214~\210A\203\315\322\323!\307\203\313\3241\203\325!0\202\205\210\307\211\262\203\313\322\326!\206\227\327\330!!\211\262\203\313\331$\211\262\203\313\332!\321BC\333\334\335\336\337!BDD\340BB!\210\347y\210\202\327E\350\232\203*\343\351!\203*\352\347!F\235\204*\353\354!B\262\355\347!\210\347y\210\202\327*G\203\270\203\270\356\n\"\211\203\267\$)\332!H\357!\210r\332!q\210\212\211b\210\362!\363\332!\364I\203\245\365
                                                                        !\3668\262\202\247J%\210\367\341\261\266)Kc\210*\210\210\211\203\205\301pr\\"\210\204$\375p!\210)\211?\206+0\2057\365!\3668\262+\266\2110\207\376\377@A$\207" [float-output-format print-level print-length no-update-autoloads noninteractive generated-autoload-load-name (error) nil get-file-buffer expand-file-name done autoload-find-file message "Generating autoloads for %s..." autoload-file-load-name (ms-dos windows-nt) autoload-generated-file t lm-header "version" (error) version-to-list "package" file-name-sans-extension file-name-nondirectory autoload--setup-output marker-buffer princ push purecopy quote intern (package--builtin-versions) "\n" "      \n\f" looking-at regexp-quote autoload--print-cookie-text 59 1 ";;;###autoload" "(\\(def[^ ]+\\) ['(]*\\([^' ()\"\n]+\\)[\n        ]" match-string match-string-no-properties 2 forward-sexp autoload--make-defs-autoload autoload-print-form default-value generated-autoload-file file-relative-name autoload-insert-section-header "actual autoloads are elsewhere" file-attributes 5 ";;; Generated autoloads from " cl--assertion-failed (> (point) output-start) md5 emacs-mule-unix "Generating autoloads for %s...done" kill-buffer error "%s:0:0: error: %s: %s" system-type autoload-builtin-package-versions print-quoted standard-output autoload-excludes generate-autoload-cookie autoload-ignored-definitions autoload-compute-prefixes autoload-print-form-outbuf autoload-timestamps autoload--non-timestamp generate-autoload-section-trailer] 24 (#$ . 18060)])
#@46 Save current buffer to its file, atomically.
(defalias 'autoload--save-buffer #[0 "\304\305  !\306 \307\310\"\307\311        !\206\312\"\313\314\315\316\31!\320\"\321$\nBU\204/\322\"\210\323ed\324\325%\210\326 \210\327      \330#\210*\266\331\324!\210\332 \210
                                                                    \206S\333\334       \"\207" [version-control buffer-file-name kill-emacs-hook noninteractive never make-temp-file default-file-modes logand 384 file-modes 438 make-byte-code 0 "\3011 \302\300!0\207\210\303\207" vconcat vector [(error) delete-file nil] 2 set-file-modes write-region nil 1 backup-buffer rename-file t set-buffer-modified-p set-visited-file-modtime message "Wrote %s"] 10 (#$ . 21513)])
(defalias 'autoload-save-buffers #[0 \205\211A\242q\210\301 \210)\202\207" [autoload-modified-buffers autoload--save-buffer] 2])
#@491 Update the autoloads for FILE.
If prefix arg SAVE-AFTER is non-nil, save the buffer too.

If FILE binds `generated-autoload-file' as a file-local variable,
autoloads are written into that file.  Otherwise, the autoloads
file is determined by OUTFILE.  If called interactively, prompt
for OUTFILE; if called from Lisp with OUTFILE nil, use the
existing value of `generated-autoload-file'.

Return FILE if there was no autoload cookie in it, else nil.

(fn FILE &optional SAVE-AFTER OUTFILE)
(defalias 'update-file-autoloads #[769 "\211\20\303\304\305!    \203203&\306 \210\202&\307\310!\203&\311\312\"\210\211\205++\207" [generated-autoload-file autoload-modified-buffers autoload-timestamps nil t autoload-generate-file-autoloads autoload-save-buffers called-interactively-p interactive message "Autoload section for %s is up to date."] 7 (#$ . 22321) (byte-code "\301\302\301\303!E\207" [current-prefix-arg read-file-name "Update autoloads for file: " "Write autoload definitions to file: "] 4)])
#@360 Find the destination point of the current buffer's autoloads.
FILE is the file name of the current buffer.
LOAD-NAME is the name as it appears in the output.
Returns a buffer whose point is placed at the requested location.
Returns nil if the file's autoloads are up-to-date, otherwise
removes any prior now out-of-date autoload entries.

(fn FILE LOAD-NAME)
(defalias 'autoload-find-destination #[514 "\3052\360\205\n\211\306 \307!\205\310!\3118\262\312r\313 q\210\314  !\315=\204,\316\317!\210\320 \315V\2048\321\32\"\210\32!\204C\321\32\"\210~\210eb\210\211\204\324\325\n\312\326#\203\324\327 \3308\230\203\300\315\224\3318\310\n!\3118\262\203y\33!\204\264\203\216\326
                  D\235\203\216\333\"?\202\251<\203\233\333\"?\202\251;\203\264\334\n\312\211\335$\232\203\264\336\305\312\"\210\202\273\337!\210\326\262\266\202\320\3308\231\203\320\315\224b\210\326\262\210\202H\211\204\341db\210\340\341\312\326#\210p\f>\204\353p\fBp)\266\2050\207" [buffer-file-name buffer-file-coding-system generate-autoload-section-header autoload--non-timestamp autoload-modified-buffers up-to-date autoload-generated-file file-exists-p file-attributes 5 nil autoload-find-generated-file coding-system-eol-type 0 set-buffer-file-coding-system unix buffer-size error "Autoloads file %s lacks boilerplate" file-writable-p "Autoloads file %s is not writable" search-forward t autoload-read-section-header 2 4 buffer-modified-p time-less-p md5 emacs-mule throw autoload-remove-section search-backward "\f"] 17 (#$ . 23343)])
#@14

(fn BEGIN)
(defalias 'autoload-remove-section #[257 "\211b\210\30!\210\211`|\207" [generate-autoload-section-trailer search-forward] 3 (#$ . 24914)])
#@757 Update autoload definitions for Lisp files in the directories DIRS.
In an interactive call, you must give one argument, the name of a
single directory.  In a call from Lisp, you can supply multiple
directories as separate arguments, but this usage is discouraged.

The function does NOT recursively descend into subdirectories of the
directory or directories specified.

In an interactive call, prompt for a default output file for the
autoload definitions, and temporarily bind the variable
`generated-autoload-file' to this value.  When called from Lisp,
use the existing value of `generated-autoload-file'.  If any Lisp
file binds `generated-autoload-file' as a file-local variable,
write its autoloads into the specified file instead.

(fn &rest DIRS)
(defalias 'update-directory-autoloads #[128 "\306\307 \211\203\211@\310\311\"\204\211B\262A\266\202\202\210\312\313\314\"\315Q\262\316\317\320\321\322\323\324\32!\326\"\327\330%\"\"\306\211\211\211\211\331\332!\203K\333\334!\202L      \335    !\205[\336      !\3278\262r\337 q\210\212\340\341\n!\320\341       \"\"\262eb\210\342
                                  \306\314#\2034\343 \3448\211:\203\321\211@;\203\321\345\346\224!\210\3478\262\314\fD\235\203\235\262\211\211\203\315\211@\336!\3278\262\211\203\305\35\"\204\305B\262\340\f\"\262
                                                                \210A\266\202\202\236\210\202\"\211;\203\"\335!\203\343\211\235\203\356\314\262\345\346\224!\210\202\"\350\3478\211\314\fD\235\203\376\202\377\211\262\336!\3278\262\"\203\"\314\262\345\346\224!\210\351p\n#\203\"\211B\262\211B\262\340     \"\26\266\202p)\206:\352\353\354\355\341        !P!\346 G\306\356%\346\306      \211\203\227\211@T\211\262\306\247\203f@Y\203l\357#\210\266\351\306\n#\211\262\203\215\21B\26\350\"\203\220\262\202\220\314\262\nA\266\202\202M\210\360!\210\203\306\361\362\"\262db\210\363\364\306\314#\210\\203\27\202\300\f%\2109c\210\266\204\323\366\306!\210\202\326\367 \210\370 +\207" [autoload-modified-buffers generated-autoload-file buffer-file-name generate-autoload-section-header autoload--non-timestamp autoload-timestamps nil get-load-suffixes string-match "\\.\\(elc\\|so\\|dll\\)" "^[^=.].*" regexp-opt t "\\'" apply nconc mapcar make-byte-code 257 "\301\302!\303\300#\207" vconcat vector [directory-files expand-file-name t] 5 "\n\n(fn DIR)" called-interactively-p interactive read-file-name "Write autoload definitions to file: " file-exists-p file-attributes autoload-find-generated-file delete file-relative-name search-forward autoload-read-section-header 3 autoload-remove-section 0 4 time-less-p autoload-generate-file-autoloads (0 0 0 0) make-progress-reporter byte-compile-info-string "Scraping files for " 10 progress-reporter-do-update progress-reporter-done sort string< search-backward "\f" autoload-insert-section-header set-buffer-modified-p autoload--save-buffer autoload-save-buffers generate-autoload-section-trailer] 21 (#$ . 25075) "DUpdate autoloads from directory: "])
#@191 Update loaddefs.el autoloads in batch mode.
Calls `update-directory-autoloads' on the command line arguments.
Definitions are written to `generated-autoload-file' (which
should be non-nil).
(defalias 'batch-update-autoloads #[0 \204V\304 !\305\306\307!\203S\310\311!r\211q\210\312\313\314\315\316!\317\"\320$\216\321\307!\210\322\323\305\324#\203Q\325\326!\262\327\330\"\204A\331\332\"\262\327\333\"\204'\334B\202'*\210)\266
                                                                                       \305\335\336\"\207" [autoload-excludes generated-autoload-file default-directory command-line-args-left file-name-directory nil file-readable-p "loadup.el" generate-new-buffer " *temp*" make-byte-code 0 "\301\300!\205      \302\300!\207" vconcat vector [buffer-name kill-buffer] 2 insert-file-contents re-search-forward "^(load \"\\([^\"]+\\)\"" t match-string 1 string-match "\\.el\\'" format "%s.el" "\\`site-" expand-file-name apply update-directory-autoloads] 9 (#$ . 28083)])
(provide 'autoload)
--8<---------------cut here---------------end--------------->8---

Could it be a byte compilation bug?

Thanks for the great editor :-)

Maxim



Reply | Threaded
Open this post in threaded view
|

bug#39823: 26.3; update-directory-autoloads regression from Emacs 26 to Emacs 27

Noam Postavsky
Maxim Cournoyer <[hidden email]> writes:

> After passing from Emacs 26 to Emacs 27, the following snippet of code
> doesn't behave the same:
>
> emacs --quick --batch --eval "(progn
>  ;(require 'autoload)
>  (let ((backup-inhibited t)
>        (generated-autoload-file \"/tmp/toto\"))
>    (update-directory-autoloads \"/tmp\")))"
>
>
> Works on Emacs 26.3, but fails on Emacs 27.0.50, with the error message:
>
> Wrong type argument: stringp, nil
The difference is that --eval now evaluates with lexical-binding
enabled, so the let-binding of generated-autoload-file is lexical unless
autoload.el, with its (defvar generated-autoload-file nil ...), has been
loaded.  Another way to demonstrate this:

    emacs -Q --batch -l bug-39823-autoload-regression.el

fails with the same error, with bug-39823-autoload-regression.el as the
attached file in both Emacs 26 and 27.  Remove the lexical-binding
setting, and it succeeds in both.



See also https://lists.gnu.org/r/emacs-devel/2020-03/msg00173.html for
(much) more discussion on this.




bug-39823-autoload-regression.el (181 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

bug#39823: 26.3; update-directory-autoloads regression from Emacs 26 to Emacs 27

Eli Zaretskii
> From: Noam Postavsky <[hidden email]>
> Date: Thu, 12 Mar 2020 20:43:09 -0400
> Cc: , [hidden email]
>
> > Works on Emacs 26.3, but fails on Emacs 27.0.50, with the error message:
> >
> > Wrong type argument: stringp, nil
>
> The difference is that --eval now evaluates with lexical-binding
> enabled, so the let-binding of generated-autoload-file is lexical unless
> autoload.el, with its (defvar generated-autoload-file nil ...), has been
> loaded.
> [...]
> See also https://lists.gnu.org/r/emacs-devel/2020-03/msg00173.html for
> (much) more discussion on this.

The "wrap with eval" trick suggested by Stefan in the latter
discussion does work here:

 emacs --quick --batch --eval "(eval '(progn
   (let ((backup-inhibited t)
         (generated-autoload-file \"/tmp/toto\"))
     (update-directory-autoloads \"/tmp\"))))"

  =|
  INFO     Scraping files for toto...75%
  INFO     Scraping files for toto...done



Reply | Threaded
Open this post in threaded view
|

bug#39823: 26.3; update-directory-autoloads regression from Emacs 26 to Emacs 27

Michael Heerdegen
In reply to this post by Noam Postavsky
Noam Postavsky <[hidden email]> writes:

> The difference is that --eval now evaluates with lexical-binding
> enabled, so the let-binding of generated-autoload-file is lexical unless
> autoload.el, with its (defvar generated-autoload-file nil ...), has been
> loaded.

For a general solution, would it make sense to let emacs -Q know in
advance which variables are dynamic, by generating some list when
building?

Michael.



Reply | Threaded
Open this post in threaded view
|

bug#39823: 26.3; update-directory-autoloads regression from Emacs 26 to Emacs 27

Maxim Cournoyer
In reply to this post by Noam Postavsky
Hello!

Noam Postavsky <[hidden email]> writes:

> Maxim Cournoyer <[hidden email]> writes:
>
>> After passing from Emacs 26 to Emacs 27, the following snippet of code
>> doesn't behave the same:
>>
>> emacs --quick --batch --eval "(progn
>>  ;(require 'autoload)
>>  (let ((backup-inhibited t)
>>        (generated-autoload-file \"/tmp/toto\"))
>>    (update-directory-autoloads \"/tmp\")))"
>>
>>
>> Works on Emacs 26.3, but fails on Emacs 27.0.50, with the error message:
>>
>> Wrong type argument: stringp, nil
>
> The difference is that --eval now evaluates with lexical-binding
> enabled, so the let-binding of generated-autoload-file is lexical unless
> autoload.el, with its (defvar generated-autoload-file nil ...), has been
> loaded.  Another way to demonstrate this:
>
>     emacs -Q --batch -l bug-39823-autoload-regression.el
>
> fails with the same error, with bug-39823-autoload-regression.el as the
> attached file in both Emacs 26 and 27.  Remove the lexical-binding
> setting, and it succeeds in both.

Thank you for opening my eyes on this; I was scratching my head a bit.

> See also https://lists.gnu.org/r/emacs-devel/2020-03/msg00173.html for
> (much) more discussion on this.

Eh, indeed, that was a bit much :-).  I have nothing against lexcal
scoping (all to the contrary), and always found it strange that I had to
dynamically bound values variable calling `update-directory-autoloads'.
Perhaps a simple fix would be to allow passing the values it needs as
arguments (while maintaining backward compatibility, i.e., make those
arguments optional?).

Maxim



Reply | Threaded
Open this post in threaded view
|

bug#39823: 26.3; update-directory-autoloads regression from Emacs 26 to Emacs 27

Maxim Cournoyer
In reply to this post by Eli Zaretskii
Hello again,

Eli Zaretskii <[hidden email]> writes:

>> From: Noam Postavsky <[hidden email]>
>> Date: Thu, 12 Mar 2020 20:43:09 -0400
>> Cc: , [hidden email]
>>
>> > Works on Emacs 26.3, but fails on Emacs 27.0.50, with the error message:
>> >
>> > Wrong type argument: stringp, nil
>>
>> The difference is that --eval now evaluates with lexical-binding
>> enabled, so the let-binding of generated-autoload-file is lexical unless
>> autoload.el, with its (defvar generated-autoload-file nil ...), has been
>> loaded.
>> [...]
>> See also https://lists.gnu.org/r/emacs-devel/2020-03/msg00173.html for
>> (much) more discussion on this.
>
> The "wrap with eval" trick suggested by Stefan in the latter
> discussion does work here:
>
>  emacs --quick --batch --eval "(eval '(progn
>    (let ((backup-inhibited t)
>          (generated-autoload-file \"/tmp/toto\"))
>      (update-directory-autoloads \"/tmp\"))))"

Oh, that's an interesting trick.  I had not realized `eval' could be
switched to either lexical or dynamic (the default).

Thanks!

Maxim



Reply | Threaded
Open this post in threaded view
|

bug#39823: 26.3; update-directory-autoloads regression from Emacs 26 to Emacs 27

Richard Stallman
In reply to this post by Noam Postavsky
[[[ To any NSA and FBI agents reading my email: please consider    ]]]
[[[ whether defending the US Constitution against all enemies,     ]]]
[[[ foreign or domestic, requires you to follow Snowden's example. ]]]

Is there any real use for lexical scoping in --eval?
I suggest reverting the default for --eval to dynamic.
We could introduce --evallex to specify lexical scoping
and ask people to tell us if they find it useful.

--
Dr Richard Stallman
Chief GNUisance of the GNU Project (https://gnu.org)
Founder, Free Software Foundation (https://fsf.org)
Internet Hall-of-Famer (https://internethalloffame.org)





Reply | Threaded
Open this post in threaded view
|

bug#39823: 26.3; update-directory-autoloads regression from Emacs 26 to Emacs 27

Noam Postavsky
In reply to this post by Maxim Cournoyer
Maxim Cournoyer <[hidden email]> writes:

> I have nothing against lexcal scoping (all to the contrary), and
> always found it strange that I had to dynamically bound values
> variable calling `update-directory-autoloads'.  Perhaps a simple fix
> would be to allow passing the values it needs as arguments (while
> maintaining backward compatibility, i.e., make those arguments
> optional?).

Hmm, I guess we could add a &key style arg (I don't think plain
&optional would be possible in a backward compatible way because the
current arg list is &rest DIRS; there wouldn't be any way to distinguish
the optional directory argument).



Reply | Threaded
Open this post in threaded view
|

bug#39823: 26.3; update-directory-autoloads regression from Emacs 26 to Emacs 27

Richard Stallman
In reply to this post by Richard Stallman
[[[ To any NSA and FBI agents reading my email: please consider    ]]]
[[[ whether defending the US Constitution against all enemies,     ]]]
[[[ foreign or domestic, requires you to follow Snowden's example. ]]]

I still see no way in which lexical as default makes any sense for --eval.

--
Dr Richard Stallman
Chief GNUisance of the GNU Project (https://gnu.org)
Founder, Free Software Foundation (https://fsf.org)
Internet Hall-of-Famer (https://internethalloffame.org)





Reply | Threaded
Open this post in threaded view
|

bug#39823: 26.3; update-directory-autoloads regression from Emacs 26 to Emacs 27

Maxim Cournoyer
Hello Richard,

Richard Stallman <[hidden email]> writes:

[...]

> I still see no way in which lexical as default makes any sense for --eval.

Why would it be different than for M-: (eval-expression)?

It seem to be mostly a matter of consistency (moving to lexical scope by
default, everywhere).

For the record, this change of behavior was mitigated in GNU Guix with
the following change, which was one of the suggestions made here (wrap
in eval):
https://git.savannah.gnu.org/cgit/guix.git/commit/?id=afc6b1c0b635e3268795c0f766be408c5e9858e7.

I think it could be nice to update update-directory-autoloads to work in
a lexical setting before closing this bug, though.

Maxim



Reply | Threaded
Open this post in threaded view
|

bug#39823: 26.3; update-directory-autoloads regression from Emacs 26 to Emacs 27

Maxim Cournoyer
Hi Eli,

Eli Zaretskii <[hidden email]> writes:

>> From: Maxim Cournoyer <[hidden email]>
>> Date: Tue, 07 Apr 2020 23:55:18 -0400
>> Cc: [hidden email], [hidden email]
>>
>> I think it could be nice to update update-directory-autoloads to work in
>> a lexical setting before closing this bug, though.
>
> Update how?

Update `update-directory-autoloads' so that it accepts a &key style arg
for the ‘generated-autoload-file’ file name.  Currently it must be
dynamically bound prior to calling `update-directory-autoloads'.  This
was discussed earlier in this thread (see:
https://debbugs.gnu.org/cgi/bugreport.cgi?bug=39823#29).

> This discussion mentioned a way to turn off lexical-binding in --eval
> command-line arguments (which is also in NEWS), so why do we need to
> do anything else specifically for update-directory-autoloads?

Because I suspect that 'update-directory-autoloads' is probably used
most of the time with the command line --eval (in Makefiles and build
scripts), and that the wrap in eval workaround, while it works, is
rather obscure.

Maxim



Reply | Threaded
Open this post in threaded view
|

bug#39823: 26.3; update-directory-autoloads regression from Emacs 26 to Emacs 27

Eli Zaretskii
> From: Maxim Cournoyer <[hidden email]>
> Cc: [hidden email],  [hidden email],  [hidden email]
> Date: Wed, 08 Apr 2020 12:41:26 -0400
>
> >> I think it could be nice to update update-directory-autoloads to work in
> >> a lexical setting before closing this bug, though.
> >
> > Update how?
>
> Update `update-directory-autoloads' so that it accepts a &key style arg
> for the ‘generated-autoload-file’ file name.  Currently it must be
> dynamically bound prior to calling `update-directory-autoloads'.

I don't think this is related to this bug report.  It's a separate
issue: you want to enhance the API of update-directory-autoloads.

> > This discussion mentioned a way to turn off lexical-binding in --eval
> > command-line arguments (which is also in NEWS), so why do we need to
> > do anything else specifically for update-directory-autoloads?
>
> Because I suspect that 'update-directory-autoloads' is probably used
> most of the time with the command line --eval (in Makefiles and build
> scripts), and that the wrap in eval workaround, while it works, is
> rather obscure.

The Emacs build also uses it, it just uses "-l autoload" before --eval.
It sounds like the right solution to me, something that people should
use if they need to call this function from a Makefile.



Reply | Threaded
Open this post in threaded view
|

bug#39823: 26.3; update-directory-autoloads regression from Emacs 26 to Emacs 27

Noam Postavsky
Maxim Cournoyer <[hidden email]> writes:

> (defun update-directory-autoloads (&rest dirs)
>
> I don't see how &key can be combined with &rest without potentially
> causing problems.

You can check if the first arg is a keyword like
:generated-autoload-file (which can't be a directory, since it's not a
string), and if it is, then handle the second arg specially.




Reply | Threaded
Open this post in threaded view
|

bug#39823: 26.3; update-directory-autoloads regression from Emacs 26 to Emacs 27

Maxim Cournoyer
Hello Noam,

Noam Postavsky <[hidden email]> writes:

> Maxim Cournoyer <[hidden email]> writes:
>
>> (defun update-directory-autoloads (&rest dirs)
>>
>> I don't see how &key can be combined with &rest without potentially
>> causing problems.
>
> You can check if the first arg is a keyword like
> :generated-autoload-file (which can't be a directory, since it's not a
> string), and if it is, then handle the second arg specially.
I've given this idea a try with the attached patch.  For some reason I
can't seem to simply eval the definition to test it (Debugger
entered--Lisp error: (void-function byte-compile-info-string).  I'm
rebuilding Emacs with the change right now.

Consider it untested for now.



Thank you!

Maxim

0001-lisp-autoload.el-Add-a-keyword-argument-to-update-di.patch (3K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

bug#39823: 26.3; update-directory-autoloads regression from Emacs 26 to Emacs 27

Noam Postavsky
Maxim Cournoyer <[hidden email]> writes:

> +  (let* (;; Honor the :generated-autoload-file keyword argument.
> +         (generated-autoload-file-arg (seq-position
> +                                       dirs ':generated-autoload-file))
> +         (generated-autoload-file (if generated-autoload-file-arg
> +                                      (elt dirs
> +                                           (1+ generated-autoload-file-arg))
> +                                    generated-autoload-file))
> +         ;; Cleanup dirs from such keyword argument, if any.
> +         (dirs (if generated-autoload-file-arg
> +                   (delete generated-autoload-file
> +                           (delete ':generated-autoload-file dirs))
> +                 dirs))

How about

    (let* ((generated-autoload-file
            (if (eq (car dirs) :generated-autoload-file)
                (progn (pop dirs) (pop dirs))
              generated-autoload-file))