Correctly unload variable aliases.
* src/eval.c (Finternal_delete_indirect_variable): Add function. * lisp/loadhist.el (loadhist-unload-element): Use it for variable aliases. * test/src/eval-tests.el (eval-tests--internal-delete-indirect-variable): Test function `internal-delete-indirect-variable'. * test/lisp/loadhist-tests.el (loadhist-test-unload-feature-alias): * test/lisp/loadhist-resources/loadhist--alias.el: Test unloading of features that define variable aliases. (Bug#76748)
This commit is contained in:
parent
b8104dadbf
commit
7f2e4508ce
5 changed files with 74 additions and 3 deletions
|
@ -211,9 +211,13 @@ unloading."
|
|||
(kill-local-variable x)))
|
||||
(if (and (boundp x) (timerp (symbol-value x)))
|
||||
(cancel-timer (symbol-value x)))
|
||||
;; Get rid of the default binding if we can.
|
||||
(unless (local-variable-if-set-p x)
|
||||
(makunbound x)))
|
||||
(cond
|
||||
;; "Unbind" indirect variable.
|
||||
((not (eq (indirect-variable x) x))
|
||||
(internal-delete-indirect-variable x))
|
||||
;; Get rid of the default binding if we can.
|
||||
((not (local-variable-if-set-p x))
|
||||
(makunbound x))))
|
||||
|
||||
(cl-defmethod loadhist-unload-element ((x (head define-type)))
|
||||
(let* ((name (cdr x)))
|
||||
|
|
19
src/eval.c
19
src/eval.c
|
@ -720,6 +720,24 @@ signal a `cyclic-variable-indirection' error. */)
|
|||
return base_variable;
|
||||
}
|
||||
|
||||
DEFUN ("internal-delete-indirect-variable", Finternal_delete_indirect_variable, Sinternal_delete_indirect_variable,
|
||||
1, 1, 0,
|
||||
doc: /* Internal use only.
|
||||
Undeclare SYMBOL as variable alias, then unbind it.
|
||||
Return SYMBOL. */)
|
||||
(register Lisp_Object symbol)
|
||||
{
|
||||
CHECK_SYMBOL (symbol);
|
||||
if (XSYMBOL (symbol)->u.s.redirect != SYMBOL_VARALIAS)
|
||||
xsignal2 (Qerror,
|
||||
build_string ("Cannot undeclare a variable that is not an alias"),
|
||||
symbol);
|
||||
XSYMBOL (symbol)->u.s.redirect = SYMBOL_PLAINVAL;
|
||||
Fput (symbol, Qvariable_documentation, Qnil);
|
||||
Fset (symbol, Qunbound);
|
||||
return symbol;
|
||||
}
|
||||
|
||||
static union specbinding *
|
||||
default_toplevel_binding (Lisp_Object symbol)
|
||||
{
|
||||
|
@ -4488,6 +4506,7 @@ alist of active lexical bindings. */);
|
|||
defsubr (&Sdefvar_1);
|
||||
defsubr (&Sdefvaralias);
|
||||
DEFSYM (Qdefvaralias, "defvaralias");
|
||||
defsubr (&Sinternal_delete_indirect_variable);
|
||||
defsubr (&Sdefconst);
|
||||
defsubr (&Sdefconst_1);
|
||||
defsubr (&Sinternal__define_uninitialized_variable);
|
||||
|
|
28
test/lisp/loadhist-resources/loadhist--alias.el
Normal file
28
test/lisp/loadhist-resources/loadhist--alias.el
Normal file
|
@ -0,0 +1,28 @@
|
|||
;;; loadhist--alias.el --- Dummy package for loadhist-tests -*- lexical-binding: t; -*-
|
||||
|
||||
;; Copyright (C) 2025 Free Software Foundation, Inc.
|
||||
|
||||
;; Author: Jens Schmidt <jschmidt4gnu@vodafonemail.de>
|
||||
|
||||
;; This file is part of GNU Emacs.
|
||||
|
||||
;; GNU Emacs is free software: you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
|
||||
;; GNU Emacs is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
;;; Code:
|
||||
|
||||
(defvaralias 'loadhist--alias-last-input-event 'last-input-event
|
||||
"Alias on built-in variable.")
|
||||
|
||||
(provide 'loadhist--alias)
|
||||
;;; loadhist--alias.el ends here
|
|
@ -101,4 +101,12 @@
|
|||
(should (null (get 'loadhist--bar-dec 'function-history)))
|
||||
(should (null (get 'loadhist--foo-inc 'function-history))))
|
||||
|
||||
(ert-deftest loadhist-test-unload-feature-alias ()
|
||||
"Check that bug#76748 has been fixed."
|
||||
(add-to-list 'load-path (expand-file-name
|
||||
"loadhist-resources/"
|
||||
loadhist--tests-dir))
|
||||
(load "loadhist--alias" nil t)
|
||||
(unload-feature 'loadhist--alias))
|
||||
|
||||
;;; loadhist-tests.el ends here
|
||||
|
|
|
@ -282,6 +282,18 @@ expressions works for identifiers starting with period."
|
|||
(should-error (defvaralias 'eval-tests--my-c 'eval-tests--my-d)
|
||||
:type 'cyclic-variable-indirection))
|
||||
|
||||
(ert-deftest eval-tests--internal-delete-indirect-variable ()
|
||||
(defvar eval-tests--i-d-i-v-var 'foo)
|
||||
(defvaralias 'eval-tests--i-d-i-v-var1 'eval-tests--i-d-i-v-var "Doc string.")
|
||||
(internal-delete-indirect-variable 'eval-tests--i-d-i-v-var1)
|
||||
|
||||
(should (eq (indirect-variable 'eval-tests--i-d-i-v-var1)
|
||||
'eval-tests--i-d-i-v-var1))
|
||||
(should-not (boundp 'eval-tests--i-d-i-v-var1))
|
||||
(should-not (get 'eval-tests--i-d-i-v-var1 'variable-documentation))
|
||||
|
||||
(should-error (internal-delete-indirect-variable 'eval-tests--i-d-i-v-var)))
|
||||
|
||||
(defvar eval-tests/global-var 'global-value)
|
||||
(defvar-local eval-tests/buffer-local-var 'default-value)
|
||||
(ert-deftest eval-tests/default-value ()
|
||||
|
|
Loading…
Add table
Reference in a new issue