diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs
index 7ca355ed11cc7..79cc0733b8b3c 100644
--- a/src/librustdoc/html/render/mod.rs
+++ b/src/librustdoc/html/render/mod.rs
@@ -44,7 +44,6 @@ use std::rc::Rc;
use std::str;
use std::string::ToString;
use std::sync::mpsc::{channel, Receiver};
-use std::sync::Arc;
use itertools::Itertools;
use rustc_ast_pretty::pprust;
@@ -103,27 +102,42 @@ crate fn ensure_trailing_slash(v: &str) -> impl fmt::Display + '_ {
crate struct Context<'tcx> {
/// Current hierarchy of components leading down to what's currently being
/// rendered
- crate current: Vec,
+ current: Vec,
/// The current destination folder of where HTML artifacts should be placed.
/// This changes as the context descends into the module hierarchy.
- crate dst: PathBuf,
+ dst: PathBuf,
/// A flag, which when `true`, will render pages which redirect to the
/// real location of an item. This is used to allow external links to
/// publicly reused items to redirect to the right location.
- crate render_redirect_pages: bool,
+ render_redirect_pages: bool,
/// The map used to ensure all generated 'id=' attributes are unique.
- id_map: Rc>,
+ id_map: RefCell,
/// Tracks section IDs for `Deref` targets so they match in both the main
/// body and the sidebar.
- deref_id_map: Rc>>,
- crate shared: Arc>,
- all: Rc>,
- /// Storage for the errors produced while generating documentation so they
- /// can be printed together at the end.
- crate errors: Rc>,
- crate cache: Rc,
+ deref_id_map: RefCell>,
+ /// Shared mutable state.
+ ///
+ /// Issue for improving the situation: [#82381][]
+ ///
+ /// [#82381]: https://github.com/rust-lang/rust/issues/82381
+ shared: Rc>,
+ /// The [`Cache`] used during rendering.
+ ///
+ /// Ideally the cache would be in [`SharedContext`], but it's mutated
+ /// between when the `SharedContext` is created and when `Context`
+ /// is created, so more refactoring would be needed.
+ ///
+ /// It's immutable once in `Context`, so it's not as bad that it's not in
+ /// `SharedContext`.
+ // FIXME: move `cache` to `SharedContext`
+ cache: Rc,
}
+// `Context` is cloned a lot, so we don't want the size to grow unexpectedly.
+#[cfg(target_arch = "x86_64")]
+rustc_data_structures::static_assert_size!(Context<'_>, 152);
+
+/// Shared mutable state used in [`Context`] and elsewhere.
crate struct SharedContext<'tcx> {
crate tcx: TyCtxt<'tcx>,
/// The path to the crate root source minus the file name.
@@ -139,16 +153,16 @@ crate struct SharedContext<'tcx> {
/// The local file sources we've emitted and their respective url-paths.
crate local_sources: FxHashMap,
/// Whether the collapsed pass ran
- crate collapsed: bool,
+ collapsed: bool,
/// The base-URL of the issue tracker for when an item has been tagged with
/// an issue number.
- crate issue_tracker_base_url: Option,
+ issue_tracker_base_url: Option,
/// The directories that have already been created in this doc run. Used to reduce the number
/// of spurious `create_dir_all` calls.
- crate created_dirs: RefCell>,
+ created_dirs: RefCell>,
/// This flag indicates whether listings of modules (in the side bar and documentation itself)
/// should be ordered alphabetically or in order of appearance (in the source code).
- crate sort_modules_alphabetically: bool,
+ sort_modules_alphabetically: bool,
/// Additional CSS files to be added to the generated docs.
crate style_files: Vec,
/// Suffix to be added on resource files (if suffix is "-v2" then "light.css" becomes
@@ -161,8 +175,12 @@ crate struct SharedContext<'tcx> {
crate fs: DocFS,
/// The default edition used to parse doctests.
crate edition: Edition,
- crate codes: ErrorCodes,
+ codes: ErrorCodes,
playground: Option,
+ all: RefCell,
+ /// Storage for the errors produced while generating documentation so they
+ /// can be printed together at the end.
+ errors: Receiver,
}
impl<'tcx> Context<'tcx> {
@@ -478,6 +496,8 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> {
edition,
codes: ErrorCodes::from(unstable_features.is_nightly_build()),
playground,
+ all: RefCell::new(AllTypes::new()),
+ errors: receiver,
};
// Add the default themes to the `Vec` of stylepaths
@@ -504,20 +524,18 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> {
current: Vec::new(),
dst,
render_redirect_pages: false,
- id_map: Rc::new(RefCell::new(id_map)),
- deref_id_map: Rc::new(RefCell::new(FxHashMap::default())),
- shared: Arc::new(scx),
- all: Rc::new(RefCell::new(AllTypes::new())),
- errors: Rc::new(receiver),
+ id_map: RefCell::new(id_map),
+ deref_id_map: RefCell::new(FxHashMap::default()),
+ shared: Rc::new(scx),
cache: Rc::new(cache),
};
CURRENT_DEPTH.with(|s| s.set(0));
// Write shared runs within a flock; disable thread dispatching of IO temporarily.
- Arc::get_mut(&mut cx.shared).unwrap().fs.set_sync_only(true);
+ Rc::get_mut(&mut cx.shared).unwrap().fs.set_sync_only(true);
write_shared(&cx, &krate, index, &md_opts)?;
- Arc::get_mut(&mut cx.shared).unwrap().fs.set_sync_only(false);
+ Rc::get_mut(&mut cx.shared).unwrap().fs.set_sync_only(false);
Ok((cx, krate))
}
@@ -558,7 +576,7 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> {
} else {
String::new()
};
- let all = self.all.replace(AllTypes::new());
+ let all = self.shared.all.replace(AllTypes::new());
let v = layout::render(
&self.shared.layout,
&page,
@@ -590,8 +608,8 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> {
self.shared.fs.write(&settings_file, v.as_bytes())?;
// Flush pending errors.
- Arc::get_mut(&mut self.shared).unwrap().fs.close();
- let nb_errors = self.errors.iter().map(|err| diag.struct_err(&err).emit()).count();
+ Rc::get_mut(&mut self.shared).unwrap().fs.close();
+ let nb_errors = self.shared.errors.iter().map(|err| diag.struct_err(&err).emit()).count();
if nb_errors > 0 {
Err(Error::new(io::Error::new(io::ErrorKind::Other, "I/O error"), ""))
} else {
@@ -670,7 +688,7 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> {
self.shared.fs.write(&joint_dst, buf.as_bytes())?;
if !self.render_redirect_pages {
- self.all.borrow_mut().append(full_path(self, &item), &item_type);
+ self.shared.all.borrow_mut().append(full_path(self, &item), &item_type);
}
// If the item is a macro, redirect from the old macro URL (with !)
// to the new one (without).
@@ -1572,6 +1590,7 @@ impl Context<'_> {
};
{
+ // FIXME: remove this once `Context` is no longer cloned
self.id_map.borrow_mut().reset();
self.id_map.borrow_mut().populate(&INITIAL_IDS);
}