From 68709fe93a2b023d03b107473438e791036b31ef Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Thu, 14 May 2020 22:32:03 -0400 Subject: [PATCH] Fix letf! sometimes losing letf binds When expanding: (quiet! ...) You'd expect (simplified for explanation): (letf! ((standard-output ...) ((symbol-function #'message) ...) ((symbol-function #'load-file) ...) ((symbol-function #'write-region) ...)) ...) But instead get: (letf! ((standard-output ...)) ;; where'd the other binds go? ...) This was due to data-loss caused by nreverse's destructive mutation of the given bindings. Also: silences byte-compiler complaining about unused bindings. --- core/core-lib.el | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/core/core-lib.el b/core/core-lib.el index 1e3dc6244..adabe49c6 100644 --- a/core/core-lib.el +++ b/core/core-lib.el @@ -210,20 +210,21 @@ the same name, for use with `funcall' or `apply'. ARGLIST and BODY are as in (setq body (macroexp-progn body)) (when (memq (car bindings) '(defun defmacro)) (setq bindings (list bindings))) - (dolist (binding (nreverse bindings) body) + (dolist (binding (reverse bindings) (macroexpand body)) (let ((type (car binding)) (rest (cdr binding))) (setq body (pcase type (`defmacro `(cl-macrolet ((,(car rest) ,(cadr rest) ,@(cddr rest))) ,body)) (`defun `(cl-letf* ((,(car rest) (symbol-function #',(car rest))) - ((symbol-function #',(car rest)) - (lambda ,(cadr rest) ,@(cddr rest)))) - ,body)) + ((symbol-function #',(car rest)) + (lambda ,(cadr rest) ,@(cddr rest)))) + (ignore ,(car rest)) + ,body)) (_ (when (eq (car-safe type) 'function) - (setq type `(symbol-function ,type))) - `(cl-letf ((,type ,@rest)) ,body))))))) + (setq type (list 'symbol-function type))) + (list 'cl-letf (list (cons type rest)) body))))))) (defmacro quiet! (&rest forms) "Run FORMS without generating any output.