diff --git a/src/librustdoc/formats/renderer.rs b/src/librustdoc/formats/renderer.rs index b779363e5c70..9b0d193a0bc0 100644 --- a/src/librustdoc/formats/renderer.rs +++ b/src/librustdoc/formats/renderer.rs @@ -9,7 +9,7 @@ use crate::formats::cache::Cache; /// Allows for different backends to rustdoc to be used with the `run_format()` function. Each /// backend renderer has hooks for initialization, documenting an item, entering and exiting a /// module, and cleanup/finalizing output. -crate trait FormatRenderer<'tcx>: Clone { +crate trait FormatRenderer<'tcx>: Sized { /// Gives a description of the renderer. Used for performance profiling. fn descr() -> &'static str; @@ -23,6 +23,9 @@ crate trait FormatRenderer<'tcx>: Clone { tcx: TyCtxt<'tcx>, ) -> Result<(Self, clean::Crate), Error>; + /// Make a new renderer to render a child of the item currently being rendered. + fn make_child_renderer(&self) -> Self; + /// Renders a single non-module item. This means no recursive sub-item rendering is required. fn item(&mut self, item: clean::Item) -> Result<(), Error>; @@ -67,7 +70,7 @@ crate fn run_format<'tcx, T: FormatRenderer<'tcx>>( item.name = Some(krate.name); // Render the crate documentation - let mut work = vec![(format_renderer.clone(), item)]; + let mut work = vec![(format_renderer.make_child_renderer(), item)]; let unknown = rustc_span::Symbol::intern(""); while let Some((mut cx, item)) = work.pop() { @@ -87,7 +90,7 @@ crate fn run_format<'tcx, T: FormatRenderer<'tcx>>( }; for it in module.items { debug!("Adding {:?} to worklist", it.name); - work.push((cx.clone(), it)); + work.push((cx.make_child_renderer(), it)); } cx.mod_item_out(&name)?; diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs index f8ca259fb9ab..ccc51c243ad8 100644 --- a/src/librustdoc/html/markdown.rs +++ b/src/librustdoc/html/markdown.rs @@ -1373,10 +1373,6 @@ impl IdMap { } } - crate fn reset(&mut self) { - self.map = init_id_map(); - } - crate fn derive + ToString>(&mut self, candidate: S) -> String { let id = match self.map.get_mut(candidate.as_ref()) { None => candidate.to_string(), diff --git a/src/librustdoc/html/markdown/tests.rs b/src/librustdoc/html/markdown/tests.rs index 59ca841715c5..e016d2c3ab00 100644 --- a/src/librustdoc/html/markdown/tests.rs +++ b/src/librustdoc/html/markdown/tests.rs @@ -38,15 +38,9 @@ fn test_unique_id() { "assoc_type.Item-1", ]; - let map = RefCell::new(IdMap::new()); - let test = || { - let mut map = map.borrow_mut(); - let actual: Vec = input.iter().map(|s| map.derive(s.to_string())).collect(); - assert_eq!(&actual[..], expected); - }; - test(); - map.borrow_mut().reset(); - test(); + let mut map = IdMap::new(); + let actual: Vec = input.iter().map(|s| map.derive(s.to_string())).collect(); + assert_eq!(&actual[..], expected); } #[test] diff --git a/src/librustdoc/html/render/context.rs b/src/librustdoc/html/render/context.rs index 23c2a9251059..41d4aef7c7af 100644 --- a/src/librustdoc/html/render/context.rs +++ b/src/librustdoc/html/render/context.rs @@ -40,7 +40,6 @@ use crate::html::{layout, sources}; /// It is intended that this context is a lightweight object which can be fairly /// easily cloned because it is cloned per work-job (about once per item in the /// rustdoc tree). -#[derive(Clone)] crate struct Context<'tcx> { /// Current hierarchy of components leading down to what's currently being /// rendered @@ -157,11 +156,6 @@ impl<'tcx> Context<'tcx> { static_extra_scripts: &[], }; - { - self.id_map.borrow_mut().reset(); - self.id_map.borrow_mut().populate(&INITIAL_IDS); - } - if !self.render_redirect_pages { layout::render( &self.shared.layout, @@ -436,6 +430,21 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> { Ok((cx, krate)) } + fn make_child_renderer(&self) -> Self { + let mut id_map = IdMap::new(); + id_map.populate(&INITIAL_IDS); + + Self { + current: self.current.clone(), + dst: self.dst.clone(), + render_redirect_pages: self.render_redirect_pages, + id_map: Box::new(RefCell::new(id_map)), + deref_id_map: Box::new(RefCell::new(FxHashMap::default())), + shared: Rc::clone(&self.shared), + cache: Rc::clone(&self.cache), + } + } + fn after_krate( &mut self, krate: &clean::Crate, diff --git a/src/librustdoc/json/mod.rs b/src/librustdoc/json/mod.rs index e6edf33d23c8..406c57826a09 100644 --- a/src/librustdoc/json/mod.rs +++ b/src/librustdoc/json/mod.rs @@ -149,6 +149,10 @@ impl<'tcx> FormatRenderer<'tcx> for JsonRenderer<'tcx> { )) } + fn make_child_renderer(&self) -> Self { + self.clone() + } + /// Inserts an item into the index. This should be used rather than directly calling insert on /// the hashmap because certain items (traits and types) need to have their mappings for trait /// implementations filled out before they're inserted.