Add empty-body warning for when, unless etc

Warn about code like (when SOME-CONDITION) because these may indicate
bugs.  Warnings currently apply to `when`, `unless`, `ignore-error`,
`with-suppressed-warnings` and (as before) `let` and `let*`.

* lisp/emacs-lisp/byte-run.el (with-suppressed-warnings):
Update doc string.
* lisp/emacs-lisp/bytecomp.el: (byte-compile-warning-types)
(byte-compile-warnings): Add empty-body.
(byte-compile-initial-macro-environment):
Add empty-body warning for with-suppressed-warnings.
* lisp/emacs-lisp/macroexp.el (macroexp--expand-all):
Use the empty-body category for let and let*.
* lisp/subr.el (when, unless, ignore-error): Add empty-body warning.
* test/lisp/emacs-lisp/bytecomp-tests.el
(bytecomp-test--with-suppressed-warnings): Add test cases.
This commit is contained in:
Mattias Engdegård 2022-12-29 13:01:47 +01:00
parent 2de25accaf
commit 7c63b632e4
5 changed files with 84 additions and 24 deletions

View file

@ -649,8 +649,8 @@ in `byte-compile-warning-types'; see the variable
`byte-compile-warnings' for a fuller explanation of the warning
types. The types that can be suppressed with this macro are
`free-vars', `callargs', `redefine', `obsolete',
`interactive-only', `lexical', `mapcar', `constants' and
`suspicious'.
`interactive-only', `lexical', `mapcar', `constants',
`suspicious' and `empty-body'.
For the `mapcar' case, only the `mapcar' function can be used in
the symbol list. For `suspicious', only `set-buffer', `lsh' and `eq'

View file

@ -295,7 +295,8 @@ The information is logged to `byte-compile-log-buffer'."
'(redefine callargs free-vars unresolved
obsolete noruntime interactive-only
make-local mapcar constants suspicious lexical lexical-dynamic
docstrings docstrings-non-ascii-quotes not-unused)
docstrings docstrings-non-ascii-quotes not-unused
empty-body)
"The list of warning types used when `byte-compile-warnings' is t.")
(defcustom byte-compile-warnings t
"List of warnings that the byte-compiler should issue (t for almost all).
@ -326,6 +327,7 @@ Elements of the list may be:
docstrings-non-ascii-quotes docstrings that have non-ASCII quotes.
This depends on the `docstrings' warning type.
suspicious constructs that usually don't do what the coder wanted.
empty-body body argument to a special form or macro is empty.
If the list begins with `not', then the remaining elements specify warnings to
suppress. For example, (not mapcar) will suppress warnings about mapcar.
@ -541,15 +543,19 @@ Return the compile-time value of FORM."
;; Later `internal--with-suppressed-warnings' binds it again, this
;; time in order to affect warnings emitted during the
;; compilation itself.
(let ((byte-compile--suppressed-warnings
(append warnings byte-compile--suppressed-warnings)))
;; This function doesn't exist, but is just a placeholder
;; symbol to hook up with the
;; `byte-hunk-handler'/`byte-defop-compiler-1' machinery.
`(internal--with-suppressed-warnings
',warnings
,(macroexpand-all `(progn ,@body)
macroexpand-all-environment))))))
(if body
(let ((byte-compile--suppressed-warnings
(append warnings byte-compile--suppressed-warnings)))
;; This function doesn't exist, but is just a placeholder
;; symbol to hook up with the
;; `byte-hunk-handler'/`byte-defop-compiler-1' machinery.
`(internal--with-suppressed-warnings
',warnings
,(macroexpand-all `(progn ,@body)
macroexpand-all-environment)))
(macroexp-warn-and-return
"`with-suppressed-warnings' with empty body"
nil '(empty-body with-suppressed-warnings) t warnings)))))
"The default macro-environment passed to macroexpand by the compiler.
Placing a macro here will cause a macro to have different semantics when
expanded by the compiler as when expanded by the interpreter.")

View file

@ -368,7 +368,7 @@ Assumes the caller has bound `macroexpand-all-environment'."
(macroexp-unprogn
(macroexp-warn-and-return
(format "Empty %s body" fun)
nil nil 'compile-only fun))
nil (list 'empty-body fun) 'compile-only fun))
(macroexp--all-forms body))
(cdr form))
form)))