aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNoam Postavsky2018-06-12 18:41:46 -0400
committerNoam Postavsky2018-06-19 20:02:16 -0400
commite292c0973cf7a92819d312ea8a828b67e6adf1ab (patch)
tree5ae59aef028cd644b87d6d4d8909972515a2a3b4
parent36737705b451ad4c765baa5789e3ceb752ee07a3 (diff)
downloademacs-e292c0973cf7a92819d312ea8a828b67e6adf1ab.tar.gz
emacs-e292c0973cf7a92819d312ea8a828b67e6adf1ab.zip
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).
-rw-r--r--doc/misc/cl.texi23
-rw-r--r--lisp/emacs-lisp/cl-macs.el17
-rw-r--r--lisp/emacs-lisp/cl.el7
-rw-r--r--test/lisp/emacs-lisp/cl-tests.el35
4 files changed, 62 insertions, 20 deletions
diff --git a/doc/misc/cl.texi b/doc/misc/cl.texi
index bf85b00e937..553b935b1ef 100644
--- a/doc/misc/cl.texi
+++ b/doc/misc/cl.texi
@@ -1299,17 +1299,18 @@ These forms make @code{let}-like bindings to functions instead
1299of variables. 1299of variables.
1300 1300
1301@defmac cl-flet (bindings@dots{}) forms@dots{} 1301@defmac cl-flet (bindings@dots{}) forms@dots{}
1302This form establishes @code{let}-style bindings on the function 1302This form establishes @code{let}-style bindings for functions rather
1303cells of symbols rather than on the value cells. Each @var{binding} 1303than values. Each @var{binding} must be a list of the form
1304must be a list of the form @samp{(@var{name} @var{arglist} 1304@samp{(@var{name} @var{arglist} @var{body}@dots{})}. Within
1305@var{forms}@dots{})}, which defines a function exactly as if 1305@var{forms}, any reference to the function @var{name} uses the local
1306it were a @code{cl-defun} form. The function @var{name} is defined 1306definition instead of the global one.
1307accordingly but only within the body of the @code{cl-flet}, hiding any external 1307
1308definition if applicable. 1308A ``reference'' to a function name is either a call to that function,
1309or a use of its name quoted by @code{function} to be passed on to,
1310say, @code{mapcar}.
1309 1311
1310The bindings are lexical in scope. This means that all references to 1312The bindings are lexical in scope. This means that all references to
1311the named functions must appear physically within the body of the 1313the named functions must appear physically within @var{forms}.
1312@code{cl-flet} form.
1313 1314
1314Functions defined by @code{cl-flet} may use the full Common Lisp 1315Functions defined by @code{cl-flet} may use the full Common Lisp
1315argument notation supported by @code{cl-defun}; also, the function 1316argument notation supported by @code{cl-defun}; also, the function
@@ -1336,10 +1337,6 @@ functions must appear physically within the body of the
1336the functions themselves. Thus, @code{cl-labels} can define 1337the functions themselves. Thus, @code{cl-labels} can define
1337local recursive functions, or mutually-recursive sets of functions. 1338local recursive functions, or mutually-recursive sets of functions.
1338 1339
1339A ``reference'' to a function name is either a call to that
1340function, or a use of its name quoted by @code{quote} or
1341@code{function} to be passed on to, say, @code{mapcar}.
1342
1343Note that the @file{cl.el} version of this macro behaves slightly 1340Note that the @file{cl.el} version of this macro behaves slightly
1344differently. @xref{Obsolete Macros}. 1341differently. @xref{Obsolete Macros}.
1345@end defmac 1342@end defmac
diff --git a/lisp/emacs-lisp/cl-macs.el b/lisp/emacs-lisp/cl-macs.el
index 9c47ceae18e..0854e665b9b 100644
--- a/lisp/emacs-lisp/cl-macs.el
+++ b/lisp/emacs-lisp/cl-macs.el
@@ -1964,13 +1964,16 @@ a `let' form, except that the list of symbols can be computed at run-time."
1964;;;###autoload 1964;;;###autoload
1965(defmacro cl-flet (bindings &rest body) 1965(defmacro cl-flet (bindings &rest body)
1966 "Make local function definitions. 1966 "Make local function definitions.
1967Like `cl-labels' but the definitions are not recursive. 1967Each definition can take the form (FUNC EXP) where
1968Each binding can take the form (FUNC EXP) where
1969FUNC is the function name, and EXP is an expression that returns the 1968FUNC is the function name, and EXP is an expression that returns the
1970function value to which it should be bound, or it can take the more common 1969function value to which it should be bound, or it can take the more common
1971form \(FUNC ARGLIST BODY...) which is a shorthand 1970form \(FUNC ARGLIST BODY...) which is a shorthand
1972for (FUNC (lambda ARGLIST BODY)). 1971for (FUNC (lambda ARGLIST BODY)).
1973 1972
1973FUNC is defined only within FORM, not BODY, so you can't write
1974recursive function definitions. Use `cl-labels' for that. See
1975info node `(cl) Function Bindings' for details.
1976
1974\(fn ((FUNC ARGLIST BODY...) ...) FORM...)" 1977\(fn ((FUNC ARGLIST BODY...) ...) FORM...)"
1975 (declare (indent 1) (debug ((&rest (cl-defun)) cl-declarations body))) 1978 (declare (indent 1) (debug ((&rest (cl-defun)) cl-declarations body)))
1976 (let ((binds ()) (newenv macroexpand-all-environment)) 1979 (let ((binds ()) (newenv macroexpand-all-environment))
@@ -2012,9 +2015,13 @@ Like `cl-flet' but the definitions can refer to previous ones.
2012 2015
2013;;;###autoload 2016;;;###autoload
2014(defmacro cl-labels (bindings &rest body) 2017(defmacro cl-labels (bindings &rest body)
2015 "Make temporary function bindings. 2018 "Make local (recursive) function definitions.
2016The bindings can be recursive and the scoping is lexical, but capturing them 2019Each definition can take the form (FUNC ARGLIST BODY...) where
2017in closures will only work if `lexical-binding' is in use. 2020FUNC is the function name, ARGLIST its arguments, and BODY the
2021forms of the function body. FUNC is defined in any BODY, as well
2022as FORM, so you can write recursive and mutually recursive
2023function definitions. See info node `(cl) Function Bindings' for
2024details.
2018 2025
2019\(fn ((FUNC ARGLIST BODY...) ...) FORM...)" 2026\(fn ((FUNC ARGLIST BODY...) ...) FORM...)"
2020 (declare (indent 1) (debug cl-flet)) 2027 (declare (indent 1) (debug cl-flet))
diff --git a/lisp/emacs-lisp/cl.el b/lisp/emacs-lisp/cl.el
index d53c8e0bbcf..f6643158d2d 100644
--- a/lisp/emacs-lisp/cl.el
+++ b/lisp/emacs-lisp/cl.el
@@ -466,9 +466,12 @@ rather than relying on `lexical-binding'."
466 (push var sets) 466 (push var sets)
467 (push (cons (car binding) 467 (push (cons (car binding)
468 `(lambda (&rest cl-labels-args) 468 `(lambda (&rest cl-labels-args)
469 (cl-list* 'funcall ',var 469 (if (eq (car cl-labels-args) cl--labels-magic)
470 cl-labels-args))) 470 (list cl--labels-magic ',var)
471 (cl-list* 'funcall ',var cl-labels-args))))
471 newenv))) 472 newenv)))
473 ;; `lexical-let' adds `cl--function-convert' (which calls
474 ;; `cl--labels-convert') as a macroexpander for `function'.
472 (macroexpand-all `(lexical-let ,vars (setq ,@sets) ,@body) newenv))) 475 (macroexpand-all `(lexical-let ,vars (setq ,@sets) ,@body) newenv)))
473 476
474;; Generalized variables are provided by gv.el, but some details are 477;; Generalized variables are provided by gv.el, but some details are
diff --git a/test/lisp/emacs-lisp/cl-tests.el b/test/lisp/emacs-lisp/cl-tests.el
new file mode 100644
index 00000000000..b673822cd9a
--- /dev/null
+++ b/test/lisp/emacs-lisp/cl-tests.el
@@ -0,0 +1,35 @@
1;;; cl-tests.el --- tests for emacs-lisp/cl.el -*- lexical-binding:t -*-
2
3;; Copyright (C) 2018 Free Software Foundation, Inc.
4
5;; This file is part of GNU Emacs.
6
7;; This program is free software: you can redistribute it and/or
8;; modify it under the terms of the GNU General Public License as
9;; published by the Free Software Foundation, either version 3 of the
10;; License, or (at your option) any later version.
11;;
12;; This program is distributed in the hope that it will be useful, but
13;; WITHOUT ANY WARRANTY; without even the implied warranty of
14;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15;; General Public License for more details.
16;;
17;; You should have received a copy of the GNU General Public License
18;; along with this program. If not, see `https://www.gnu.org/licenses/'.
19
20;;; Commentary:
21
22;;; Code:
23
24(require 'cl)
25(require 'ert)
26
27
28
29(ert-deftest labels-function-quoting ()
30 "Test that #'foo does the right thing in `labels'." ; Bug#31792.
31 (should (eq (funcall (labels ((foo () t))
32 #'foo))
33 t)))
34
35;;; cl-tests.el ends here