mirror of
git://git.sv.gnu.org/emacs.git
synced 2026-02-16 17:24:23 +00:00
src/eval.c: Fix bug#62419
Yup, almost 40 years after ELisp first combined them, buffer-local and let bindings still don't work quite right :-( The "automatically buffer-local if set" semantics should follow the principle that it becomes buffer-local iff the var's current binding refers to the top-level/global/non-let binding. * src/eval.c (let_shadows_buffer_binding_p): Disregard non-global let-bindings. * test/src/eval-tests.el (eval-test--bug62419): New test.
This commit is contained in:
parent
00144fa287
commit
5223762e02
2 changed files with 21 additions and 1 deletions
|
|
@ -3400,7 +3400,7 @@ DEFUN ("fetch-bytecode", Ffetch_bytecode, Sfetch_bytecode,
|
|||
return object;
|
||||
}
|
||||
|
||||
/* Return true if SYMBOL currently has a let-binding
|
||||
/* Return true if SYMBOL's default currently has a let-binding
|
||||
which was made in the buffer that is now current. */
|
||||
|
||||
bool
|
||||
|
|
@ -3415,6 +3415,7 @@ let_shadows_buffer_binding_p (struct Lisp_Symbol *symbol)
|
|||
struct Lisp_Symbol *let_bound_symbol = XSYMBOL (specpdl_symbol (p));
|
||||
eassert (let_bound_symbol->u.s.redirect != SYMBOL_VARALIAS);
|
||||
if (symbol == let_bound_symbol
|
||||
&& p->kind != SPECPDL_LET_LOCAL /* bug#62419 */
|
||||
&& EQ (specpdl_where (p), buf))
|
||||
return 1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -247,4 +247,23 @@ expressions works for identifiers starting with period."
|
|||
(should (equal (string-trim (buffer-string))
|
||||
expected-messages))))))))
|
||||
|
||||
(defvar-local eval-test--local-var 'global)
|
||||
|
||||
(ert-deftest eval-test--bug62419 ()
|
||||
(with-temp-buffer
|
||||
(setq eval-test--local-var 'first-local)
|
||||
(let ((eval-test--local-var t))
|
||||
(kill-local-variable 'eval-test--local-var)
|
||||
(setq eval-test--local-var 'second-local)
|
||||
(should (eq eval-test--local-var 'second-local)))
|
||||
;; FIXME: It's not completely clear if exiting the above `let'
|
||||
;; should restore the buffer-local binding to `first-local'
|
||||
;; (i.e. reset the value of the second buffer-local binding to the
|
||||
;; first's initial value) or should do nothing (on the principle that
|
||||
;; the first buffer-local binding doesn't exists any more so there's
|
||||
;; nothing to restore). I think both semantics make sense.
|
||||
;;(should (eq eval-test--local-var 'first-local))
|
||||
)
|
||||
(should (eq eval-test--local-var 'global)))
|
||||
|
||||
;;; eval-tests.el ends here
|
||||
|
|
|
|||
Loading…
Reference in a new issue