Subject: bug#35802: Broken data loaded from uni-decomposition

From: Juri Linkov <[email-masked]>
Date: Wed, 12 Jun 2019 00:11:33 +0300

> Actually maybe it's just a matter of making isearch bind
> search-spaces-regexp less widely.  I'm not quite following when the your
> problem happens though.  Can you show a backtrace from your original
> problem using
>
>     (add-hook 'after-load-functions
>               (lambda (f) (when (string-match-p "uni-decomposition" f)
>                        (debug nil :search-spaces-regexp search-spaces-regexp))))

When I eval both the above and (setq search-whitespace-regexp "\\(\\s-\\|\n\\)+")
then debugger still shows that search-spaces-regexp is nil
(also note where search-spaces-regexp is let-bound to non-nil in the backtrace,
see also more info after the backtrace):

Debugger entered: (:search-spaces-regexp nil)
  (progn (debug nil :search-spaces-regexp search-spaces-regexp))
  (if (string-match-p "uni-decomposition" f) (progn (debug nil :search-spaces-regexp search-spaces-regexp)))
  (closure (t) (f) (if (string-match-p "uni-decomposition" f) (progn (debug nil :search-spaces-regexp search-spaces-regexp))))("emacs/lisp/international/uni-decomposition.el")
  run-hook-with-args((closure (t) (f) (if (string-match-p "uni-decomposition" f) (progn (debug nil :search-spaces-regexp search-spaces-regexp)))) "emacs/lisp/international/uni-decomposition.el")
  do-after-load-evaluation("emacs/lisp/international/uni-decomposition.el")
  load-with-code-conversion("emacs/lisp/international/uni-decomposition.el" "emacs/lisp/international/uni-decomposition.el" t t)
  unicode-property-table-internal(decomposition)
  char-fold-make-table()
  byte-code("\301 \20\301\207" [char-fold-table char-fold-make-table] 1)
  char-fold-to-regexp("a" (isearch-printing-char isearch-del-char))
  funcall(char-fold-to-regexp "a" (isearch-printing-char isearch-del-char))
  (if (functionp isearch-regexp-function) (funcall isearch-regexp-function string lax) (word-search-regexp string lax))
  (let ((lax (and (not bound) (isearch--lax-regexp-function-p)))) (if lax (progn (setq isearch-adjusted t))) (if (functionp isearch-regexp-function) (funcall isearch-regexp-function string lax) (word-search-regexp string lax)))
  (cond (isearch-regexp-function (let ((lax (and (not bound) (isearch--lax-regexp-function-p)))) (if lax (progn (setq isearch-adjusted t))) (if (functionp isearch-regexp-function) (funcall isearch-regexp-function string lax) (word-search-regexp string lax)))) (isearch-regexp string) (t (regexp-quote string)))
  (funcall (if isearch-forward #'re-search-forward #'re-search-backward) (cond (isearch-regexp-function (let ((lax (and (not bound) (isearch--lax-regexp-function-p)))) (if lax (progn (setq isearch-adjusted t))) (if (functionp isearch-regexp-function) (funcall isearch-regexp-function string lax) (word-search-regexp string lax)))) (isearch-regexp string) (t (regexp-quote string))) bound noerror count)
  (let ((search-spaces-regexp (if (cond (isearch-regexp isearch-regexp-lax-whitespace) (t isearch-lax-whitespace)) (progn search-whitespace-regexp)))) (funcall (if isearch-forward #'re-search-forward #'re-search-backward) (cond (isearch-regexp-function (let ((lax (and (not bound) (isearch--lax-regexp-function-p)))) (if lax (progn (setq isearch-adjusted t))) (if (functionp isearch-regexp-function) (funcall isearch-regexp-function string lax) (word-search-regexp string lax)))) (isearch-regexp string) (t (regexp-quote string))) bound noerror count))
  (closure (isearch-commands minibuffer-history-symbol t) (string &optional bound noerror count) (let ((search-spaces-regexp (if (cond (isearch-regexp isearch-regexp-lax-whitespace) (t isearch-lax-whitespace)) (progn search-whitespace-regexp)))) (funcall (if isearch-forward #'re-search-forward #'re-search-backward) (cond (isearch-regexp-function (let (...) (if lax ...) (if ... ... ...))) (isearch-regexp string) (t (regexp-quote string))) bound noerror count)))("a" nil t)
  funcall((closure (isearch-commands minibuffer-history-symbol t) (string &optional bound noerror count) (let ((search-spaces-regexp (if (cond (isearch-regexp isearch-regexp-lax-whitespace) (t isearch-lax-whitespace)) (progn search-whitespace-regexp)))) (funcall (if isearch-forward #'re-search-forward #'re-search-backward) (cond (isearch-regexp-function (let (...) (if lax ...) (if ... ... ...))) (isearch-regexp string) (t (regexp-quote string))) bound noerror count))) "a" nil t)
  (save-excursion (funcall func string bound noerror))
  (let* ((func (isearch-search-fun)) (pos1 (save-excursion (funcall func string bound noerror))) pos2) (if (and (with-no-warnings (char-table-p translation-table-for-input)) (multibyte-string-p string) (string-match-p "[^[:ascii:]]" string)) (progn (let ((translated (apply 'string (mapcar ... string))) match-data) (if translated (progn (let (...) (unwind-protect ... ...)) (if (and pos2 ...) (progn ... ...))))))) (if pos1 (progn (if (and multi-isearch-next-buffer-current-function (buffer-live-p multi-isearch-current-buffer)) (switch-to-buffer multi-isearch-current-buffer)) (goto-char pos1) pos1)))
  isearch-search-string("a" nil t)
  isearch-search()
  isearch-search-and-update()
  isearch-process-search-string("a" "a")
  isearch-process-search-char(97 1)
  isearch-printing-char(97 1)
  funcall-interactively(isearch-printing-char 97 1)
  call-interactively(isearch-printing-char nil nil)
  command-execute(isearch-printing-char)

But when I add (message "search-spaces-regexp: %S" search-spaces-regexp)
at the top level in char-fold.el, then after its autoload from isearch,
the *Message* buffer contains:

  search-spaces-regexp: "\\(\\s-\\|
  \\)+"