From 305744fdfc2ec97c9eb2214c35dca8f350f4e209 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mattias=20Engdeg=C3=A5rd?= Date: Wed, 29 Oct 2025 13:02:32 +0100 Subject: [PATCH] Define compiler macros for /=, atom and nlistp Calls to these functions were previously rewritten in terms of other functions both in the optimiser and during codegen, for no good reason. This also resulted in poor diagnostics: wrong-arity calls to 'atom' and 'nlistp' produced doubled but slightly-different warnings, and no warnings at all for '/='. Using compiler macros fixes the problems. The generated code is the same. * lisp/emacs-lisp/bytecomp.el (byte-compile-negated) (byte-compile-negation-optimizer): Replace with... (bytecomp--define-negated): ...this compiler macro defining macro. --- lisp/emacs-lisp/byte-opt.el | 6 ------ lisp/emacs-lisp/bytecomp.el | 34 ++++++++++++---------------------- 2 files changed, 12 insertions(+), 28 deletions(-) diff --git a/lisp/emacs-lisp/byte-opt.el b/lisp/emacs-lisp/byte-opt.el index 869d07016d6..d936d7e341c 100644 --- a/lisp/emacs-lisp/byte-opt.el +++ b/lisp/emacs-lisp/byte-opt.el @@ -1424,12 +1424,6 @@ See Info node `(elisp) Integer Basics'." (put 'not 'byte-optimizer #'byte-optimize-not) (put 'null 'byte-optimizer #'byte-optimize-not) -;; byte-compile-negation-optimizer lives in bytecomp.el -(put '/= 'byte-optimizer #'byte-compile-negation-optimizer) -(put 'atom 'byte-optimizer #'byte-compile-negation-optimizer) -(put 'nlistp 'byte-optimizer #'byte-compile-negation-optimizer) - - (defun byte-optimize-funcall (form) ;; (funcall #'(lambda ...) ...) -> (let ...) ;; (funcall #'SYM ...) -> (SYM ...) diff --git a/lisp/emacs-lisp/bytecomp.el b/lisp/emacs-lisp/bytecomp.el index b016b04c2d3..3ba934b13ae 100644 --- a/lisp/emacs-lisp/bytecomp.el +++ b/lisp/emacs-lisp/bytecomp.el @@ -4911,28 +4911,6 @@ binding slots have been popped." (> byte-compile-depth init-stack-depth)))))) - -(byte-defop-compiler-1 /= byte-compile-negated) -(byte-defop-compiler-1 atom byte-compile-negated) -(byte-defop-compiler-1 nlistp byte-compile-negated) - -(put '/= 'byte-compile-negated-op '=) -(put 'atom 'byte-compile-negated-op 'consp) -(put 'nlistp 'byte-compile-negated-op 'listp) - -(defun byte-compile-negated (form) - (byte-compile-form-do-effect (byte-compile-negation-optimizer form))) - -;; Even when optimization is off, /= is optimized to (not (= ...)). -(defun byte-compile-negation-optimizer (form) - ;; an optimizer for forms where is less efficient than (not ) - (list 'not - (cons (or (get (car form) 'byte-compile-negated-op) - (error - "Compiler error: `%s' has no `byte-compile-negated-op' property" - (car form))) - (cdr form)))) - ;;; other tricky macro-like special-forms (byte-defop-compiler-1 catch) @@ -5883,6 +5861,18 @@ and corresponding effects." (featurep (cadr feature)) form))) +(defmacro bytecomp--define-negated (fn arity negfn) + "Define FN with ARITY as the Boolean negation of NEGFN." + `(put ',fn 'compiler-macro + (lambda (form &rest args) + (if (= (length args) ,arity) + (list 'not (cons ',negfn args)) + form)))) + +(bytecomp--define-negated /= 2 = ) +(bytecomp--define-negated atom 1 consp) +(bytecomp--define-negated nlistp 1 listp) + ;; Report comma operator used outside of backquote. ;; Inside backquote, backquote will transform it before it gets here.