Subject: bug#67523: check-declare doesn't account for shorthands

From: João Távora <[email-masked]>
Date: Wed, 29 Nov 2023 10:35:34 +0000

On Wed, Nov 29, 2023 at 9:56 AM João Távora <[email-masked]> wrote:
>
> On Wed, Nov 29, 2023 at 9:12 AM Joseph Turner <[email-masked]> wrote:
>
> > A potential solution could be to convert the longhand symbol into its
> > shorthand form and pass that into re-search-forward.  This is tricky
> > since there may be multiple different shorthands which could yield the
> > same longhand form.  It might be more feasible to run re-search-forward
> > on a known common suffix portion of the symbol name, then with point on
> > the suspected definition, run `intern-soft' to get the full symbol name.
>
> No, this is brittle.  Check-declare, if it's to be useful (is it?)
> is probably meant to be as precise as possible.
>
> > A workaround is to not use shorthands in function definitions.
>
> That's letting the bad guys win :-)
>
> > Thoughts?
>
> As usual, my thoughts are that tools that read Lisp code
> should use the Lisp reader, not regular expressions.
>
> Here, check-declare should just walk the whole file.

Or maybe just this 100% guaranteed untested patch would work:

diff --git a/lisp/emacs-lisp/check-declare.el b/lisp/emacs-lisp/check-declare.el
index c887d95210c..00440276643 100644
--- a/lisp/emacs-lisp/check-declare.el
+++ b/lisp/emacs-lisp/check-declare.el
@@ -145,6 +145,7 @@ check-declare-verify
     (if (file-regular-p fnfile)
         (with-temp-buffer
           (insert-file-contents fnfile)
+          (hack-local-variables) ;; for shorthands
           ;; defsubst's don't _have_ to be known at compile time.
           (setq re (format (if cflag
                                "^[ \t]*\\(DEFUN\\)[ \t]*([ \t]*\"%s\""
@@ -158,7 +159,7 @@ check-declare-verify
                            (regexp-opt (mapcar 'cadr fnlist) t)))
           (while (re-search-forward re nil t)
             (skip-chars-forward " \t\n")
-            (setq fn (match-string 2)
+            (setq fn (symbol-name (car (read-from-string (match-string 2))))
                   type (match-string 1)
                   ;; (min . max) for a fixed number of arguments, or
                   ;; arglists with optional elements.