Subject: bug#57502: 29.0.50; Issue with `or' clause of buffer-match-p

From: Philip Kaludercic <[email-masked]>
Date: Wed, 31 Aug 2022 12:47:07 +0000

Augusto Stoffel <[email-masked]> writes:

> This buffer-match-p condition does the expected job:
>
>      (buffer-match-p '(or "\\*" (derived-mode . special-mode))
>                      (current-buffer))
>
> But this presumably equivalent one gives a “(wrong-type-argument listp
> special-mode)” error:
>
>      (buffer-match-p '(or (and "\\*")
>                           (derived-mode . special-mode))
>                      (current-buffer))

It seems to me that the issue is related to the `and' being wrapped by
an `or', specifically because of a typo in the handling of `and':

diff --git a/lisp/subr.el b/lisp/subr.el
index 2ffc594997..0350c16ccf 100644
--- a/lisp/subr.el
+++ b/lisp/subr.el
@@ -7014,8 +7014,8 @@ buffer-match-p
                       (funcall match (cdr condition)))
                      ((eq (car-safe condition) 'and)
                       (catch 'fail
-                        (dolist (c (cdr conditions))
-                          (unless (funcall match c)
+                        (dolist (c (cdr condition))
+                          (unless (funcall match (list c))
                             (throw 'fail nil)))
                         t)))
                 (throw 'match t)))))))

As you have pointed out to me privately, it might make sense to rewrite
the case distinction using pcase, to avoid simple mistakes like these.