]> code.delx.au - gnu-emacs/commitdiff
Fix map-put and map-delete for alists (Bug#23105)
authorNicolas Petton <nicolas@petton.fr>
Fri, 25 Mar 2016 14:09:04 +0000 (15:09 +0100)
committerNicolas Petton <nicolas@petton.fr>
Fri, 25 Mar 2016 14:11:23 +0000 (15:11 +0100)
* lisp/emacs-lisp/map.el (map-put): Do not bind the evaluated place
expression to a new symbol.
* test/lisp/emacs-lisp/map-tests.el: Add a regression test.

lisp/emacs-lisp/map.el
test/automated/map-tests.el

index ec8d3d79d9f37abec05aea1da932f3eb560e34b1..ba15a65f5e109dd651d027259dfb634edab29bd6 100644 (file)
@@ -123,33 +123,26 @@ MAP can be a list, hash-table or array."
              default)))
 
 (defmacro map-put (map key value)
-  "Associate KEY with VALUE in MAP and return MAP.
+  "Associate KEY with VALUE in MAP and return VALUE.
 If KEY is already present in MAP, replace the associated value
 with VALUE.
 
 MAP can be a list, hash-table or array."
-  (macroexp-let2 nil map map
-    `(progn
-       (setf (map-elt ,map ,key) ,value)
-       ,map)))
+  `(setf (map-elt ,map ,key) ,value))
 
-(defmacro map-delete (map key)
+(defun map-delete (map key)
   "Delete KEY from MAP and return MAP.
 No error is signaled if KEY is not a key of MAP.  If MAP is an
 array, store nil at the index KEY.
 
 MAP can be a list, hash-table or array."
-  (declare (debug t))
-  (gv-letplace (mgetter msetter) `(gv-delay-error ,map)
-    (macroexp-let2 nil key key
-      `(if (not (listp ,mgetter))
-           (map--delete ,mgetter ,key)
-         ;; The alist case is special, since it can't be handled by the
-         ;; map--delete function.
-         (setf (alist-get ,key (gv-synthetic-place ,mgetter ,msetter)
-                          nil t)
-               nil)
-         ,mgetter))))
+  (map--dispatch map
+    :list (setf (alist-get key map nil t) nil)
+    :hash-table (remhash key map)
+    :array (and (>= key 0)
+                (<= key (seq-length map))
+                (aset map key nil)))
+  map)
 
 (defun map-nested-elt (map keys &optional default)
   "Traverse MAP using KEYS and return the looked up value or DEFAULT if nil.
@@ -337,15 +330,6 @@ MAP can be a list, hash-table or array."
                       (cdr pair)))
            map))
 
-(defun map--delete (map key)
-  (map--dispatch map
-    :list (error "No place to remove the mapping for %S" key)
-    :hash-table (remhash key map)
-    :array (and (>= key 0)
-                (<= key (seq-length map))
-                (aset map key nil)))
-  map)
-
 (defun map--apply-hash-table (function map)
   "Private function used to apply FUNCTION over MAP, MAP being a hash-table."
   (let (result)
index d145c197a4e6c5958dea8bf3199e6d603786a402..20cb0f6b39967a7d16aef7832eaf8b02530ed840 100644 (file)
@@ -87,9 +87,16 @@ Evaluate BODY for each created map.
   (let ((vec [3 4 5]))
    (should-error (setf (map-elt vec 3) 6))))
 
+(ert-deftest test-map-put-alist-new-key ()
+  "Regression test for Bug#23105."
+  (let ((alist '((0 . a))))
+    (map-put alist 2 'b)
+    (should (eq (map-elt alist 2)
+                'b))))
+
 (ert-deftest test-map-put-return-value ()
   (let ((ht (make-hash-table)))
-    (should (eq (map-put ht 'a 'hello) ht))))
+    (should (eq (map-put ht 'a 'hello) 'hello))))
 
 (ert-deftest test-map-delete ()
   (with-maps-do map