From 3757ce6d1f6b3f54fabaf87d4b2c9ac1db76e808 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 19 Jan 2026 13:35:05 +0100 Subject: [PATCH 1/3] Remove a string comparison and reduce number of clones in `Hierarchy::add_path` --- src/librustdoc/html/render/write_shared.rs | 52 ++++++++++++---------- 1 file changed, 28 insertions(+), 24 deletions(-) diff --git a/src/librustdoc/html/render/write_shared.rs b/src/librustdoc/html/render/write_shared.rs index af97ae93a2b9..42fc35ded7c6 100644 --- a/src/librustdoc/html/render/write_shared.rs +++ b/src/librustdoc/html/render/write_shared.rs @@ -504,33 +504,37 @@ impl Hierarchy { fn add_path(self: &Rc, path: &Path) { let mut h = Rc::clone(self); - let mut elems = path + let mut components = path .components() - .filter_map(|s| match s { - Component::Normal(s) => Some(s.to_owned()), - Component::ParentDir => Some(OsString::from("..")), - _ => None, - }) + .filter(|component| matches!(component, Component::Normal(_) | Component::ParentDir)) .peekable(); - loop { - let cur_elem = elems.next().expect("empty file path"); - if cur_elem == ".." { - if let Some(parent) = h.parent.upgrade() { - h = parent; + + while let Some(component) = components.next() { + match component { + Component::Normal(s) => { + if components.peek().is_none() { + h.elems.borrow_mut().insert(s.to_owned()); + break; + } + let next_h = { + let mut children = h.children.borrow_mut(); + + if let Some(existing) = children.get(s) { + Rc::clone(existing) + } else { + let new_node = Rc::new(Self::with_parent(s.to_owned(), &h)); + children.insert(s.to_owned(), Rc::clone(&new_node)); + new_node + } + }; + h = next_h; } - continue; - } - if elems.peek().is_none() { - h.elems.borrow_mut().insert(cur_elem); - break; - } else { - let entry = Rc::clone( - h.children - .borrow_mut() - .entry(cur_elem.clone()) - .or_insert_with(|| Rc::new(Self::with_parent(cur_elem, &h))), - ); - h = entry; + Component::ParentDir => { + if let Some(parent) = h.parent.upgrade() { + h = parent; + } + } + _ => {} } } } From dd42a9f118e3d35928a5efccfca1ad692f13e93b Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 19 Jan 2026 15:00:04 +0100 Subject: [PATCH 2/3] Replace regex with find calls --- src/librustdoc/html/render/write_shared.rs | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/librustdoc/html/render/write_shared.rs b/src/librustdoc/html/render/write_shared.rs index 42fc35ded7c6..aa7972449e55 100644 --- a/src/librustdoc/html/render/write_shared.rs +++ b/src/librustdoc/html/render/write_shared.rs @@ -26,7 +26,6 @@ use std::str::FromStr; use std::{fmt, fs}; use indexmap::IndexMap; -use regex::Regex; use rustc_ast::join_path_syms; use rustc_data_structures::flock; use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet}; @@ -376,12 +375,15 @@ fn hack_get_external_crate_names( }; // this is only run once so it's fine not to cache it // !dot_matches_new_line: all crates on same line. greedy: match last bracket - let regex = Regex::new(r"\[.*\]").unwrap(); - let Some(content) = regex.find(&content) else { - return Err(Error::new("could not find crates list in crates.js", path)); - }; - let content: Vec = try_err!(serde_json::from_str(content.as_str()), &path); - Ok(content) + if let Some(start) = content.find('[') + && let Some(end) = content[start..].find(']') + { + let content: Vec = + try_err!(serde_json::from_str(&content[start..=start + end]), &path); + Ok(content) + } else { + Err(Error::new("could not find crates list in crates.js", path)) + } } #[derive(Serialize, Deserialize, Clone, Default, Debug)] From bd453118ee2ac0195e8b5eff653cde11b9ca66e4 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 26 Jan 2026 14:59:44 +0100 Subject: [PATCH 3/3] Improve code --- src/librustdoc/html/render/write_shared.rs | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/librustdoc/html/render/write_shared.rs b/src/librustdoc/html/render/write_shared.rs index aa7972449e55..1b5dbeed8de8 100644 --- a/src/librustdoc/html/render/write_shared.rs +++ b/src/librustdoc/html/render/write_shared.rs @@ -511,6 +511,7 @@ impl Hierarchy { .filter(|component| matches!(component, Component::Normal(_) | Component::ParentDir)) .peekable(); + assert!(components.peek().is_some(), "empty file path"); while let Some(component) = components.next() { match component { Component::Normal(s) => { @@ -518,7 +519,7 @@ impl Hierarchy { h.elems.borrow_mut().insert(s.to_owned()); break; } - let next_h = { + h = { let mut children = h.children.borrow_mut(); if let Some(existing) = children.get(s) { @@ -529,12 +530,9 @@ impl Hierarchy { new_node } }; - h = next_h; } - Component::ParentDir => { - if let Some(parent) = h.parent.upgrade() { - h = parent; - } + Component::ParentDir if let Some(parent) = h.parent.upgrade() => { + h = parent; } _ => {} }