]> git.eshelyaron.com Git - emacs.git/commitdiff
(Fmake_local_variable): Fix bug#65209
authorStefan Monnier <monnier@iro.umontreal.ca>
Fri, 18 Aug 2023 23:22:17 +0000 (19:22 -0400)
committerStefan Monnier <monnier@iro.umontreal.ca>
Fri, 18 Aug 2023 23:22:17 +0000 (19:22 -0400)
* src/data.c (Fmake_local_variable): Don't delegate to `Fset` since
they have to obey `let_shadows_buffer_binding_p` whereas we don't.

* test/src/data-tests.el (data-tests--bug65209): New var.
(data-tests-make-local-bug65209): New test.

src/data.c
test/src/data-tests.el

index 619ab8fde64fd95d920c207d36bb3fafb360a2f0..377bcfce35dbd3c292b45105826338557593a3f2 100644 (file)
@@ -2213,17 +2213,18 @@ Instead, use `add-hook' and specify t for the LOCAL argument.  */)
   if (sym->u.s.trapped_write == SYMBOL_NOWRITE)
     xsignal1 (Qsetting_constant, variable);
 
-  if (blv ? blv->local_if_set
-      : (forwarded && BUFFER_OBJFWDP (valcontents.fwd)))
-    {
-      tem = Fboundp (variable);
-      /* Make sure the symbol has a local value in this particular buffer,
-        by setting it to the same value it already has.  */
-      Fset (variable, (EQ (tem, Qt) ? Fsymbol_value (variable) : Qunbound));
-      return variable;
-    }
   if (!blv)
     {
+      if (forwarded && BUFFER_OBJFWDP (valcontents.fwd))
+        {
+          int offset = XBUFFER_OBJFWD (valcontents.fwd)->offset;
+          int idx = PER_BUFFER_IDX (offset);
+          eassert (idx);
+          if (idx > 0)
+            /* If idx < 0, it's always buffer local, like `mode-name`.  */
+            SET_PER_BUFFER_VALUE_P (current_buffer, idx, true);
+          return variable;
+        }
       blv = make_blv (sym, forwarded, valcontents);
       sym->u.s.redirect = SYMBOL_LOCALIZED;
       SET_SYMBOL_BLV (sym, blv);
index 680fdd57d71e880a7b21fa205c5e6f81416e3c66..8167cccdd18ec92714ea3d46881a550c752890e3 100644 (file)
@@ -768,6 +768,31 @@ comparing the subr with a much slower Lisp implementation."
                          (default-value 'last-coding-system-used))
                    '(no-conversion bug34318)))))
 
+(defvar-local data-tests--bug65209 :default-value)
+
+(ert-deftest data-tests-make-local-bug65209 ()
+  (dolist (sym '(data-tests--bug65209   ;A normal always-local Lisp var.
+                 cursor-in-non-selected-windows)) ;Same but DEFVAR_PER_BUFFER.
+    ;; Note: For vars like `mode-name' that are *really* always buffer-local,
+    ;; this test isn't right because the `cl-progv' only binds the
+    ;; buffer-local value!
+    (let ((default (default-value sym))
+          vli vlo vgi vgo)
+      (with-temp-buffer
+        (cl-progv (list sym) '(:let-bound-value)
+          ;; While `setq' would not make the var buffer-local
+          ;; (because we'd be setq-ing the let-binding instead),
+          ;; `setq-local' definitely should.
+          (set (make-local-variable sym) :buffer-local-value)
+          (setq vgi (with-temp-buffer (symbol-value sym)))
+          (setq vli (symbol-value sym)))
+      (setq vgo (with-temp-buffer (symbol-value sym)))
+      (setq vlo (symbol-value sym)))
+      (should (equal (list vgo vgi vlo vli)
+                     (cons default
+                           '(:let-bound-value
+                             :buffer-local-value :buffer-local-value)))))))
+
 (ert-deftest data-tests-make_symbol_constant ()
   "Can't set variable marked with 'make_symbol_constant'."
   (should-error (setq most-positive-fixnum 1) :type 'setting-constant))