[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

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

From: Maxim Cournoyer
Subject: bug#39823: 26.3; update-directory-autoloads regression from Emacs 26 to Emacs 27
Date: Fri, 28 Feb 2020 10:11:54 -0500


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

--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'
 {st_mode=S_IFREG|0444, st_size=29029, ...}) = 0--8<---------------cut 

Its content is copied below:
--8<---------------cut here---------------start------------->8---
;;; 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
 - 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:

(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 
\301    %\262\202_\f\30%\262\202o                                               
                      \301\f%\266\202\202?      \301\n%\262\202O
 [load-file-name nil defalias #[1285 

\303\211&\262\\303\211&\262\202g\211\303\211&\207" ['function #[1542 "\242;\203
   \257\207" [interactive t help-add-fundoc-usage autoload] 14 "\n\n(fn FORM 
#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 
 [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)
 [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)
             \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)

(fn FILE)
(defalias 'autoload-ensure-file-writeable #[257 
 [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.

(defalias 'autoload-insert-section-header #[1285 
      \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)
 [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 
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)

(defalias 'autoload--make-defs-autoload #[514 
 [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 
 [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)])

(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)])

(defalias 'autoload--print-cookie-text #[771 "\303!\304 
 [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 
 [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        
 \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 (#$ . 
(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.

(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.

(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 
 [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)])

(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 
      \335    !\205[\336      !\3278\262r\337 q\210\212\340\341\n!\320\341      
     \"\26\266\202p)\206:\352\353\354\355\341        !P!\346 G\306\356%\346\306 
 \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\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 :-)


reply via email to

[Prev in Thread] Current Thread [Next in Thread]