From 5fa1653c5cd175430d14c3c3d8416635772811da Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 25 Nov 2024 16:19:02 +0100 Subject: [PATCH] Move `SharedContext` out of `Rc` --- src/librustdoc/html/render/context.rs | 45 ++++---- src/librustdoc/html/render/mod.rs | 70 ++++++------ src/librustdoc/html/render/print_item.rs | 117 ++++++++++----------- src/librustdoc/html/render/sidebar.rs | 72 +++++++++---- src/librustdoc/html/render/write_shared.rs | 23 ++-- src/librustdoc/html/sources.rs | 6 +- 6 files changed, 171 insertions(+), 162 deletions(-) diff --git a/src/librustdoc/html/render/context.rs b/src/librustdoc/html/render/context.rs index bc1f0423c17c..81a9cce80d12 100644 --- a/src/librustdoc/html/render/context.rs +++ b/src/librustdoc/html/render/context.rs @@ -2,7 +2,6 @@ use std::cell::RefCell; use std::collections::BTreeMap; use std::io; use std::path::{Path, PathBuf}; -use std::rc::Rc; use std::sync::mpsc::{Receiver, channel}; use rinja::Template; @@ -51,17 +50,17 @@ pub(crate) struct Context<'tcx> { pub(crate) dst: PathBuf, /// Tracks section IDs for `Deref` targets so they match in both the main /// body and the sidebar. - pub(super) deref_id_map: DefIdMap, + pub(super) deref_id_map: RefCell>, /// The map used to ensure all generated 'id=' attributes are unique. - pub(super) id_map: IdMap, + pub(super) id_map: RefCell, /// Shared mutable state. /// /// Issue for improving the situation: [#82381][] /// /// [#82381]: https://github.com/rust-lang/rust/issues/82381 - pub(crate) shared: Rc>, + pub(crate) shared: SharedContext<'tcx>, /// Collection of all types with notable traits referenced in the current module. - pub(crate) types_with_notable_traits: FxIndexSet, + pub(crate) types_with_notable_traits: RefCell>, /// Contains information that needs to be saved and reset after rendering an item which is /// not a module. pub(crate) info: ContextInfo, @@ -170,8 +169,8 @@ impl<'tcx> Context<'tcx> { self.shared.tcx.sess } - pub(super) fn derive_id + ToString>(&mut self, id: S) -> String { - self.id_map.derive(id) + pub(super) fn derive_id + ToString>(&self, id: S) -> String { + self.id_map.borrow_mut().derive(id) } /// String representation of how to get back to the root path of the 'doc/' @@ -230,24 +229,23 @@ impl<'tcx> Context<'tcx> { }; if !render_redirect_pages { - let clone_shared = Rc::clone(&self.shared); + let mut page_buffer = Buffer::html(); + print_item(self, it, &mut page_buffer); let page = layout::Page { css_class: tyname_s, root_path: &self.root_path(), - static_root_path: clone_shared.static_root_path.as_deref(), + static_root_path: self.shared.static_root_path.as_deref(), title: &title, description: &desc, - resource_suffix: &clone_shared.resource_suffix, + resource_suffix: &self.shared.resource_suffix, rust_logo: has_doc_flag(self.tcx(), LOCAL_CRATE.as_def_id(), sym::rust_logo), }; - let mut page_buffer = Buffer::html(); - print_item(self, it, &mut page_buffer); layout::render( - &clone_shared.layout, + &self.shared.layout, &page, |buf: &mut _| print_sidebar(self, it, buf), move |buf: &mut Buffer| buf.push_buffer(page_buffer), - &clone_shared.style_files, + &self.shared.style_files, ) } else { if let Some(&(ref names, ty)) = self.cache().paths.get(&it.item_id.expect_def_id()) { @@ -572,10 +570,10 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> { let mut cx = Context { current: Vec::new(), dst, - id_map, + id_map: RefCell::new(id_map), deref_id_map: Default::default(), - shared: Rc::new(scx), - types_with_notable_traits: FxIndexSet::default(), + shared: scx, + types_with_notable_traits: RefCell::new(FxIndexSet::default()), info: ContextInfo::new(include_sources), }; @@ -591,9 +589,9 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> { } fn make_child_renderer(&mut self) -> Self::InfoType { - self.deref_id_map.clear(); - self.id_map.clear(); - self.types_with_notable_traits.clear(); + self.deref_id_map.borrow_mut().clear(); + self.id_map.borrow_mut().clear(); + self.types_with_notable_traits.borrow_mut().clear(); self.info } @@ -612,7 +610,7 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> { if !root_path.ends_with('/') { root_path.push('/'); } - let shared = Rc::clone(&self.shared); + let shared = &self.shared; let mut page = layout::Page { title: "List of all items in this crate", css_class: "mod sys", @@ -759,11 +757,8 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> { shared.fs.write(redirect_map_path, paths)?; } - // No need for it anymore. - drop(shared); - // Flush pending errors. - Rc::get_mut(&mut self.shared).unwrap().fs.close(); + self.shared.fs.close(); let nb_errors = self.shared.errors.iter().map(|err| self.tcx().dcx().err(err)).count(); if nb_errors > 0 { Err(Error::new(io::Error::new(io::ErrorKind::Other, "I/O error"), "")) diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index 7c5048cd164b..f43672575723 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -41,7 +41,6 @@ use std::collections::VecDeque; use std::fmt::{self, Write}; use std::iter::Peekable; use std::path::PathBuf; -use std::rc::Rc; use std::{fs, str}; use rinja::Template; @@ -504,7 +503,7 @@ fn scrape_examples_help(shared: &SharedContext<'_>) -> String { } fn document<'a, 'cx: 'a>( - cx: &'a mut Context<'cx>, + cx: &'a Context<'cx>, item: &'a clean::Item, parent: Option<&'a clean::Item>, heading_offset: HeadingOffset, @@ -525,7 +524,7 @@ fn document<'a, 'cx: 'a>( /// Render md_text as markdown. fn render_markdown<'a, 'cx: 'a>( - cx: &'a mut Context<'cx>, + cx: &'a Context<'cx>, md_text: &'a str, links: Vec, heading_offset: HeadingOffset, @@ -537,7 +536,7 @@ fn render_markdown<'a, 'cx: 'a>( Markdown { content: md_text, links: &links, - ids: &mut cx.id_map, + ids: &mut cx.id_map.borrow_mut(), error_codes: cx.shared.codes, edition: cx.shared.edition(), playground: &cx.shared.playground, @@ -552,7 +551,7 @@ fn render_markdown<'a, 'cx: 'a>( /// docs are longer, a "Read more" link is appended to the end. fn document_short<'a, 'cx: 'a>( item: &'a clean::Item, - cx: &'a mut Context<'cx>, + cx: &'a Context<'cx>, link: AssocItemLink<'a>, parent: &'a clean::Item, show_def_docs: bool, @@ -585,7 +584,7 @@ fn document_short<'a, 'cx: 'a>( fn document_full_collapsible<'a, 'cx: 'a>( item: &'a clean::Item, - cx: &'a mut Context<'cx>, + cx: &'a Context<'cx>, heading_offset: HeadingOffset, ) -> impl fmt::Display + 'a + Captures<'cx> { document_full_inner(item, cx, true, heading_offset) @@ -593,7 +592,7 @@ fn document_full_collapsible<'a, 'cx: 'a>( fn document_full<'a, 'cx: 'a>( item: &'a clean::Item, - cx: &'a mut Context<'cx>, + cx: &'a Context<'cx>, heading_offset: HeadingOffset, ) -> impl fmt::Display + 'a + Captures<'cx> { document_full_inner(item, cx, false, heading_offset) @@ -601,7 +600,7 @@ fn document_full<'a, 'cx: 'a>( fn document_full_inner<'a, 'cx: 'a>( item: &'a clean::Item, - cx: &'a mut Context<'cx>, + cx: &'a Context<'cx>, is_collapsible: bool, heading_offset: HeadingOffset, ) -> impl fmt::Display + 'a + Captures<'cx> { @@ -644,7 +643,7 @@ struct ItemInfo { /// * Deprecated /// * Required features (through the `doc_cfg` feature) fn document_item_info( - cx: &mut Context<'_>, + cx: &Context<'_>, item: &clean::Item, parent: Option<&clean::Item>, ) -> ItemInfo { @@ -690,7 +689,7 @@ enum ShortItemInfo { /// the item's documentation. fn short_item_info( item: &clean::Item, - cx: &mut Context<'_>, + cx: &Context<'_>, parent: Option<&clean::Item>, ) -> Vec { let mut extra_info = vec![]; @@ -715,7 +714,8 @@ fn short_item_info( if let Some(note) = note { let note = note.as_str(); - let html = MarkdownItemInfo(note, &mut cx.id_map); + let mut id_map = cx.id_map.borrow_mut(); + let html = MarkdownItemInfo(note, &mut id_map); message.push_str(": "); message.push_str(&html.into_string()); } @@ -749,18 +749,17 @@ fn short_item_info( // Render the list of items inside one of the sections "Trait Implementations", // "Auto Trait Implementations," "Blanket Trait Implementations" (on struct/enum pages). pub(crate) fn render_impls( - cx: &mut Context<'_>, + cx: &Context<'_>, mut w: impl Write, impls: &[&Impl], containing_item: &clean::Item, toggle_open_by_default: bool, ) { - let tcx = cx.tcx(); let mut rendered_impls = impls .iter() .map(|i| { let did = i.trait_did().unwrap(); - let provided_trait_methods = i.inner_impl().provided_trait_methods(tcx); + let provided_trait_methods = i.inner_impl().provided_trait_methods(cx.tcx()); let assoc_link = AssocItemLink::GotoSource(did.into(), &provided_trait_methods); let mut buffer = Buffer::new(); render_impl( @@ -906,7 +905,7 @@ fn assoc_method( d: &clean::FnDecl, link: AssocItemLink<'_>, parent: ItemType, - cx: &mut Context<'_>, + cx: &Context<'_>, render_mode: RenderMode, ) { let tcx = cx.tcx(); @@ -1071,7 +1070,7 @@ fn render_assoc_item( item: &clean::Item, link: AssocItemLink<'_>, parent: ItemType, - cx: &mut Context<'_>, + cx: &Context<'_>, render_mode: RenderMode, ) { match &item.kind { @@ -1191,7 +1190,7 @@ fn write_impl_section_heading(w: &mut impl fmt::Write, title: &str, id: &str) { pub(crate) fn render_all_impls( mut w: impl Write, - cx: &mut Context<'_>, + cx: &Context<'_>, containing_item: &clean::Item, concrete: &[&Impl], synthetic: &[&Impl], @@ -1225,7 +1224,7 @@ pub(crate) fn render_all_impls( } fn render_assoc_items<'a, 'cx: 'a>( - cx: &'a mut Context<'cx>, + cx: &'a Context<'cx>, containing_item: &'a clean::Item, it: DefId, what: AssocItemRender<'a>, @@ -1240,15 +1239,14 @@ fn render_assoc_items<'a, 'cx: 'a>( fn render_assoc_items_inner( mut w: &mut dyn fmt::Write, - cx: &mut Context<'_>, + cx: &Context<'_>, containing_item: &clean::Item, it: DefId, what: AssocItemRender<'_>, derefs: &mut DefIdSet, ) { info!("Documenting associated items of {:?}", containing_item.name); - let shared = Rc::clone(&cx.shared); - let cache = &shared.cache; + let cache = &cx.shared.cache; let Some(v) = cache.impls.get(&it) else { return }; let (non_trait, traits): (Vec<_>, _) = v.iter().partition(|i| i.inner_impl().trait_.is_none()); if !non_trait.is_empty() { @@ -1276,7 +1274,7 @@ fn render_assoc_items_inner( ); tmp_buf.write_str(""); if let Some(def_id) = type_.def_id(cx.cache()) { - cx.deref_id_map.insert(def_id, id); + cx.deref_id_map.borrow_mut().insert(def_id, id); } (RenderMode::ForDeref { mut_: deref_mut_ }, derived_id, r#" class="impl-items""#) } @@ -1340,7 +1338,7 @@ fn render_assoc_items_inner( fn render_deref_methods( mut w: impl Write, - cx: &mut Context<'_>, + cx: &Context<'_>, impl_: &Impl, container_item: &clean::Item, deref_mut: bool, @@ -1407,7 +1405,7 @@ fn should_render_item(item: &clean::Item, deref_mut_: bool, tcx: TyCtxt<'_>) -> } } -pub(crate) fn notable_traits_button(ty: &clean::Type, cx: &mut Context<'_>) -> Option { +pub(crate) fn notable_traits_button(ty: &clean::Type, cx: &Context<'_>) -> Option { let mut has_notable_trait = false; if ty.is_unit() { @@ -1450,7 +1448,7 @@ pub(crate) fn notable_traits_button(ty: &clean::Type, cx: &mut Context<'_>) -> O } if has_notable_trait { - cx.types_with_notable_traits.insert(ty.clone()); + cx.types_with_notable_traits.borrow_mut().insert(ty.clone()); Some(format!( " ", ty = Escape(&format!("{:#}", ty.print(cx))), @@ -1554,7 +1552,7 @@ struct ImplRenderingParameters { fn render_impl( w: &mut Buffer, - cx: &mut Context<'_>, + cx: &Context<'_>, i: &Impl, parent: &clean::Item, link: AssocItemLink<'_>, @@ -1563,8 +1561,7 @@ fn render_impl( aliases: &[String], rendering_params: ImplRenderingParameters, ) { - let shared = Rc::clone(&cx.shared); - let cache = &shared.cache; + let cache = &cx.shared.cache; let traits = &cache.traits; let trait_ = i.trait_did().map(|did| &traits[&did]); let mut close_tags = >::with_capacity(2); @@ -1577,7 +1574,7 @@ fn render_impl( fn doc_impl_item( boring: &mut Buffer, interesting: &mut Buffer, - cx: &mut Context<'_>, + cx: &Context<'_>, item: &clean::Item, parent: &clean::Item, link: AssocItemLink<'_>, @@ -1867,7 +1864,7 @@ fn render_impl( fn render_default_items( boring: &mut Buffer, interesting: &mut Buffer, - cx: &mut Context<'_>, + cx: &Context<'_>, t: &clean::Trait, i: &clean::Impl, parent: &clean::Item, @@ -1907,6 +1904,7 @@ fn render_impl( } } + let trait_is_none = trait_.is_none(); // If we've implemented a trait, then also emit documentation for all // default items which weren't overridden in the implementation block. // We don't emit documentation for default items if they appear in the @@ -1952,7 +1950,7 @@ fn render_impl( } if let Some(ref dox) = i.impl_item.opt_doc_value() { - if trait_.is_none() && impl_.items.is_empty() { + if trait_is_none && impl_.items.is_empty() { w.write_str( "
\
This impl block contains no items.
\ @@ -1965,7 +1963,7 @@ fn render_impl( Markdown { content: dox, links: &i.impl_item.links(cx), - ids: &mut cx.id_map, + ids: &mut cx.id_map.borrow_mut(), error_codes: cx.shared.codes, edition: cx.shared.edition(), playground: &cx.shared.playground, @@ -2025,7 +2023,7 @@ fn render_rightside(w: &mut Buffer, cx: &Context<'_>, item: &clean::Item, render pub(crate) fn render_impl_summary( w: &mut Buffer, - cx: &mut Context<'_>, + cx: &Context<'_>, i: &Impl, parent: &clean::Item, show_def_docs: bool, @@ -2186,7 +2184,7 @@ fn extract_for_impl_name(item: &clean::Item, cx: &Context<'_>) -> Option<(String /// implementations that are on concrete or partially generic types, only keeping implementations /// of the form `impl Trait for &T`. pub(crate) fn get_filtered_impls_for_reference<'a>( - shared: &'a Rc>, + shared: &'a SharedContext<'_>, it: &clean::Item, ) -> (Vec<&'a Impl>, Vec<&'a Impl>, Vec<&'a Impl>) { let def_id = it.item_id.expect_def_id(); @@ -2423,14 +2421,14 @@ const MAX_FULL_EXAMPLES: usize = 5; const NUM_VISIBLE_LINES: usize = 10; /// Generates the HTML for example call locations generated via the --scrape-examples flag. -fn render_call_locations(mut w: W, cx: &mut Context<'_>, item: &clean::Item) { +fn render_call_locations(mut w: W, cx: &Context<'_>, item: &clean::Item) { let tcx = cx.tcx(); let def_id = item.item_id.expect_def_id(); let key = tcx.def_path_hash(def_id); let Some(call_locations) = cx.shared.call_locations.get(&key) else { return }; // Generate a unique ID so users can link to this section for a given method - let id = cx.id_map.derive("scraped-examples"); + let id = cx.derive_id("scraped-examples"); write!( &mut w, "
\ diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index a86b7966c260..4c8d704e65bc 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -1,7 +1,5 @@ -use std::cell::{RefCell, RefMut}; use std::cmp::Ordering; use std::fmt; -use std::rc::Rc; use itertools::Itertools; use rinja::Template; @@ -61,7 +59,7 @@ macro_rules! item_template { ( $(#[$meta:meta])* struct $name:ident<'a, 'cx> { - cx: RefCell<&'a mut Context<'cx>>, + cx: &'a Context<'cx>, it: &'a clean::Item, $($field_name:ident: $field_ty:ty),*, }, @@ -70,14 +68,14 @@ macro_rules! item_template { #[derive(Template)] $(#[$meta])* struct $name<'a, 'cx> { - cx: RefCell<&'a mut Context<'cx>>, + cx: &'a Context<'cx>, it: &'a clean::Item, $($field_name: $field_ty),* } impl<'a, 'cx: 'a> ItemTemplate<'a, 'cx> for $name<'a, 'cx> { - fn item_and_mut_cx(&self) -> (&'a clean::Item, RefMut<'_, &'a mut Context<'cx>>) { - (&self.it, self.cx.borrow_mut()) + fn item_and_cx(&self) -> (&'a clean::Item, &'a Context<'cx>) { + (&self.it, &self.cx) } } @@ -95,8 +93,8 @@ macro_rules! item_template_methods { (document $($rest:tt)*) => { fn document<'b>(&'b self) -> impl fmt::Display + Captures<'a> + 'b + Captures<'cx> { display_fn(move |f| { - let (item, mut cx) = self.item_and_mut_cx(); - let v = document(*cx, item, None, HeadingOffset::H2); + let (item, cx) = self.item_and_cx(); + let v = document(cx, item, None, HeadingOffset::H2); write!(f, "{v}") }) } @@ -105,9 +103,9 @@ macro_rules! item_template_methods { (document_type_layout $($rest:tt)*) => { fn document_type_layout<'b>(&'b self) -> impl fmt::Display + Captures<'a> + 'b + Captures<'cx> { display_fn(move |f| { - let (item, cx) = self.item_and_mut_cx(); + let (item, cx) = self.item_and_cx(); let def_id = item.item_id.expect_def_id(); - let v = document_type_layout(*cx, def_id); + let v = document_type_layout(cx, def_id); write!(f, "{v}") }) } @@ -116,8 +114,8 @@ macro_rules! item_template_methods { (render_attributes_in_pre $($rest:tt)*) => { fn render_attributes_in_pre<'b>(&'b self) -> impl fmt::Display + Captures<'a> + 'b + Captures<'cx> { display_fn(move |f| { - let (item, cx) = self.item_and_mut_cx(); - let v = render_attributes_in_pre(item, "", &cx); + let (item, cx) = self.item_and_cx(); + let v = render_attributes_in_pre(item, "", cx); write!(f, "{v}") }) } @@ -126,9 +124,9 @@ macro_rules! item_template_methods { (render_assoc_items $($rest:tt)*) => { fn render_assoc_items<'b>(&'b self) -> impl fmt::Display + Captures<'a> + 'b + Captures<'cx> { display_fn(move |f| { - let (item, mut cx) = self.item_and_mut_cx(); + let (item, cx) = self.item_and_cx(); let def_id = item.item_id.expect_def_id(); - let v = render_assoc_items(*cx, item, def_id, AssocItemRender::All); + let v = render_assoc_items(cx, item, def_id, AssocItemRender::All); write!(f, "{v}") }) } @@ -175,7 +173,7 @@ fn print_where_clause_and_check<'a, 'tcx: 'a>( len_before != buffer.len() } -pub(super) fn print_item(cx: &mut Context<'_>, item: &clean::Item, buf: &mut Buffer) { +pub(super) fn print_item(cx: &Context<'_>, item: &clean::Item, buf: &mut Buffer) { debug_assert!(!item.is_stripped()); let typ = match item.kind { clean::ModuleItem(_) => { @@ -277,13 +275,14 @@ pub(super) fn print_item(cx: &mut Context<'_>, item: &clean::Item, buf: &mut Buf } // Render notable-traits.js used for all methods in this module. - if !cx.types_with_notable_traits.is_empty() { + let mut types_with_notable_traits = cx.types_with_notable_traits.borrow_mut(); + if !types_with_notable_traits.is_empty() { write!( buf, r#""#, - notable_traits_json(cx.types_with_notable_traits.iter(), cx) + notable_traits_json(types_with_notable_traits.iter(), cx) ); - cx.types_with_notable_traits.clear(); + types_with_notable_traits.clear(); } } @@ -308,10 +307,10 @@ fn toggle_close(mut w: impl fmt::Write) { } trait ItemTemplate<'a, 'cx: 'a>: rinja::Template + fmt::Display { - fn item_and_mut_cx(&self) -> (&'a clean::Item, RefMut<'_, &'a mut Context<'cx>>); + fn item_and_cx(&self) -> (&'a clean::Item, &'a Context<'cx>); } -fn item_module(w: &mut Buffer, cx: &mut Context<'_>, item: &clean::Item, items: &[clean::Item]) { +fn item_module(w: &mut Buffer, cx: &Context<'_>, item: &clean::Item, items: &[clean::Item]) { write!(w, "{}", document(cx, item, None, HeadingOffset::H2)); let mut not_stripped_items = @@ -594,7 +593,7 @@ fn extra_info_tags<'a, 'tcx: 'a>( }) } -fn item_function(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, f: &clean::Function) { +fn item_function(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, f: &clean::Function) { let tcx = cx.tcx(); let header = it.fn_header(tcx).expect("printing a function which isn't a function"); debug!( @@ -649,7 +648,7 @@ fn item_function(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, f: &cle write!(w, "{}", document(cx, it, None, HeadingOffset::H2)); } -fn item_trait(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &clean::Trait) { +fn item_trait(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Trait) { let tcx = cx.tcx(); let bounds = bounds(&t.bounds, false, cx); let required_types = t.items.iter().filter(|m| m.is_ty_associated_type()).collect::>(); @@ -801,7 +800,7 @@ fn item_trait(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &clean: // Trait documentation write!(w, "{}", document(cx, it, None, HeadingOffset::H2)); - fn trait_item(w: &mut Buffer, cx: &mut Context<'_>, m: &clean::Item, t: &clean::Item) { + fn trait_item(w: &mut Buffer, cx: &Context<'_>, m: &clean::Item, t: &clean::Item) { let name = m.name.unwrap(); info!("Documenting {name} on {ty_name:?}", ty_name = t.name); let item_type = m.type_(); @@ -929,8 +928,6 @@ fn item_trait(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &clean: // If there are methods directly on this trait object, render them here. write!(w, "{}", render_assoc_items(cx, it, it.item_id.expect_def_id(), AssocItemRender::All)); - let cloned_shared = Rc::clone(&cx.shared); - let cache = &cloned_shared.cache; let mut extern_crates = FxIndexSet::default(); if !t.is_dyn_compatible(cx.tcx()) { @@ -950,12 +947,13 @@ fn item_trait(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &clean: ); } - if let Some(implementors) = cache.implementors.get(&it.item_id.expect_def_id()) { + if let Some(implementors) = cx.shared.cache.implementors.get(&it.item_id.expect_def_id()) { // The DefId is for the first Type found with that name. The bool is // if any Types with the same name but different DefId have been found. let mut implementor_dups: FxHashMap = FxHashMap::default(); for implementor in implementors { - if let Some(did) = implementor.inner_impl().for_.without_borrowed_ref().def_id(cache) + if let Some(did) = + implementor.inner_impl().for_.without_borrowed_ref().def_id(&cx.shared.cache) && !did.is_local() { extern_crates.insert(did.krate); @@ -1036,7 +1034,10 @@ fn item_trait(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &clean: it, w, &implementor_dups, - &collect_paths_for_type(implementor.inner_impl().for_.clone(), cache), + &collect_paths_for_type( + implementor.inner_impl().for_.clone(), + &cx.shared.cache, + ), ); } w.write_str("
"); @@ -1139,8 +1140,8 @@ fn item_trait(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &clean: .chain(std::iter::once("trait.impl")) .collect(); if let Some(did) = it.item_id.as_def_id() - && let get_extern = { || cache.external_paths.get(&did).map(|s| &s.0) } - && let Some(fqp) = cache.exact_paths.get(&did).or_else(get_extern) + && let get_extern = { || cx.shared.cache.external_paths.get(&did).map(|s| &s.0) } + && let Some(fqp) = cx.shared.cache.exact_paths.get(&did).or_else(get_extern) { js_src_path.extend(fqp[..fqp.len() - 1].iter().copied()); js_src_path.push_fmt(format_args!("{}.{}.js", it.type_(), fqp.last().unwrap())); @@ -1164,7 +1165,7 @@ fn item_trait(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &clean: fn item_trait_alias( w: &mut impl fmt::Write, - cx: &mut Context<'_>, + cx: &Context<'_>, it: &clean::Item, t: &clean::TraitAlias, ) { @@ -1190,7 +1191,7 @@ fn item_trait_alias( .unwrap(); } -fn item_type_alias(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &clean::TypeAlias) { +fn item_type_alias(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::TypeAlias) { wrap_item(w, |w| { write!( w, @@ -1355,8 +1356,7 @@ fn item_type_alias(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &c // // [JSONP]: https://en.wikipedia.org/wiki/JSONP // [^115718]: https://github.com/rust-lang/rust/issues/115718 - let cloned_shared = Rc::clone(&cx.shared); - let cache = &cloned_shared.cache; + let cache = &cx.shared.cache; if let Some(target_did) = t.type_.def_id(cache) && let get_extern = { || cache.external_paths.get(&target_did) } && let Some(&(ref target_fqp, target_type)) = cache.paths.get(&target_did).or_else(get_extern) && @@ -1380,11 +1380,11 @@ fn item_type_alias(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &c } } -fn item_union(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, s: &clean::Union) { +fn item_union(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, s: &clean::Union) { item_template!( #[template(path = "item_union.html")] struct ItemUnion<'a, 'cx> { - cx: RefCell<&'a mut Context<'cx>>, + cx: &'a Context<'cx>, it: &'a clean::Item, s: &'a clean::Union, }, @@ -1394,8 +1394,7 @@ fn item_union(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, s: &clean: impl<'a, 'cx: 'a> ItemUnion<'a, 'cx> { fn render_union<'b>(&'b self) -> impl fmt::Display + Captures<'a> + 'b + Captures<'cx> { display_fn(move |f| { - let cx = self.cx.borrow_mut(); - let v = render_union(self.it, Some(&self.s.generics), &self.s.fields, *cx); + let v = render_union(self.it, Some(&self.s.generics), &self.s.fields, self.cx); write!(f, "{v}") }) } @@ -1405,15 +1404,13 @@ fn item_union(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, s: &clean: field: &'a clean::Item, ) -> impl fmt::Display + Captures<'a> + 'b + Captures<'cx> { display_fn(move |f| { - let mut cx = self.cx.borrow_mut(); - let v = document(*cx, field, Some(self.it), HeadingOffset::H3); + let v = document(self.cx, field, Some(self.it), HeadingOffset::H3); write!(f, "{v}") }) } fn stability_field(&self, field: &clean::Item) -> Option { - let cx = self.cx.borrow(); - field.stability_class(cx.tcx()) + field.stability_class(self.cx.tcx()) } fn print_ty<'b>( @@ -1421,8 +1418,7 @@ fn item_union(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, s: &clean: ty: &'a clean::Type, ) -> impl fmt::Display + Captures<'a> + 'b + Captures<'cx> { display_fn(move |f| { - let cx = self.cx.borrow(); - let v = ty.print(*cx); + let v = ty.print(&self.cx); write!(f, "{v}") }) } @@ -1441,7 +1437,7 @@ fn item_union(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, s: &clean: } } - ItemUnion { cx: RefCell::new(cx), it, s }.render_into(w).unwrap(); + ItemUnion { cx, it, s }.render_into(w).unwrap(); } fn print_tuple_struct_fields<'a, 'cx: 'a>( @@ -1471,7 +1467,7 @@ fn print_tuple_struct_fields<'a, 'cx: 'a>( }) } -fn item_enum(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, e: &clean::Enum) { +fn item_enum(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, e: &clean::Enum) { let count_variants = e.variants().count(); wrap_item(w, |w| { render_attributes_in_code(w, it, cx); @@ -1532,7 +1528,7 @@ fn should_show_enum_discriminant( fn display_c_like_variant( w: &mut Buffer, - cx: &mut Context<'_>, + cx: &Context<'_>, item: &clean::Item, variant: &clean::Variant, index: VariantIdx, @@ -1557,7 +1553,7 @@ fn display_c_like_variant( fn render_enum_fields( mut w: &mut Buffer, - cx: &mut Context<'_>, + cx: &Context<'_>, g: Option<&clean::Generics>, variants: &IndexVec, count_variants: usize, @@ -1621,7 +1617,7 @@ fn render_enum_fields( fn item_variants( w: &mut Buffer, - cx: &mut Context<'_>, + cx: &Context<'_>, it: &clean::Item, variants: &IndexVec, enum_def_id: DefId, @@ -1743,7 +1739,7 @@ fn item_variants( write!(w, "
"); } -fn item_macro(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &clean::Macro) { +fn item_macro(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Macro) { wrap_item(w, |w| { // FIXME: Also print `#[doc(hidden)]` for `macro_rules!` if it `is_doc_hidden`. if !t.macro_rules { @@ -1756,7 +1752,7 @@ fn item_macro(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &clean: fn item_proc_macro( w: &mut impl fmt::Write, - cx: &mut Context<'_>, + cx: &Context<'_>, it: &clean::Item, m: &clean::ProcMacro, ) { @@ -1790,7 +1786,7 @@ fn item_proc_macro( write!(w, "{}", document(cx, it, None, HeadingOffset::H2)).unwrap(); } -fn item_primitive(w: &mut impl fmt::Write, cx: &mut Context<'_>, it: &clean::Item) { +fn item_primitive(w: &mut impl fmt::Write, cx: &Context<'_>, it: &clean::Item) { let def_id = it.item_id.expect_def_id(); write!(w, "{}", document(cx, it, None, HeadingOffset::H2)).unwrap(); if it.name.map(|n| n.as_str() != "reference").unwrap_or(false) { @@ -1798,8 +1794,7 @@ fn item_primitive(w: &mut impl fmt::Write, cx: &mut Context<'_>, it: &clean::Ite } else { // We handle the "reference" primitive type on its own because we only want to list // implementations on generic types. - let shared = Rc::clone(&cx.shared); - let (concrete, synthetic, blanket_impl) = get_filtered_impls_for_reference(&shared, it); + let (concrete, synthetic, blanket_impl) = get_filtered_impls_for_reference(&cx.shared, it); render_all_impls(w, cx, it, &concrete, &synthetic, &blanket_impl); } @@ -1807,7 +1802,7 @@ fn item_primitive(w: &mut impl fmt::Write, cx: &mut Context<'_>, it: &clean::Ite fn item_constant( w: &mut Buffer, - cx: &mut Context<'_>, + cx: &Context<'_>, it: &clean::Item, generics: &clean::Generics, ty: &clean::Type, @@ -1862,7 +1857,7 @@ fn item_constant( write!(w, "{}", document(cx, it, None, HeadingOffset::H2)) } -fn item_struct(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, s: &clean::Struct) { +fn item_struct(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, s: &clean::Struct) { wrap_item(w, |w| { render_attributes_in_code(w, it, cx); render_struct(w, it, Some(&s.generics), s.ctor_kind, &s.fields, "", true, cx); @@ -1879,7 +1874,7 @@ fn item_struct(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, s: &clean fn item_fields( w: &mut Buffer, - cx: &mut Context<'_>, + cx: &Context<'_>, it: &clean::Item, fields: &[clean::Item], ctor_kind: Option, @@ -1920,7 +1915,7 @@ fn item_fields( fn item_static( w: &mut impl fmt::Write, - cx: &mut Context<'_>, + cx: &Context<'_>, it: &clean::Item, s: &clean::Static, safety: Option, @@ -1944,7 +1939,7 @@ fn item_static( write!(w, "{}", document(cx, it, None, HeadingOffset::H2)).unwrap(); } -fn item_foreign_type(w: &mut impl fmt::Write, cx: &mut Context<'_>, it: &clean::Item) { +fn item_foreign_type(w: &mut impl fmt::Write, cx: &Context<'_>, it: &clean::Item) { wrap_item(w, |buffer| { buffer.write_str("extern {\n").unwrap(); render_attributes_in_code(buffer, it, cx); @@ -1962,7 +1957,7 @@ fn item_foreign_type(w: &mut impl fmt::Write, cx: &mut Context<'_>, it: &clean:: .unwrap(); } -fn item_keyword(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item) { +fn item_keyword(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item) { write!(w, "{}", document(cx, it, None, HeadingOffset::H2)) } @@ -2134,7 +2129,7 @@ impl Ord for ImplString { } fn render_implementor( - cx: &mut Context<'_>, + cx: &Context<'_>, implementor: &Impl, trait_: &clean::Item, w: &mut Buffer, diff --git a/src/librustdoc/html/render/sidebar.rs b/src/librustdoc/html/render/sidebar.rs index 76de8d872311..e99e2f04b2c5 100644 --- a/src/librustdoc/html/render/sidebar.rs +++ b/src/librustdoc/html/render/sidebar.rs @@ -1,10 +1,9 @@ use std::borrow::Cow; -use std::rc::Rc; use rinja::Template; use rustc_data_structures::fx::FxHashSet; use rustc_hir::def::CtorKind; -use rustc_hir::def_id::DefIdSet; +use rustc_hir::def_id::{DefIdMap, DefIdSet}; use rustc_middle::ty::{self, TyCtxt}; use tracing::debug; @@ -119,17 +118,18 @@ pub(crate) mod filters { pub(super) fn print_sidebar(cx: &Context<'_>, it: &clean::Item, buffer: &mut Buffer) { let mut ids = IdMap::new(); let mut blocks: Vec> = docblock_toc(cx, it, &mut ids).into_iter().collect(); + let deref_id_map = cx.deref_id_map.borrow(); match it.kind { - clean::StructItem(ref s) => sidebar_struct(cx, it, s, &mut blocks), - clean::TraitItem(ref t) => sidebar_trait(cx, it, t, &mut blocks), - clean::PrimitiveItem(_) => sidebar_primitive(cx, it, &mut blocks), - clean::UnionItem(ref u) => sidebar_union(cx, it, u, &mut blocks), - clean::EnumItem(ref e) => sidebar_enum(cx, it, e, &mut blocks), - clean::TypeAliasItem(ref t) => sidebar_type_alias(cx, it, t, &mut blocks), + clean::StructItem(ref s) => sidebar_struct(cx, it, s, &mut blocks, &deref_id_map), + clean::TraitItem(ref t) => sidebar_trait(cx, it, t, &mut blocks, &deref_id_map), + clean::PrimitiveItem(_) => sidebar_primitive(cx, it, &mut blocks, &deref_id_map), + clean::UnionItem(ref u) => sidebar_union(cx, it, u, &mut blocks, &deref_id_map), + clean::EnumItem(ref e) => sidebar_enum(cx, it, e, &mut blocks, &deref_id_map), + clean::TypeAliasItem(ref t) => sidebar_type_alias(cx, it, t, &mut blocks, &deref_id_map), clean::ModuleItem(ref m) => { blocks.push(sidebar_module(&m.items, &mut ids, ModuleLike::from(it))) } - clean::ForeignTypeItem => sidebar_foreign_type(cx, it, &mut blocks), + clean::ForeignTypeItem => sidebar_foreign_type(cx, it, &mut blocks, &deref_id_map), _ => {} } // The sidebar is designed to display sibling functions, modules and @@ -245,6 +245,7 @@ fn sidebar_struct<'a>( it: &'a clean::Item, s: &'a clean::Struct, items: &mut Vec>, + deref_id_map: &'a DefIdMap, ) { let fields = get_struct_fields_name(&s.fields); let field_name = match s.ctor_kind { @@ -255,7 +256,7 @@ fn sidebar_struct<'a>( if let Some(name) = field_name { items.push(LinkBlock::new(Link::new("fields", name), "structfield", fields)); } - sidebar_assoc_items(cx, it, items); + sidebar_assoc_items(cx, it, items, deref_id_map); } fn sidebar_trait<'a>( @@ -263,6 +264,7 @@ fn sidebar_trait<'a>( it: &'a clean::Item, t: &'a clean::Trait, blocks: &mut Vec>, + deref_id_map: &'a DefIdMap, ) { fn filter_items<'a>( items: &'a [clean::Item], @@ -313,7 +315,7 @@ fn sidebar_trait<'a>( .into_iter() .map(|(id, title, items)| LinkBlock::new(Link::new(id, title), "", items)), ); - sidebar_assoc_items(cx, it, blocks); + sidebar_assoc_items(cx, it, blocks, deref_id_map); if !t.is_dyn_compatible(cx.tcx()) { blocks.push(LinkBlock::forced( @@ -331,13 +333,17 @@ fn sidebar_trait<'a>( } } -fn sidebar_primitive<'a>(cx: &'a Context<'_>, it: &'a clean::Item, items: &mut Vec>) { +fn sidebar_primitive<'a>( + cx: &'a Context<'_>, + it: &'a clean::Item, + items: &mut Vec>, + deref_id_map: &'a DefIdMap, +) { if it.name.map(|n| n.as_str() != "reference").unwrap_or(false) { - sidebar_assoc_items(cx, it, items); + sidebar_assoc_items(cx, it, items, deref_id_map); } else { - let shared = Rc::clone(&cx.shared); let (concrete, synthetic, blanket_impl) = - super::get_filtered_impls_for_reference(&shared, it); + super::get_filtered_impls_for_reference(&cx.shared, it); sidebar_render_assoc_items(cx, &mut IdMap::new(), concrete, synthetic, blanket_impl, items); } @@ -348,6 +354,7 @@ fn sidebar_type_alias<'a>( it: &'a clean::Item, t: &'a clean::TypeAlias, items: &mut Vec>, + deref_id_map: &'a DefIdMap, ) { if let Some(inner_type) = &t.inner_type { items.push(LinkBlock::forced(Link::new("aliased-type", "Aliased type"), "type")); @@ -370,7 +377,7 @@ fn sidebar_type_alias<'a>( } } } - sidebar_assoc_items(cx, it, items); + sidebar_assoc_items(cx, it, items, deref_id_map); } fn sidebar_union<'a>( @@ -378,10 +385,11 @@ fn sidebar_union<'a>( it: &'a clean::Item, u: &'a clean::Union, items: &mut Vec>, + deref_id_map: &'a DefIdMap, ) { let fields = get_struct_fields_name(&u.fields); items.push(LinkBlock::new(Link::new("fields", "Fields"), "structfield", fields)); - sidebar_assoc_items(cx, it, items); + sidebar_assoc_items(cx, it, items, deref_id_map); } /// Adds trait implementations into the blocks of links @@ -389,6 +397,7 @@ fn sidebar_assoc_items<'a>( cx: &'a Context<'_>, it: &'a clean::Item, links: &mut Vec>, + deref_id_map: &'a DefIdMap, ) { let did = it.item_id.expect_def_id(); let cache = cx.cache(); @@ -433,7 +442,15 @@ fn sidebar_assoc_items<'a>( { let mut derefs = DefIdSet::default(); derefs.insert(did); - sidebar_deref_methods(cx, &mut blocks, impl_, v, &mut derefs, &mut used_links); + sidebar_deref_methods( + cx, + &mut blocks, + impl_, + v, + &mut derefs, + &mut used_links, + deref_id_map, + ); } let (synthetic, concrete): (Vec<&Impl>, Vec<&Impl>) = @@ -462,6 +479,7 @@ fn sidebar_deref_methods<'a>( v: &[Impl], derefs: &mut DefIdSet, used_links: &mut FxHashSet, + deref_id_map: &'a DefIdMap, ) { let c = cx.cache(); @@ -501,7 +519,7 @@ fn sidebar_deref_methods<'a>( if !ret.is_empty() { let id = if let Some(target_def_id) = real_target.def_id(c) { Cow::Borrowed( - cx.deref_id_map + deref_id_map .get(&target_def_id) .expect("Deref section without derived id") .as_str(), @@ -531,7 +549,15 @@ fn sidebar_deref_methods<'a>( .unwrap_or(false) }) { - sidebar_deref_methods(cx, out, target_deref_impl, target_impls, derefs, used_links); + sidebar_deref_methods( + cx, + out, + target_deref_impl, + target_impls, + derefs, + used_links, + deref_id_map, + ); } } } @@ -541,6 +567,7 @@ fn sidebar_enum<'a>( it: &'a clean::Item, e: &'a clean::Enum, items: &mut Vec>, + deref_id_map: &'a DefIdMap, ) { let mut variants = e .variants() @@ -550,7 +577,7 @@ fn sidebar_enum<'a>( variants.sort_unstable(); items.push(LinkBlock::new(Link::new("variants", "Variants"), "variant", variants)); - sidebar_assoc_items(cx, it, items); + sidebar_assoc_items(cx, it, items, deref_id_map); } pub(crate) fn sidebar_module_like( @@ -607,8 +634,9 @@ fn sidebar_foreign_type<'a>( cx: &'a Context<'_>, it: &'a clean::Item, items: &mut Vec>, + deref_id_map: &'a DefIdMap, ) { - sidebar_assoc_items(cx, it, items); + sidebar_assoc_items(cx, it, items, deref_id_map); } /// Renders the trait implementations for this type diff --git a/src/librustdoc/html/render/write_shared.rs b/src/librustdoc/html/render/write_shared.rs index 1fb589d829e5..ce10e5ecc244 100644 --- a/src/librustdoc/html/render/write_shared.rs +++ b/src/librustdoc/html/render/write_shared.rs @@ -43,7 +43,6 @@ use crate::config::{EmitType, PathToParts, RenderOptions, ShouldMerge}; use crate::docfs::PathError; use crate::error::Error; use crate::formats::Impl; -use crate::formats::cache::Cache; use crate::formats::item_type::ItemType; use crate::html::format::Buffer; use crate::html::layout; @@ -62,13 +61,12 @@ pub(crate) fn write_shared( tcx: TyCtxt<'_>, ) -> Result<(), Error> { // NOTE(EtomicBomb): I don't think we need sync here because no read-after-write? - Rc::get_mut(&mut cx.shared).unwrap().fs.set_sync_only(true); + cx.shared.fs.set_sync_only(true); let lock_file = cx.dst.join(".lock"); // Write shared runs within a flock; disable thread dispatching of IO temporarily. let _lock = try_err!(flock::Lock::new(&lock_file, true, true, true), &lock_file); - let SerializedSearchIndex { index, desc } = - build_index(krate, &mut Rc::get_mut(&mut cx.shared).unwrap().cache, tcx); + let SerializedSearchIndex { index, desc } = build_index(krate, &mut cx.shared.cache, tcx); write_search_desc(cx, krate, &desc)?; // does not need to be merged let crate_name = krate.name(cx.tcx()); @@ -128,7 +126,7 @@ pub(crate) fn write_shared( } } - Rc::get_mut(&mut cx.shared).unwrap().fs.set_sync_only(false); + cx.shared.fs.set_sync_only(false); Ok(()) } @@ -597,13 +595,11 @@ impl TypeAliasPart { krate: &Crate, crate_name_json: &OrderedJson, ) -> Result, Error> { - let cache = &Rc::clone(&cx.shared).cache; let mut path_parts = PartsAndLocations::default(); let mut type_impl_collector = TypeImplCollector { aliased_types: IndexMap::default(), visited_aliases: FxHashSet::default(), - cache, cx, }; DocVisitor::visit_crate(&mut type_impl_collector, krate); @@ -625,14 +621,14 @@ impl TypeAliasPart { // each type alias, and if it gives a different result, split the impl for &(type_alias_fqp, type_alias_item) in type_aliases { let mut buf = Buffer::html(); - cx.id_map = Default::default(); - cx.deref_id_map = Default::default(); + cx.id_map.borrow_mut().clear(); + cx.deref_id_map.borrow_mut().clear(); let target_did = impl_ .inner_impl() .trait_ .as_ref() .map(|trait_| trait_.def_id()) - .or_else(|| impl_.inner_impl().for_.def_id(cache)); + .or_else(|| impl_.inner_impl().for_.def_id(&cx.shared.cache)); let provided_methods; let assoc_link = if let Some(target_did) = target_did { provided_methods = impl_.inner_impl().provided_trait_methods(cx.tcx()); @@ -720,7 +716,7 @@ impl TraitAliasPart { } fn get( - cx: &mut Context<'_>, + cx: &Context<'_>, crate_name_json: &OrderedJson, ) -> Result, Error> { let cache = &cx.shared.cache; @@ -828,8 +824,7 @@ struct TypeImplCollector<'cx, 'cache, 'item> { /// Map from DefId-of-aliased-type to its data. aliased_types: IndexMap>, visited_aliases: FxHashSet, - cache: &'cache Cache, - cx: &'cache mut Context<'cx>, + cx: &'cache Context<'cx>, } /// Data for an aliased type. @@ -868,7 +863,7 @@ struct AliasedTypeImpl<'cache, 'item> { impl<'item> DocVisitor<'item> for TypeImplCollector<'_, '_, 'item> { fn visit_item(&mut self, it: &'item Item) { self.visit_item_recur(it); - let cache = self.cache; + let cache = &self.cx.shared.cache; let ItemKind::TypeAliasItem(ref t) = it.kind else { return }; let Some(self_did) = it.item_id.as_def_id() else { return }; if !self.visited_aliases.insert(self_did) { diff --git a/src/librustdoc/html/sources.rs b/src/librustdoc/html/sources.rs index 71b110c943e2..c37506e35883 100644 --- a/src/librustdoc/html/sources.rs +++ b/src/librustdoc/html/sources.rs @@ -2,7 +2,6 @@ use std::cell::RefCell; use std::ffi::OsStr; use std::ops::RangeInclusive; use std::path::{Component, Path, PathBuf}; -use std::rc::Rc; use std::{fmt, fs}; use rinja::Template; @@ -197,7 +196,7 @@ impl SourceCollector<'_, '_> { // Remove the utf-8 BOM if any let contents = contents.strip_prefix('\u{feff}').unwrap_or(&contents); - let shared = Rc::clone(&self.cx.shared); + let shared = &self.cx.shared; // Create the intermediate directories let cur = RefCell::new(PathBuf::new()); let root_path = RefCell::new(PathBuf::new()); @@ -250,12 +249,11 @@ impl SourceCollector<'_, '_> { &page, "", |buf: &mut _| { - let cx = &mut self.cx; print_src( buf, contents, file_span, - cx, + self.cx, &root_path, highlight::DecorationInfo::default(), SourceContext::Standalone { file_path },