about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNicholas Nethercote <n.nethercote@gmail.com>2025-06-11 12:54:19 +1000
committerNicholas Nethercote <n.nethercote@gmail.com>2025-06-11 13:52:50 +1000
commit278f4b2d9c2cdc741d38c78f14a60e78e2f668f4 (patch)
tree5b716915471226019b7f0690517970f07a0c9b03
parent79b3c08bdb729e77c38957500eade13e5dd16923 (diff)
downloadrust-278f4b2d9c2cdc741d38c78f14a60e78e2f668f4.tar.gz
rust-278f4b2d9c2cdc741d38c78f14a60e78e2f668f4.zip
Don't clone `new_item` in `after_krate`.
We can avoid it by using the `entry` API, which lets us do the
`assert_eq` comparison before `new_item` is consumed.
-rw-r--r--src/librustdoc/json/mod.rs23
1 files changed, 16 insertions, 7 deletions
diff --git a/src/librustdoc/json/mod.rs b/src/librustdoc/json/mod.rs
index 965212f019f..29c63a391e2 100644
--- a/src/librustdoc/json/mod.rs
+++ b/src/librustdoc/json/mod.rs
@@ -217,6 +217,8 @@ impl<'tcx> FormatRenderer<'tcx> for JsonRenderer<'tcx> {
     /// the hashmap because certain items (traits and types) need to have their mappings for trait
     /// implementations filled out before they're inserted.
     fn item(&mut self, item: &clean::Item) -> Result<(), Error> {
+        use std::collections::hash_map::Entry;
+
         let item_type = item.type_();
         let item_name = item.name;
         trace!("rendering {item_type} {item_name:?}");
@@ -271,18 +273,25 @@ impl<'tcx> FormatRenderer<'tcx> for JsonRenderer<'tcx> {
                 | types::ItemEnum::Macro(_)
                 | types::ItemEnum::ProcMacro(_) => false,
             };
-            let removed = self.index.insert(new_item.id, new_item.clone());
 
             // FIXME(adotinthevoid): Currently, the index is duplicated. This is a sanity check
             // to make sure the items are unique. The main place this happens is when an item, is
             // reexported in more than one place. See `rustdoc-json/reexport/in_root_and_mod`
-            if let Some(old_item) = removed {
-                // In case of generic implementations (like `impl<T> Trait for T {}`), all the
-                // inner items will be duplicated so we can ignore if they are slightly different.
-                if !can_be_ignored {
-                    assert_eq!(old_item, new_item);
+            match self.index.entry(new_item.id) {
+                Entry::Vacant(entry) => {
+                    entry.insert(new_item);
+                }
+                Entry::Occupied(mut entry) => {
+                    // In case of generic implementations (like `impl<T> Trait for T {}`), all the
+                    // inner items will be duplicated so we can ignore if they are slightly
+                    // different.
+                    let old_item = entry.get_mut();
+                    if !can_be_ignored {
+                        assert_eq!(*old_item, new_item);
+                    }
+                    trace!("replaced {old_item:?}\nwith {new_item:?}");
+                    *old_item = new_item;
                 }
-                trace!("replaced {old_item:?}\nwith {new_item:?}");
             }
         }