unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
From: Spencer Baugh <sbaugh@janestreet.com>
To: 66326@debbugs.gnu.org
Subject: bug#66326: 29.1.50; There should be a way to promote warnings to errors
Date: Tue, 03 Oct 2023 14:39:02 -0400	[thread overview]
Message-ID: <iero7hfv9dl.fsf@janestreet.com> (raw)
In-Reply-To: <ierr0mbveyt.fsf@janestreet.com> (Spencer Baugh's message of "Tue, 03 Oct 2023 12:38:18 -0400")

[-- Attachment #1: Type: text/plain, Size: 27 bytes --]


Patch implementing this:


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-Support-turning-warnings-into-errors.patch --]
[-- Type: text/x-patch, Size: 10631 bytes --]

From 6fad83ea8729569c968ccdfc1ec2807387bc979e Mon Sep 17 00:00:00 2001
From: Spencer Baugh <sbaugh@janestreet.com>
Date: Tue, 3 Oct 2023 14:36:25 -0400
Subject: [PATCH] Support turning warnings into errors

Support turning warnings into errors in a user-configurable way.  This
is especially useful in combination with (setq debug-on-error t) to
drop to the debugger when a warning happens.

* lisp/emacs-lisp/warnings.el (warning-suppress-types): Improve
docstring.
(warning-to-error-types, warning-to-error): Add.
(display-warning): Check warning-to-error-types.
---
 lisp/emacs-lisp/warnings.el | 209 ++++++++++++++++++++----------------
 1 file changed, 114 insertions(+), 95 deletions(-)

diff --git a/lisp/emacs-lisp/warnings.el b/lisp/emacs-lisp/warnings.el
index 31b840d6c83..9e0a35b87bb 100644
--- a/lisp/emacs-lisp/warnings.el
+++ b/lisp/emacs-lisp/warnings.el
@@ -114,11 +114,20 @@ warning-suppress-types
 The element must match an initial segment of the list TYPE.
 Thus, (foo bar) as an element matches (foo bar)
 or (foo bar ANYTHING...) as TYPE.
+An empty list as an element matches any TYPE.
 If TYPE is a symbol FOO, that is equivalent to the list (FOO),
 so only the element (FOO) will match it.
 See also `warning-suppress-log-types'."
   :type '(repeat (repeat symbol))
   :version "22.1")
+
+(defcustom warning-to-error-types nil
+  "List of warning types to signal as an error instead.
+If any element of this list matches the TYPE argument to `display-warning',
+an error is signaled instead of logging a warning.
+See `warning-suppress-types' for the format of elements in this list."
+  :type '(repeat (repeat symbol))
+  :version "30.1")
 \f
 ;; The autoload cookie is so that programs can bind this variable
 ;; safely, testing the existing value, before they call one of the
@@ -230,6 +239,12 @@ warnings-suppress
                               (cons (list type) warning-suppress-types)))
     (_ (message "Exiting"))))
 
+(defun warning-to-error (type message level)
+  (let* ((typename (if (consp type) (car type) type))
+         (level-info (assq level warning-levels)))
+    (error (nth 1 level-info)
+           (format warning-type-format typename))))
+
 ;;;###autoload
 (defun display-warning (type message &optional level buffer-name)
   "Display a warning message, MESSAGE.
@@ -263,105 +278,109 @@ display-warning
 disable automatic display of the warning or disable the warning
 entirely by setting `warning-suppress-types' or
 `warning-suppress-log-types' on their behalf."
-  (if (not (or after-init-time noninteractive (daemonp)))
-      ;; Ensure warnings that happen early in the startup sequence
-      ;; are visible when startup completes (bug#20792).
-      (delay-warning type message level buffer-name)
-    (unless level
-      (setq level :warning))
-    (unless buffer-name
-      (setq buffer-name "*Warnings*"))
+  (unless level
+    (setq level :warning))
+  (unless buffer-name
+    (setq buffer-name "*Warnings*"))
+  (cond
+   ((< (warning-numeric-level level)
+       (warning-numeric-level warning-minimum-log-level)))
+   ((warning-suppress-p type warning-suppress-log-types))
+   ((warning-suppress-p type warning-to-error-types)
+    (warning-to-error type message level))
+   ((not (or after-init-time noninteractive (daemonp)))
+    ;; Ensure warnings that happen early in the startup sequence
+    ;; are visible when startup completes (bug#20792).
+    (delay-warning type message level buffer-name))
+   (t
     (with-suppressed-warnings ((obsolete warning-level-aliases))
       (when-let ((new (cdr (assq level warning-level-aliases))))
         (warn "Warning level `%s' is obsolete; use `%s' instead" level new)
         (setq level new)))
-    (or (< (warning-numeric-level level)
-	   (warning-numeric-level warning-minimum-log-level))
-	(warning-suppress-p type warning-suppress-log-types)
-	(let* ((typename (if (consp type) (car type) type))
-	       (old (get-buffer buffer-name))
-	       (buffer (or old (get-buffer-create buffer-name)))
-	       (level-info (assq level warning-levels))
-               ;; `newline' may be unbound during bootstrap.
-               (newline (if (fboundp 'newline) #'newline
-                          (lambda () (insert "\n"))))
-	       start end)
-	  (with-current-buffer buffer
-	    ;; If we created the buffer, disable undo.
-	    (unless old
-	      (when (fboundp 'special-mode) ; Undefined during bootstrap.
-                (special-mode))
-	      (setq buffer-read-only t)
-	      (setq buffer-undo-list t))
-	    (goto-char (point-max))
-	    (when (and warning-series (symbolp warning-series))
-	      (setq warning-series
-		    (prog1 (point-marker)
-		      (unless (eq warning-series t)
-			(funcall warning-series)))))
-	    (let ((inhibit-read-only t))
-	      (unless (bolp)
-		(funcall newline))
-	      (setq start (point))
-              ;; Don't output the button when doing batch compilation
-              ;; and similar.
-              (unless (or noninteractive (eq type 'bytecomp))
-                (insert (buttonize (icon-string 'warnings-suppress)
-                                   #'warnings-suppress type)
-                        " "))
-	      (if warning-prefix-function
-		  (setq level-info (funcall warning-prefix-function
-					    level level-info)))
-	      (insert (format (nth 1 level-info)
-			      (format warning-type-format typename))
-		      message)
-              (funcall newline)
-	      (when (and warning-fill-prefix
-                         (not (string-search "\n" message))
-                         (not noninteractive))
-		(let ((fill-prefix warning-fill-prefix)
-		      (fill-column warning-fill-column))
-		  (fill-region start (point))))
-	      (setq end (point)))
-	    (when (and (markerp warning-series)
-		       (eq (marker-buffer warning-series) buffer))
-	      (goto-char warning-series)))
-	  (if (nth 2 level-info)
-	      (funcall (nth 2 level-info)))
-	  (cond (noninteractive
-		 ;; Noninteractively, take the text we inserted
-		 ;; in the warnings buffer and print it.
-		 ;; Do this unconditionally, since there is no way
-		 ;; to view logged messages unless we output them.
-		 (with-current-buffer buffer
-		   (save-excursion
-		     ;; Don't include the final newline in the arg
-		     ;; to `message', because it adds a newline.
-		     (goto-char end)
-		     (if (bolp)
-			 (forward-char -1))
-		     (message "%s" (buffer-substring start (point))))))
-		((and (daemonp) (null after-init-time))
-		 ;; Warnings assigned during daemon initialization go into
-		 ;; the messages buffer.
-		 (message "%s"
-			  (with-current-buffer buffer
-			    (save-excursion
-			      (goto-char end)
-			      (if (bolp)
-				  (forward-char -1))
-			      (buffer-substring start (point))))))
-		(t
-		 ;; Interactively, decide whether the warning merits
-		 ;; immediate display.
-		 (or (< (warning-numeric-level level)
-			(warning-numeric-level warning-minimum-level))
-		     (warning-suppress-p type warning-suppress-types)
-		     (let ((window (display-buffer buffer)))
-		       (when (and (markerp warning-series)
-				  (eq (marker-buffer warning-series) buffer))
-			 (set-window-start window warning-series))
-		       (sit-for 0)))))))))
+    (let* ((typename (if (consp type) (car type) type))
+	   (old (get-buffer buffer-name))
+	   (buffer (or old (get-buffer-create buffer-name)))
+	   (level-info (assq level warning-levels))
+           ;; `newline' may be unbound during bootstrap.
+           (newline (if (fboundp 'newline) #'newline
+                      (lambda () (insert "\n"))))
+	   start end)
+      (with-current-buffer buffer
+	;; If we created the buffer, disable undo.
+	(unless old
+	  (when (fboundp 'special-mode) ; Undefined during bootstrap.
+            (special-mode))
+	  (setq buffer-read-only t)
+	  (setq buffer-undo-list t))
+	(goto-char (point-max))
+	(when (and warning-series (symbolp warning-series))
+	  (setq warning-series
+		(prog1 (point-marker)
+		  (unless (eq warning-series t)
+		    (funcall warning-series)))))
+	(let ((inhibit-read-only t))
+	  (unless (bolp)
+	    (funcall newline))
+	  (setq start (point))
+          ;; Don't output the button when doing batch compilation
+          ;; and similar.
+          (unless (or noninteractive (eq type 'bytecomp))
+            (insert (buttonize (icon-string 'warnings-suppress)
+                               #'warnings-suppress type)
+                    " "))
+	  (if warning-prefix-function
+	      (setq level-info (funcall warning-prefix-function
+					level level-info)))
+	  (insert (format (nth 1 level-info)
+			  (format warning-type-format typename))
+		  message)
+          (funcall newline)
+	  (when (and warning-fill-prefix
+                     (not (string-search "\n" message))
+                     (not noninteractive))
+	    (let ((fill-prefix warning-fill-prefix)
+		  (fill-column warning-fill-column))
+	      (fill-region start (point))))
+	  (setq end (point)))
+	(when (and (markerp warning-series)
+		   (eq (marker-buffer warning-series) buffer))
+	  (goto-char warning-series)))
+      (if (nth 2 level-info)
+	  (funcall (nth 2 level-info)))
+      (cond (noninteractive
+	     ;; Noninteractively, take the text we inserted
+	     ;; in the warnings buffer and print it.
+	     ;; Do this unconditionally, since there is no way
+	     ;; to view logged messages unless we output them.
+	     (with-current-buffer buffer
+	       (save-excursion
+		 ;; Don't include the final newline in the arg
+		 ;; to `message', because it adds a newline.
+		 (goto-char end)
+		 (if (bolp)
+		     (forward-char -1))
+		 (message "%s" (buffer-substring start (point))))))
+	    ((and (daemonp) (null after-init-time))
+	     ;; Warnings assigned during daemon initialization go into
+	     ;; the messages buffer.
+	     (message "%s"
+		      (with-current-buffer buffer
+			(save-excursion
+			  (goto-char end)
+			  (if (bolp)
+			      (forward-char -1))
+			  (buffer-substring start (point))))))
+	    (t
+	     ;; Interactively, decide whether the warning merits
+	     ;; immediate display.
+	     (or (< (warning-numeric-level level)
+		    (warning-numeric-level warning-minimum-level))
+		 (warning-suppress-p type warning-suppress-types)
+		 (let ((window (display-buffer buffer)))
+		   (when (and (markerp warning-series)
+			      (eq (marker-buffer warning-series) buffer))
+		     (set-window-start window warning-series))
+		   (sit-for 0)))))))))
 \f
 ;; Use \\<special-mode-map> so that help-enable-autoload can do its thing.
 ;; Any keymap that is defined will do.
-- 
2.39.3


  reply	other threads:[~2023-10-03 18:39 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-10-03 16:38 bug#66326: 29.1.50; There should be a way to promote warnings to errors Spencer Baugh
2023-10-03 18:39 ` Spencer Baugh [this message]
2023-10-03 18:57   ` Eli Zaretskii
2023-10-03 19:16     ` sbaugh
2023-10-04  5:59       ` Eli Zaretskii
2023-10-04 12:20         ` Spencer Baugh
2023-10-14  7:27           ` Eli Zaretskii
2023-10-14 22:25             ` sbaugh
2023-10-15  5:45               ` Eli Zaretskii
2023-10-16 19:26                 ` Spencer Baugh
2023-10-19 12:13                   ` Eli Zaretskii
2023-10-19 14:50                     ` Spencer Baugh
2023-10-19 15:07                       ` Eli Zaretskii
2023-10-19 15:18                         ` Spencer Baugh
2023-10-19 15:42                           ` Eli Zaretskii
2023-10-19 16:15                             ` Spencer Baugh
2023-10-20  7:20                               ` Eli Zaretskii
2023-10-21  9:12                                 ` Stefan Kangas
2023-10-21 13:43                                   ` sbaugh
2023-11-10 21:40                                     ` Spencer Baugh
2023-11-11  7:02                                       ` Eli Zaretskii
2023-11-11 14:37                                         ` Spencer Baugh
2023-11-11 14:51                                           ` Eli Zaretskii

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/emacs/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=iero7hfv9dl.fsf@janestreet.com \
    --to=sbaugh@janestreet.com \
    --cc=66326@debbugs.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).