master 6f2cc5417fc: gv.el (cond): Emit a warning if there's no default branch

Stefan Monnier via Mailing list for Emacs changes <[email protected]>
Newsgroups gmane.emacs.diffs
Message-ID <[email protected]>
branch: master
commit 6f2cc5417fc568edc719227019bfdc3cae205f6c
Author: Stefan Monnier <[email protected]>
Commit: Stefan Monnier <[email protected]>

    gv.el (cond): Emit a warning if there's no default branch
    
    * lisp/emacs-lisp/gv.el (gv--cond-expander): New function, extracted
    from the `gv-expander` of `cond`.
    (cond) <gv-expander>: Use it, and add a warning for missing default branch.
---
 lisp/emacs-lisp/gv.el | 74 ++++++++++++++++++++++++++++++---------------------
 1 file changed, 43 insertions(+), 31 deletions(-)

diff --git a/lisp/emacs-lisp/gv.el b/lisp/emacs-lisp/gv.el
index 625eaedf844..74bafc6a294 100644
--- a/lisp/emacs-lisp/gv.el
+++ b/lisp/emacs-lisp/gv.el
@@ -532,37 +532,49 @@ See also `incf'."
 
 (put 'cond 'gv-expander
      (lambda (do &rest branches)
-       (if (or (not lexical-binding)  ;The other code requires lexical-binding.
-               (macroexp-small-p (funcall do 'dummy (lambda (_) 'dummy))))
-           ;; This duplicates the `do' code, which is a problem if that
-           ;; code is large, but otherwise results in more efficient code.
-           `(cond
-             ,@(mapcar (lambda (branch)
-                         (if (cdr branch)
-                             (cons (car branch)
-                                   (macroexp-unprogn
-                                    (gv-get (macroexp-progn (cdr branch)) do)))
-                           (gv-get (car branch) do)))
-                       branches))
-         (let ((v (gensym "v")))
-           (macroexp-let2 nil
-               gv `(cond
-                    ,@(mapcar
-                       (lambda (branch)
-                         (if (cdr branch)
-                             `(,(car branch)
-                               ,@(macroexp-unprogn
-                                  (gv-letplace (getter setter)
-                                      (macroexp-progn (cdr branch))
-                                    `(cons (lambda () ,getter)
-                                           (lambda (,v) ,(funcall setter v))))))
-                           (gv-letplace (getter setter)
-                               (car branch)
-                             `(cons (lambda () ,getter)
-                                    (lambda (,v) ,(funcall setter v))))))
-                       branches))
-             (funcall do `(funcall (car ,gv))
-                      (lambda (v) `(funcall (cdr ,gv) ,v))))))))
+       (let ((res (apply #'gv--cond-expander do branches))
+             (last-test (caar (last branches))))
+         (if (and (macroexp-const-p last-test)
+                  (if (consp last-test) (cadr last-test) last-test))
+             res
+           ;; There is no setter for the nil expression, so a missing default
+           ;; branch is a bug (bug#81217).  Let's not signal an error, tho,
+           ;; for backward compatibility reasons.
+           (macroexp-warn-and-return "Missing default branch in cond"
+                                     res '(suspicious cond))))))
+
+(defun gv--cond-expander (do &rest branches)
+  (if (or (not lexical-binding) ;The other code requires lexical-binding.
+          (macroexp-small-p (funcall do 'dummy (lambda (_) 'dummy))))
+      ;; This duplicates the `do' code, which is a problem if that
+      ;; code is large, but otherwise results in more efficient code.
+      `(cond
+        ,@(mapcar (lambda (branch)
+                    (if (cdr branch)
+                        (cons (car branch)
+                              (macroexp-unprogn
+                               (gv-get (macroexp-progn (cdr branch)) do)))
+                      (gv-get (car branch) do)))
+                  branches))
+    (let ((v (gensym "v")))
+      (macroexp-let2 nil
+          gv `(cond
+               ,@(mapcar
+                  (lambda (branch)
+                    (if (cdr branch)
+                        `(,(car branch)
+                          ,@(macroexp-unprogn
+                             (gv-letplace (getter setter)
+                                 (macroexp-progn (cdr branch))
+                               `(cons (lambda () ,getter)
+                                      (lambda (,v) ,(funcall setter v))))))
+                      (gv-letplace (getter setter)
+                          (car branch)
+                        `(cons (lambda () ,getter)
+                               (lambda (,v) ,(funcall setter v))))))
+                  branches))
+        (funcall do `(funcall (car ,gv))
+                 (lambda (v) `(funcall (cdr ,gv) ,v)))))))
 
 (put 'error 'gv-expander
      (lambda (do &rest args)
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.