Subject: Re: bug#67991: 30.0.50; boundp always returns nil in format-mode-line with let* after 0fde935

From: Gerd Möllmann <[email-masked]>
Date: Sun, 24 Dec 2023 08:13:39 +0100

Eli Zaretskii <[email-masked]> writes:

> This one will return t:
>
>   (format-mode-line
>    '(:eval (progn
> 	     (defvar some-var)
> 	     (let* ((some-var "some-value")
> 		    (_ (message "Bound: %S" (boundp 'some-var))))
> 	       (message "Var: %S, Bound: %S" some-var (boundp 'some-var))))))
>

Indeed. Looking at Fdefvar, one can see that a "(defvar foo)" does this
when lexical-binding is t

    /* A simple (defvar foo) with lexical scoping does "nothing" except
       declare that var to be dynamically scoped *locally* (i.e. within
       the current file or let-block).  */

while it does nothing at all if lexical-binding is nil. Maybe defvar's
doc string could give some hint to that. This sentence at least is not
true for "(defvar SYMBOL)":

        The ‘defvar’ form also declares the variable as "special",
so that it is always dynamically bound even if ‘lexical-binding’ is t.