Subject: bug#75188: persist.el should recursively copy hash tables

From: Joseph Turner <[email-masked]>
Date: Mon, 27 Jan 2025 18:08:57 -0800

Eli Zaretskii <[email-masked]> writes:

>> From: Joseph Turner <[email-masked]>
>> Cc:  Daniel Mendler <[email-masked]>,
>> 	Ihor Radchenko <[email-masked]>,
>> 	Stefan Monnier <[email-masked]>,
>> 	Adam Porter <[email-masked]>, Eli Zaretskii <[email-masked]>,
>> 	[email-masked]
>> Date: Tue, 31 Dec 2024 14:12:00 -0800
>>
>> > Hello!
>> >
>> > This patch demonstrates a bug in persist.el
>>
>> [...]
>>
>> This issue also relates to the bug#63513, in which the suggestion was
>> made to replace persist-copy-tree with (compat-call copy-tree) now that
>> Compat 30 is available:
>>
>> https://yhetil.org/emacs-bugs/[email-masked]/
>
> Thanks, would you like to submit a patch along those lines?

Please see patch:

>From 8c3d276a977010d4b903d9de7344b6fad8de8eab Mon Sep 17 00:00:00 2001
From: Joseph Turner <[email-masked]>
Date: Mon, 27 Jan 2025 18:05:10 -0800
Subject: [PATCH] Depend on compat.el for new copy-tree behavior

---
 persist.el | 34 ++++------------------------------
 1 file changed, 4 insertions(+), 30 deletions(-)

diff --git a/persist.el b/persist.el
index 49b3e9b51f..3260df0964 100644
--- a/persist.el
+++ b/persist.el
@@ -5,7 +5,7 @@
 ;; Author: Phillip Lord <[email-masked]>
 ;; Maintainer: Joseph Turner <[email-masked]>
 ;; Package-Type: multi
-;; Package-Requires: ((emacs "26.1"))
+;; Package-Requires: ((emacs "26.1") (compat "30.0.2.0"))
 ;; Version: 0.6.1
 
 ;; The contents of this file are subject to the GPL License, Version 3.0.
@@ -43,6 +43,8 @@
 
 ;;; Code:
 
+(require 'compat)
+
 (defvar persist--directory-location
   (locate-user-emacs-file "persist")
   "The location of persist directory.")
@@ -211,39 +213,11 @@ (defun persist-equal (a b)
              t))
     (equal a b)))
 
-(defun persist-copy-tree (tree &optional vectors-and-records)
-  "Make a copy of TREE.
-If TREE is a cons cell, this recursively copies both its car and its cdr.
-Contrast to `copy-sequence', which copies only along the cdrs.
-With the second argument VECTORS-AND-RECORDS non-nil, this
-traverses and copies vectors and records as well as conses."
-  (declare (side-effect-free error-free))
-  (if (consp tree)
-      (let (result)
-	(while (consp tree)
-	  (let ((newcar (car tree)))
-	    (if (or (consp (car tree))
-                    (and vectors-and-records
-                         (or (vectorp (car tree)) (recordp (car tree)))))
-		(setq newcar (persist-copy-tree (car tree) vectors-and-records)))
-	    (push newcar result))
-	  (setq tree (cdr tree)))
-	(nconc (nreverse result)
-               (if (and vectors-and-records (or (vectorp tree) (recordp tree)))
-                   (persist-copy-tree tree vectors-and-records)
-                 tree)))
-    (if (and vectors-and-records (or (vectorp tree) (recordp tree)))
-	(let ((i (length (setq tree (copy-sequence tree)))))
-	  (while (>= (setq i (1- i)) 0)
-	    (aset tree i (persist-copy-tree (aref tree i) vectors-and-records)))
-	  tree)
-      tree)))
-
 (defun persist-copy (obj)
   "Return copy of OBJ."
   (if (hash-table-p obj)
       (copy-hash-table obj)
-    (persist-copy-tree obj t)))
+    (compat-call copy-tree obj t)))
 
 (provide 'persist)
 ;;; persist.el ends here
-- 
2.46.0