Skip to content

Don't share id_map and deref_id_map #82424

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 7 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 47 additions & 28 deletions src/librustdoc/html/render/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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<String>,
current: Vec<String>,
/// 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<RefCell<IdMap>>,
id_map: RefCell<IdMap>,
/// Tracks section IDs for `Deref` targets so they match in both the main
/// body and the sidebar.
deref_id_map: Rc<RefCell<FxHashMap<DefId, String>>>,
crate shared: Arc<SharedContext<'tcx>>,
all: Rc<RefCell<AllTypes>>,
/// Storage for the errors produced while generating documentation so they
/// can be printed together at the end.
crate errors: Rc<Receiver<String>>,
crate cache: Rc<Cache>,
deref_id_map: RefCell<FxHashMap<DefId, String>>,
/// Shared mutable state.
///
/// Issue for improving the situation: [#82381][]
///
/// [#82381]: https://github.com/rust-lang/rust/issues/82381
shared: Rc<SharedContext<'tcx>>,
/// 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<Cache>,
}

// `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.
Expand All @@ -139,16 +153,16 @@ crate struct SharedContext<'tcx> {
/// The local file sources we've emitted and their respective url-paths.
crate local_sources: FxHashMap<PathBuf, String>,
/// 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<String>,
issue_tracker_base_url: Option<String>,
/// 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<FxHashSet<PathBuf>>,
created_dirs: RefCell<FxHashSet<PathBuf>>,
/// 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<StylePath>,
/// Suffix to be added on resource files (if suffix is "-v2" then "light.css" becomes
Expand All @@ -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<markdown::Playground>,
all: RefCell<AllTypes>,
/// Storage for the errors produced while generating documentation so they
/// can be printed together at the end.
errors: Receiver<String>,
}

impl<'tcx> Context<'tcx> {
Expand Down Expand Up @@ -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
Expand All @@ -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))
}

Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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).
Expand Down Expand Up @@ -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);
}
Expand Down