Subject: bug#70597: Problem in pcase-let?

From: Stefan Monnier <[email-masked]>
Date: Sat, 04 May 2024 11:23:16 -0400

> I haven't looked at the code for it, so I don't know how easy it is to
> implement, but let' hope there's an "easy" way to do it.

Hmm... the patch below kind of works, but it's not ideal and it's not
easy to fix its shortcomings:

- It happens a bit "too late", i.e. at a level where the pattern has
  already been macro-expanded so the message may refer to a subpattern
  that's not readily present in the source code.
  [ I think we can live with this.  ]
- It applies to more situations than just `pcase-let`, and for some of
  them the warning is not desirable.
- It has a few false positives.

This last point is because of a fuzziness about what it is we want to
warn about: in a pattern like `[a ,b] there are fundamentally 3 tests:

- Is the pattern of type `vector`.
- Does the vector have size 2.
- Is the first element equal to `a`.

We want to drop all three.  But we don't want to warn about the first
two, since there's no convenient way to write a pattern without them.
But for some other patterns the equivalent to the first point above can
look like `(equal (type-of foo) 'bar)` and thus ends up caught in our
warning (which basically warns when we test that something is equal
to some constant), even though there's no other way to write the pattern.

        Stefan

diff --git a/lisp/emacs-lisp/pcase.el b/lisp/emacs-lisp/pcase.el
index 23f1bac600c..f0302dbcbe0 100644
--- a/lisp/emacs-lisp/pcase.el
+++ b/lisp/emacs-lisp/pcase.el
@@ -1050,6 +1058,11 @@ pcase--u1
              `((,nsym ,(pcase--funcall fun sym vars)))
              body))))
        ((eq (car-safe upat) 'quote)
+        (when (and (length= rest 1)
+                   (not (memq (cadr upat) '(nil _))) ;Too common.
+                   (eq 'match (car-safe (caar rest)))
+                   (eq 'pcase--dontcare (cddr (caar rest))))
+          (message "Ignoring pattern %S, you might replace it with _" upat))
         (pcase--mark-used sym)
         (let* ((val (cadr upat))
                (splitrest (pcase--split-rest