Subject: Re: bug#77883: 31.0.50; C-c C-e in *scratch* generates a missing lexical binding cookie warning

From: Eli Zaretskii <[email-masked]>
Date: Sat, 03 May 2025 11:15:00 +0300

> From: Stefan Monnier <[email-masked]>
> Cc: [email-masked],  [email-masked],  [email-masked]
> Date: Fri, 18 Apr 2025 11:36:30 -0400
> 
> > If load-with-code-conversion is the only case where this is needed, we
> > could do that locally in load-with-code-conversion, right?  I mean,
> > there's no need to "punish" all the users of eval-buffer for that
> > single use.  Right?
> 
> I guess someone should look at the other uses of `eval-buffer` to figure
> out if that's the case.
> 
> Another approach might be to check if `lexical-binding` is set
> buffer-locally and if so to obey it without even checking the
> `lexical-binding` cookie.

I prefer the latter solution, as it sounds to me less ad-hoc.  Any
objections to installing the below on the master branch?

diff --git a/src/lread.c b/src/lread.c
index 5c8bbe7..6a1d259 100644
--- a/src/lread.c
+++ b/src/lread.c
@@ -2589,11 +2589,13 @@ DEFUN ("eval-buffer", Feval_buffer, Seval_buffer, 0, 5, "",
  evaluated code should work normally even if PRINTFLAG is nil, in
  which case the output is displayed in the echo area.
 
-This function ignores the current value of the `lexical-binding'
-variable.  Instead it will heed any
+This function ignores the global value of the `lexical-binding'
+variable.  Instead it will heed the buffer-local value of that
+variable and any
   -*- lexical-binding: t -*-
-settings in the buffer, and if there is no such setting, the buffer
-will be evaluated without lexical binding.
+settings in the buffer; if there is no such setting, and the
+buffer-local value of the variable is nil, the buffer will be
+evaluated without lexical binding.
 
 This function preserves the position of point.  */)
   (Lisp_Object buffer, Lisp_Object printflag, Lisp_Object filename,
@@ -2621,7 +2623,10 @@ DEFUN ("eval-buffer", Feval_buffer, Seval_buffer, 0, 5, "",
   specbind (Qstandard_output, tem);
   record_unwind_protect_excursion ();
   BUF_TEMP_SET_PT (XBUFFER (buf), BUF_BEGV (XBUFFER (buf)));
-  specbind (Qlexical_binding, get_lexical_binding (buf, buf));
+  /* Don't emit a warning about 'lexical-binding' if it already has a
+     local binding in the buffer.  */
+  if (NILP (Flocal_variable_p (Qlexical_binding, buf)))
+    specbind (Qlexical_binding, get_lexical_binding (buf, buf));
   BUF_TEMP_SET_PT (XBUFFER (buf), BUF_BEGV (XBUFFER (buf)));
   readevalloop (buf, 0, filename,
 		!NILP (printflag), unibyte, Qnil, Qnil, Qnil);