mirror of
git://git.sv.gnu.org/emacs.git
synced 2025-12-06 06:20:55 -08:00
Fix #'fun handling inside `labels' (Bug#31792)
* lisp/emacs-lisp/cl.el (labels): Apply the equivalent of the cl-labels change from 2015-01-16 "* lisp/emacs-lisp/cl-macs.el: Fix last change". * test/lisp/emacs-lisp/cl-tests.el (labels-function-quoting): New test. * lisp/emacs-lisp/cl-macs.el (cl-flet, cl-labels): Improve docstring, link to relevant manual page. * doc/misc/cl.texi (Function Bindings): Don't imply that function cells of symbols are modified by cl-flet. Don't claim that cl-flet or cl-labels affect references of the form (quote FUNC).
This commit is contained in:
parent
36737705b4
commit
e292c0973c
4 changed files with 62 additions and 20 deletions
|
|
@ -1964,13 +1964,16 @@ a `let' form, except that the list of symbols can be computed at run-time."
|
|||
;;;###autoload
|
||||
(defmacro cl-flet (bindings &rest body)
|
||||
"Make local function definitions.
|
||||
Like `cl-labels' but the definitions are not recursive.
|
||||
Each binding can take the form (FUNC EXP) where
|
||||
Each definition can take the form (FUNC EXP) where
|
||||
FUNC is the function name, and EXP is an expression that returns the
|
||||
function value to which it should be bound, or it can take the more common
|
||||
form \(FUNC ARGLIST BODY...) which is a shorthand
|
||||
for (FUNC (lambda ARGLIST BODY)).
|
||||
|
||||
FUNC is defined only within FORM, not BODY, so you can't write
|
||||
recursive function definitions. Use `cl-labels' for that. See
|
||||
info node `(cl) Function Bindings' for details.
|
||||
|
||||
\(fn ((FUNC ARGLIST BODY...) ...) FORM...)"
|
||||
(declare (indent 1) (debug ((&rest (cl-defun)) cl-declarations body)))
|
||||
(let ((binds ()) (newenv macroexpand-all-environment))
|
||||
|
|
@ -2012,9 +2015,13 @@ Like `cl-flet' but the definitions can refer to previous ones.
|
|||
|
||||
;;;###autoload
|
||||
(defmacro cl-labels (bindings &rest body)
|
||||
"Make temporary function bindings.
|
||||
The bindings can be recursive and the scoping is lexical, but capturing them
|
||||
in closures will only work if `lexical-binding' is in use.
|
||||
"Make local (recursive) function definitions.
|
||||
Each definition can take the form (FUNC ARGLIST BODY...) where
|
||||
FUNC is the function name, ARGLIST its arguments, and BODY the
|
||||
forms of the function body. FUNC is defined in any BODY, as well
|
||||
as FORM, so you can write recursive and mutually recursive
|
||||
function definitions. See info node `(cl) Function Bindings' for
|
||||
details.
|
||||
|
||||
\(fn ((FUNC ARGLIST BODY...) ...) FORM...)"
|
||||
(declare (indent 1) (debug cl-flet))
|
||||
|
|
|
|||
|
|
@ -466,9 +466,12 @@ rather than relying on `lexical-binding'."
|
|||
(push var sets)
|
||||
(push (cons (car binding)
|
||||
`(lambda (&rest cl-labels-args)
|
||||
(cl-list* 'funcall ',var
|
||||
cl-labels-args)))
|
||||
(if (eq (car cl-labels-args) cl--labels-magic)
|
||||
(list cl--labels-magic ',var)
|
||||
(cl-list* 'funcall ',var cl-labels-args))))
|
||||
newenv)))
|
||||
;; `lexical-let' adds `cl--function-convert' (which calls
|
||||
;; `cl--labels-convert') as a macroexpander for `function'.
|
||||
(macroexpand-all `(lexical-let ,vars (setq ,@sets) ,@body) newenv)))
|
||||
|
||||
;; Generalized variables are provided by gv.el, but some details are
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue