1
Fork 0
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:
Noam Postavsky 2018-06-12 18:41:46 -04:00
parent 36737705b4
commit e292c0973c
4 changed files with 62 additions and 20 deletions

View file

@ -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))

View file

@ -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