]> git.eshelyaron.com Git - emacs.git/commitdiff
Explicitly disallow named-let in code using dynamic binding
authorMattias Engdegård <mattiase@acm.org>
Mon, 21 Aug 2023 11:50:03 +0000 (13:50 +0200)
committerMattias Engdegård <mattiase@acm.org>
Mon, 21 Aug 2023 12:17:03 +0000 (14:17 +0200)
There is no point in permitting named-let to be used in dynbound code;
our code transforms are simply not valid in that context, and it's not
worth the trouble to make it work (to the extent that it is at all
possible). (Bug#59576)

* lisp/emacs-lisp/subr-x.el (named-let):
Error if used with dynamic binding.
* doc/lispref/variables.texi (Local Variables): Amend manual.

doc/lispref/variables.texi
lisp/emacs-lisp/subr-x.el

index 55761ff75e29d9d2da7533384fa8f3acaa3cf188..93930d175878e253666822f7e03a939bb56c1b52 100644 (file)
@@ -351,8 +351,8 @@ A function call is in the tail position if it's the very last thing
 done so that the value returned by the call is the value of @var{body}
 itself, as is the case in the recursive call to @code{sum} above.
 
-@strong{Warning:} @code{named-let} works as expected only when
-lexical-binding is enabled.  @xref{Lexical Binding}.
+@code{named-let} can only be used when lexical-binding is enabled.
+@xref{Lexical Binding}.
 @end defspec
 
   Here is a complete list of the other facilities that create local
index 78dc58e0bcdf83080c084f03d486498c6cc2a392..572822351b19d0748f0246af39a5939b1557a24b 100644 (file)
@@ -312,9 +312,13 @@ it makes no sense to convert it to a string using
 Like `let', bind variables in BINDINGS and then evaluate BODY,
 but with the twist that BODY can evaluate itself recursively by
 calling NAME, where the arguments passed to NAME are used
-as the new values of the bound variables in the recursive invocation."
+as the new values of the bound variables in the recursive invocation.
+
+This construct can only be used with lexical binding."
   (declare (indent 2) (debug (symbolp (&rest (symbolp form)) body)))
   (require 'cl-lib)
+  (unless lexical-binding
+    (error "`named-let' requires lexical binding"))
   (let ((fargs (mapcar (lambda (b) (if (consp b) (car b) b)) bindings))
         (aargs (mapcar (lambda (b) (if (consp b) (cadr b))) bindings)))
     ;; According to the Scheme semantics of named let, `name' is not in scope