From 8d651d7247c4e8cf07ba805712cdb09e8095dd89 Mon Sep 17 00:00:00 2001
Message-ID: <8d651d7247c4e8cf07ba805712cdb09e8095dd89.1773006315.git.dannym@friendly-machines.com>
From: Danny Milosavljevic <dannym@friendly-machines.com>
Date: Sun, 8 Mar 2026 21:44:05 +0000
Subject: [PATCH] Scope native-comp trampoline disabling to spy-on only
See: <https://github.com/jorgenschaefer/emacs-buttercup/pull/257>

buttercup-with-cleanup disabled native-comp-enable-subr-trampolines
for the entire spec execution.  This was a workaround for Emacs
bug#61880, where trampoline compilation fails when spy-on redefines
primitives that the trampoline compiler itself depends on (e.g.
file-exists-p).

However, disabling trampolines globally has the side effect that fset
overrides of C primitives become invisible to natively compiled code.
This breaks shut-up's message override when called indirectly through
native-compiled functions like display-message-or-buffer (from
simple.eln), because without a trampoline, the native code calls the C
primitive directly, bypassing the fset'd function.

Move the trampoline disabling from buttercup-with-cleanup into
buttercup--spy-on-and-call-replacement, scoping it to just the fset
call that installs the spy.  This avoids the trampoline compilation
issue while allowing other fset overrides (e.g. from shut-up or
cl-letf) to work correctly with native-compiled callers.
---
 buttercup.el | 34 +++++++++++++++++-----------------
 1 file changed, 17 insertions(+), 17 deletions(-)

diff --git a/buttercup.el b/buttercup.el
index 07e003f..417786d 100644
--- a/buttercup.el
+++ b/buttercup.el
@@ -1293,12 +1293,23 @@ responsibility to ensure ARG is a command."
       (error "Spies can only be created in `before-each' or `it'"))))
 
 
+(defvar native-comp-enable-subr-trampolines)
+(defvar comp-enable-subr-trampolines)
+
 (defun buttercup--spy-on-and-call-replacement (spy fun)
   "Replace the function in symbol SPY with a spy calling FUN."
   (let ((orig-function (and (fboundp spy) (symbol-function spy))))
     (when (buttercup--add-cleanup (lambda ()
                                   (fset spy orig-function)))
-      (fset spy (buttercup--make-spy fun)))))
+      ;; Disable subr trampoline generation around the fset call.
+      ;; Redefining certain primitives causes trampoline compilation
+      ;; to fail because the trampoline compiler itself depends on
+      ;; primitives that may have just been redefined.
+      ;; See <https://github.com/jorgenschaefer/emacs-buttercup/issues/230>
+      ;; and <https://debbugs.gnu.org/61880>.
+      (let ((native-comp-enable-subr-trampolines nil)
+            (comp-enable-subr-trampolines nil))
+        (fset spy (buttercup--make-spy fun))))))
 
 (defun buttercup--make-spy (fun)
   "Create a new spy function wrapping FUN and tracking every call to itself."
@@ -1343,24 +1354,13 @@ responsibility to ensure ARG is a command."
 Should always be set to a value that is not `listp', except while
 in a `buttercup-with-cleanup' environment.")
 
-(defvar native-comp-enable-subr-trampolines)
-(defvar comp-enable-subr-trampolines)
-
 (defmacro buttercup-with-cleanup (&rest body)
   "Execute BODY, cleaning spys and the rest afterwards."
-  `(,@(if (fboundp 'with-suppressed-warnings)
-          '(with-suppressed-warnings ((obsolete comp-enable-subr-trampolines)))
-        '(progn))
-     (let ((buttercup--cleanup-functions nil)
-           ;; Redefining certain primitive's trampolines will cause problems,
-           ;; see https://github.com/jorgenschaefer/emacs-buttercup/issues/230 and
-           ;; https://debbugs.gnu.org/cgi/bugreport.cgi?bug=61880
-           (comp-enable-subr-trampolines nil)
-           (native-comp-enable-subr-trampolines nil))
-       (unwind-protect (progn ,@body)
-         (dolist (fun buttercup--cleanup-functions)
-           (ignore-errors
-             (funcall fun)))))))
+  `(let ((buttercup--cleanup-functions nil))
+     (unwind-protect (progn ,@body)
+       (dolist (fun buttercup--cleanup-functions)
+         (ignore-errors
+           (funcall fun))))))
 
 (defun buttercup--add-cleanup (function)
   "Register FUNCTION for cleanup in `buttercup-with-cleanup'."

base-commit: cc5a2ab7c7f18aaaf525fac61fe59bae5ad018dd
-- 
2.52.0
