* 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)
(cherry picked from commit
7f2e4508cebe76a885b72ca4789ae839d5bd45e1)
(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)))
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)
{
defsubr (&Sdefvar_1);
defsubr (&Sdefvaralias);
DEFSYM (Qdefvaralias, "defvaralias");
+ defsubr (&Sinternal_delete_indirect_variable);
defsubr (&Sdefconst);
defsubr (&Sdefconst_1);
defsubr (&Sinternal__define_uninitialized_variable);
--- /dev/null
+;;; 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
(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
(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 ()