Rollup merge of #82018 - jyn514:no-dummy-cache, r=camelid,GuillaumeGomez

Remove the dummy cache in `DocContext`; delete RenderInfo

The same information is available everywhere; the only reason the dummy
cache was needed is because it was previously stored in three different
places. This consolidates the info a bit so the cache in `DocContext` is
used throughout. As a bonus, it also completely removes `RenderInfo`.

- Return a `Cache` from `run_global_ctxt`, not `RenderInfo`
- Remove the unused `render_info` from `run_renderer`
- Remove RenderInfo altogether

Helps with https://github.com/rust-lang/rust/pull/82014. The next step is to move the `populate()` call before the `collect_intra_doc_links` pass, which currently breaks because a) lots of the cache is populated in early passes, and b) intra_doc_links itself sets some info with `register_res`. I'm working on separate PR for that to avoid making too many big changes at once.

r? `@GuillaumeGomez`
This commit is contained in:
Guillaume Gomez 2021-03-02 00:50:07 +01:00 committed by GitHub
commit b51272edfe
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 82 additions and 133 deletions

View File

@ -21,7 +21,7 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> {
debug!("get_blanket_impls({:?})", ty);
let mut impls = Vec::new();
for &trait_def_id in self.cx.tcx.all_traits(LOCAL_CRATE).iter() {
if !self.cx.renderinfo.access_levels.is_public(trait_def_id)
if !self.cx.cache.access_levels.is_public(trait_def_id)
|| self.cx.generated_synthetics.get(&(ty, trait_def_id)).is_some()
{
continue;

View File

@ -17,6 +17,7 @@
use crate::clean::{self, Attributes, GetDefId, ToSource, TypeKind};
use crate::core::DocContext;
use crate::formats::item_type::ItemType;
use super::Clean;
@ -122,7 +123,7 @@
let target_attrs = load_attrs(cx, did);
let attrs = box merge_attrs(cx, Some(parent_module), target_attrs, attrs_clone);
cx.renderinfo.inlined.insert(did);
cx.inlined.insert(did);
let what_rustc_thinks = clean::Item::from_def_id_and_parts(did, Some(name), kind, cx);
ret.push(clean::Item { attrs, ..what_rustc_thinks });
Some(ret)
@ -181,9 +182,9 @@
};
if did.is_local() {
cx.renderinfo.exact_paths.insert(did, fqn);
cx.cache.exact_paths.insert(did, fqn);
} else {
cx.renderinfo.external_paths.insert(did, (fqn, kind));
cx.cache.external_paths.insert(did, (fqn, ItemType::from(kind)));
}
}
@ -315,7 +316,7 @@ fn merge_attrs(
attrs: Option<Attrs<'_>>,
ret: &mut Vec<clean::Item>,
) {
if !cx.renderinfo.inlined.insert(did) {
if !cx.inlined.insert(did) {
return;
}
@ -327,7 +328,7 @@ fn merge_attrs(
if !did.is_local() {
if let Some(traitref) = associated_trait {
let did = traitref.def_id;
if !cx.renderinfo.access_levels.is_public(did) {
if !cx.cache.access_levels.is_public(did) {
return;
}
@ -359,7 +360,7 @@ fn merge_attrs(
// reachable in rustdoc generated documentation
if !did.is_local() {
if let Some(did) = for_.def_id() {
if !cx.renderinfo.access_levels.is_public(did) {
if !cx.cache.access_levels.is_public(did) {
return;
}

View File

@ -1304,7 +1304,7 @@ fn clean_qpath(hir_ty: &hir::Ty<'_>, cx: &mut DocContext<'_>) -> Type {
// Substitute private type aliases
if let Some(def_id) = def_id.as_local() {
let hir_id = cx.tcx.hir().local_def_id_to_hir_id(def_id);
if !cx.renderinfo.access_levels.is_exported(def_id.to_def_id()) {
if !cx.cache.access_levels.is_exported(def_id.to_def_id()) {
alias = Some(&cx.tcx.hir().expect_item(hir_id).kind);
}
}

View File

@ -50,7 +50,6 @@
#[derive(Clone, Debug)]
crate struct Crate {
crate name: Symbol,
crate version: Option<String>,
crate src: FileName,
crate module: Option<Item>,
crate externs: Vec<(CrateNum, ExternalCrate)>,

View File

@ -17,21 +17,21 @@
use rustc_span::symbol::{kw, sym, Symbol};
use std::mem;
crate fn krate(mut cx: &mut DocContext<'_>) -> Crate {
crate fn krate(cx: &mut DocContext<'_>) -> Crate {
use crate::visit_lib::LibEmbargoVisitor;
let krate = cx.tcx.hir().krate();
let module = crate::visit_ast::RustdocVisitor::new(&mut cx).visit(krate);
let module = crate::visit_ast::RustdocVisitor::new(cx).visit(krate);
cx.renderinfo.deref_trait_did = cx.tcx.lang_items().deref_trait();
cx.renderinfo.deref_mut_trait_did = cx.tcx.lang_items().deref_mut_trait();
cx.renderinfo.owned_box_did = cx.tcx.lang_items().owned_box();
cx.cache.deref_trait_did = cx.tcx.lang_items().deref_trait();
cx.cache.deref_mut_trait_did = cx.tcx.lang_items().deref_mut_trait();
cx.cache.owned_box_did = cx.tcx.lang_items().owned_box();
let mut externs = Vec::new();
for &cnum in cx.tcx.crates().iter() {
externs.push((cnum, cnum.clean(cx)));
// Analyze doc-reachability for extern items
LibEmbargoVisitor::new(&mut cx).visit_lib(cnum);
LibEmbargoVisitor::new(cx).visit_lib(cnum);
}
externs.sort_by(|&(a, _), &(b, _)| a.cmp(&b));
@ -77,7 +77,6 @@
Crate {
name,
version: None,
src,
module: Some(module),
externs,

View File

@ -4,9 +4,7 @@
use std::fmt;
use std::path::PathBuf;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_hir::def_id::DefId;
use rustc_middle::middle::privacy::AccessLevels;
use rustc_data_structures::fx::FxHashMap;
use rustc_session::config::{self, parse_crate_types_from_list, parse_externs, CrateType};
use rustc_session::config::{
build_codegen_options, build_debugging_options, get_cmd_lint_options, host_triple,
@ -268,20 +266,6 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
crate unstable_features: rustc_feature::UnstableFeatures,
}
/// Temporary storage for data obtained during `RustdocVisitor::clean()`.
/// Later on moved into `cache`.
#[derive(Default, Clone)]
crate struct RenderInfo {
crate inlined: FxHashSet<DefId>,
crate external_paths: crate::core::ExternalPaths,
crate exact_paths: FxHashMap<DefId, Vec<String>>,
crate access_levels: AccessLevels<DefId>,
crate deref_trait_did: Option<DefId>,
crate deref_mut_trait_did: Option<DefId>,
crate owned_box_did: Option<DefId>,
crate output_format: OutputFormat,
}
impl Options {
/// Parses the given command-line for options. If an error message or other early-return has
/// been printed, returns `Err` with the exit code.

View File

@ -31,15 +31,12 @@
use crate::clean;
use crate::clean::inline::build_external_trait;
use crate::clean::{AttributesExt, TraitWithExtraInfo, MAX_DEF_IDX};
use crate::config::{Options as RustdocOptions, RenderOptions};
use crate::config::{OutputFormat, RenderInfo};
use crate::config::{Options as RustdocOptions, OutputFormat, RenderOptions};
use crate::formats::cache::Cache;
use crate::passes::{self, Condition::*, ConditionalPass};
crate use rustc_session::config::{DebuggingOptions, Input, Options};
crate type ExternalPaths = FxHashMap<DefId, (Vec<String>, clean::TypeKind)>;
crate struct DocContext<'tcx> {
crate tcx: TyCtxt<'tcx>,
/// Name resolver. Used for intra-doc links.
@ -52,8 +49,6 @@
///
/// Most of this logic is copied from rustc_lint::late.
crate param_env: ParamEnv<'tcx>,
/// Later on moved into `cache`
crate renderinfo: RenderInfo,
/// Later on moved through `clean::Crate` into `cache`
crate external_traits: Rc<RefCell<FxHashMap<DefId, clean::TraitWithExtraInfo>>>,
/// Used while populating `external_traits` to ensure we don't process the same trait twice at
@ -81,8 +76,12 @@
/// See `collect_intra_doc_links::traits_implemented_by` for more details.
/// `map<module, set<trait>>`
crate module_trait_cache: RefCell<FxHashMap<DefId, FxHashSet<DefId>>>,
/// Fake empty cache used when cache is required as parameter.
/// This same cache is used throughout rustdoc, including in [`crate::html::render`].
crate cache: Cache,
/// Used by [`clean::inline`] to tell if an item has already been inlined.
crate inlined: FxHashSet<DefId>,
/// Used by `calculate_doc_coverage`.
crate output_format: OutputFormat,
}
impl<'tcx> DocContext<'tcx> {
@ -465,7 +464,7 @@ pub(crate) fn init_lints<F>(
mut manual_passes: Vec<String>,
render_options: RenderOptions,
output_format: OutputFormat,
) -> (clean::Crate, RenderInfo, RenderOptions) {
) -> (clean::Crate, RenderOptions, Cache) {
// Certain queries assume that some checks were run elsewhere
// (see https://github.com/rust-lang/rust/pull/73566#issuecomment-656954425),
// so type-check everything other than function bodies in this crate before running lints.
@ -504,17 +503,12 @@ pub(crate) fn init_lints<F>(
.collect(),
};
let mut renderinfo = RenderInfo::default();
renderinfo.access_levels = access_levels;
renderinfo.output_format = output_format;
let mut ctxt = DocContext {
tcx,
resolver,
param_env: ParamEnv::empty(),
external_traits: Default::default(),
active_extern_traits: Default::default(),
renderinfo,
ty_substs: Default::default(),
lt_substs: Default::default(),
ct_substs: Default::default(),
@ -527,9 +521,11 @@ pub(crate) fn init_lints<F>(
.cloned()
.filter(|trait_def_id| tcx.trait_is_auto(*trait_def_id))
.collect(),
render_options,
module_trait_cache: RefCell::new(FxHashMap::default()),
cache: Cache::default(),
cache: Cache::new(access_levels, render_options.document_private),
inlined: FxHashSet::default(),
output_format,
render_options,
};
// Small hack to force the Sized trait to be present.
@ -647,10 +643,16 @@ fn report_deprecated_attr(name: &str, diag: &rustc_errors::Handler) {
ctxt.sess().abort_if_errors();
let render_options = ctxt.render_options;
let mut cache = ctxt.cache;
krate = tcx.sess.time("create_format_cache", || {
cache.populate(krate, tcx, &render_options.extern_html_root_urls, &render_options.output)
});
// The main crate doc comments are always collapsed.
krate.collapsed = true;
(krate, ctxt.renderinfo, ctxt.render_options)
(krate, render_options, cache)
}
/// Due to <https://github.com/rust-lang/rust/pull/73566>,

View File

@ -11,7 +11,6 @@
use rustc_span::Symbol;
use crate::clean::{self, GetDefId};
use crate::config::RenderInfo;
use crate::fold::DocFolder;
use crate::formats::item_type::ItemType;
use crate::formats::Impl;
@ -131,44 +130,23 @@ struct CacheBuilder<'a, 'tcx> {
}
impl Cache {
crate fn from_krate<'tcx>(
render_info: RenderInfo,
document_private: bool,
crate fn new(access_levels: AccessLevels<DefId>, document_private: bool) -> Self {
Cache { access_levels, document_private, ..Cache::default() }
}
/// Populates the `Cache` with more data. The returned `Crate` will be missing some data that was
/// in `krate` due to the data being moved into the `Cache`.
crate fn populate(
&mut self,
mut krate: clean::Crate,
tcx: TyCtxt<'_>,
extern_html_root_urls: &BTreeMap<String, String>,
dst: &Path,
mut krate: clean::Crate,
tcx: TyCtxt<'tcx>,
) -> (clean::Crate, Cache) {
) -> clean::Crate {
// Crawl the crate to build various caches used for the output
let RenderInfo {
inlined: _,
external_paths,
exact_paths,
access_levels,
deref_trait_did,
deref_mut_trait_did,
owned_box_did,
..
} = render_info;
let external_paths =
external_paths.into_iter().map(|(k, (v, t))| (k, (v, ItemType::from(t)))).collect();
let mut cache = Cache {
external_paths,
exact_paths,
parent_is_trait_impl: false,
stripped_mod: false,
access_levels,
crate_version: krate.version.take(),
document_private,
traits: krate.external_traits.replace(Default::default()),
deref_trait_did,
deref_mut_trait_did,
owned_box_did,
masked_crates: mem::take(&mut krate.masked_crates),
..Cache::default()
};
debug!(?self.crate_version);
self.traits = krate.external_traits.take();
self.masked_crates = mem::take(&mut krate.masked_crates);
// Cache where all our extern crates are located
// FIXME: this part is specific to HTML so it'd be nice to remove it from the common code
@ -181,12 +159,11 @@ impl Cache {
_ => PathBuf::new(),
};
let extern_url = extern_html_root_urls.get(&*e.name.as_str()).map(|u| &**u);
cache
.extern_locations
self.extern_locations
.insert(n, (e.name, src_root, extern_location(e, extern_url, &dst)));
let did = DefId { krate: n, index: CRATE_DEF_INDEX };
cache.external_paths.insert(did, (vec![e.name.to_string()], ItemType::Module));
self.external_paths.insert(did, (vec![e.name.to_string()], ItemType::Module));
}
// Cache where all known primitives have their documentation located.
@ -195,27 +172,26 @@ impl Cache {
// reverse topological order.
for &(_, ref e) in krate.externs.iter().rev() {
for &(def_id, prim) in &e.primitives {
cache.primitive_locations.insert(prim, def_id);
self.primitive_locations.insert(prim, def_id);
}
}
for &(def_id, prim) in &krate.primitives {
cache.primitive_locations.insert(prim, def_id);
self.primitive_locations.insert(prim, def_id);
}
cache.stack.push(krate.name.to_string());
self.stack.push(krate.name.to_string());
krate = CacheBuilder { tcx, cache: &mut cache, empty_cache: Cache::default() }
.fold_crate(krate);
krate = CacheBuilder { tcx, cache: self, empty_cache: Cache::default() }.fold_crate(krate);
for (trait_did, dids, impl_) in cache.orphan_trait_impls.drain(..) {
if cache.traits.contains_key(&trait_did) {
for (trait_did, dids, impl_) in self.orphan_trait_impls.drain(..) {
if self.traits.contains_key(&trait_did) {
for did in dids {
cache.impls.entry(did).or_default().push(impl_.clone());
self.impls.entry(did).or_default().push(impl_.clone());
}
}
}
(krate, cache)
krate
}
}

View File

@ -2,7 +2,7 @@
use rustc_span::edition::Edition;
use crate::clean;
use crate::config::{RenderInfo, RenderOptions};
use crate::config::RenderOptions;
use crate::error::Error;
use crate::formats::cache::Cache;
@ -18,7 +18,6 @@
fn init(
krate: clean::Crate,
options: RenderOptions,
render_info: RenderInfo,
edition: Edition,
cache: Cache,
tcx: TyCtxt<'tcx>,
@ -49,26 +48,16 @@ fn after_krate(
crate fn run_format<'tcx, T: FormatRenderer<'tcx>>(
krate: clean::Crate,
options: RenderOptions,
render_info: RenderInfo,
cache: Cache,
diag: &rustc_errors::Handler,
edition: Edition,
tcx: TyCtxt<'tcx>,
) -> Result<(), Error> {
let (krate, cache) = tcx.sess.time("create_format_cache", || {
Cache::from_krate(
render_info.clone(),
options.document_private,
&options.extern_html_root_urls,
&options.output,
krate,
tcx,
)
});
let prof = &tcx.sess.prof;
let (mut format_renderer, mut krate) = prof
.extra_verbose_generic_activity("create_renderer", T::descr())
.run(|| T::init(krate, options, render_info, edition, cache, tcx))?;
.run(|| T::init(krate, options, edition, cache, tcx))?;
let mut item = match krate.module.take() {
Some(i) => i,

View File

@ -66,7 +66,7 @@
use serde::{Serialize, Serializer};
use crate::clean::{self, AttributesExt, GetDefId, RenderedLink, SelfTy, TypeKind};
use crate::config::{RenderInfo, RenderOptions};
use crate::config::RenderOptions;
use crate::docfs::{DocFS, PathError};
use crate::error::Error;
use crate::formats::cache::Cache;
@ -385,7 +385,6 @@ fn descr() -> &'static str {
fn init(
mut krate: clean::Crate,
options: RenderOptions,
_render_info: RenderInfo,
edition: Edition,
mut cache: Cache,
tcx: TyCtxt<'tcx>,

View File

@ -19,7 +19,7 @@
use rustdoc_json_types as types;
use crate::clean;
use crate::config::{RenderInfo, RenderOptions};
use crate::config::RenderOptions;
use crate::error::Error;
use crate::formats::cache::Cache;
use crate::formats::FormatRenderer;
@ -133,7 +133,6 @@ fn descr() -> &'static str {
fn init(
krate: clean::Crate,
options: RenderOptions,
_render_info: RenderInfo,
_edition: Edition,
cache: Cache,
tcx: TyCtxt<'tcx>,
@ -200,7 +199,7 @@ fn mod_item_out(&mut self, _item_name: &str) -> Result<(), Error> {
fn after_krate(
&mut self,
krate: &clean::Crate,
_krate: &clean::Crate,
_diag: &rustc_errors::Handler,
) -> Result<(), Error> {
debug!("Done with crate");
@ -211,7 +210,7 @@ fn after_krate(
#[allow(rustc::default_hash_types)]
let output = types::Crate {
root: types::Id(String::from("0:0")),
crate_version: krate.version.clone(),
crate_version: self.cache.crate_version.clone(),
includes_private: self.cache.document_private,
index: index.into_iter().collect(),
paths: self

View File

@ -553,12 +553,12 @@ fn wrap_return(diag: &rustc_errors::Handler, res: Result<(), String>) -> MainRes
fn run_renderer<'tcx, T: formats::FormatRenderer<'tcx>>(
krate: clean::Crate,
renderopts: config::RenderOptions,
render_info: config::RenderInfo,
cache: formats::cache::Cache,
diag: &rustc_errors::Handler,
edition: rustc_span::edition::Edition,
tcx: TyCtxt<'tcx>,
) -> MainResult {
match formats::run_format::<T>(krate, renderopts, render_info, &diag, edition, tcx) {
match formats::run_format::<T>(krate, renderopts, cache, &diag, edition, tcx) {
Ok(_) => Ok(()),
Err(e) => {
let mut msg = diag.struct_err(&format!("couldn't generate documentation: {}", e.error));
@ -627,7 +627,7 @@ fn main_options(options: config::Options) -> MainResult {
let mut global_ctxt = abort_on_err(queries.global_ctxt(), sess).peek_mut();
global_ctxt.enter(|tcx| {
let (mut krate, render_info, render_opts) = sess.time("run_global_ctxt", || {
let (krate, render_opts, mut cache) = sess.time("run_global_ctxt", || {
core::run_global_ctxt(
tcx,
resolver,
@ -639,7 +639,7 @@ fn main_options(options: config::Options) -> MainResult {
});
info!("finished with rustc");
krate.version = crate_version;
cache.crate_version = crate_version;
if show_coverage {
// if we ran coverage, bail early, we don't need to also generate docs at this point
@ -658,7 +658,7 @@ fn main_options(options: config::Options) -> MainResult {
run_renderer::<html::render::Context<'_>>(
krate,
render_opts,
render_info,
cache,
&diag,
edition,
tcx,
@ -668,7 +668,7 @@ fn main_options(options: config::Options) -> MainResult {
run_renderer::<json::JsonRenderer<'_>>(
krate,
render_opts,
render_info,
cache,
&diag,
edition,
tcx,

View File

@ -127,7 +127,7 @@ fn to_json(&self) -> String {
}
fn print_results(&self) {
let output_format = self.ctx.renderinfo.output_format;
let output_format = self.ctx.output_format;
if output_format.is_json() {
println!("{}", self.to_json());
return;

View File

@ -47,7 +47,7 @@
// FIXME(eddyb) is this `doc(hidden)` check needed?
if !cx.tcx.get_attrs(def_id).lists(sym::doc).has_word(sym::hidden) {
let impls = get_auto_trait_and_blanket_impls(cx, def_id);
new_items.extend(impls.filter(|i| cx.renderinfo.inlined.insert(i.def_id)));
new_items.extend(impls.filter(|i| cx.inlined.insert(i.def_id)));
}
});
}

View File

@ -97,7 +97,7 @@ fn add_test(&mut self, _: String, config: LangString, _: usize) {
|lint| lint.build("missing code example in this documentation").emit(),
);
}
} else if tests.found_tests > 0 && !cx.renderinfo.access_levels.is_public(item.def_id) {
} else if tests.found_tests > 0 && !cx.cache.access_levels.is_public(item.def_id) {
cx.tcx.struct_span_lint_hir(
lint::builtin::PRIVATE_DOC_TESTS,
hir_id,

View File

@ -17,13 +17,12 @@
crate fn strip_private(mut krate: clean::Crate, cx: &mut DocContext<'_>) -> clean::Crate {
// This stripper collects all *retained* nodes.
let mut retained = DefIdSet::default();
let access_levels = cx.renderinfo.access_levels.clone();
// strip all private items
{
let mut stripper = Stripper {
retained: &mut retained,
access_levels: &access_levels,
access_levels: &cx.cache.access_levels,
update_retained: true,
};
krate = ImportStripper.fold_crate(stripper.fold_crate(krate));

View File

@ -113,7 +113,7 @@ fn store_path(&mut self, did: DefId) {
assert_eq!(cur_mod_def_id, macro_parent_def_id);
cur_mod.macros.push((def, None));
}
self.cx.renderinfo.exact_paths = self.exact_paths;
self.cx.cache.exact_paths = self.exact_paths;
top_level_module
}
@ -199,7 +199,7 @@ fn inherits_doc_hidden(cx: &core::DocContext<'_>, mut node: hir::HirId) -> bool
} else {
// All items need to be handled here in case someone wishes to link
// to them with intra-doc links
self.cx.renderinfo.access_levels.map.insert(did, AccessLevel::Public);
self.cx.cache.access_levels.map.insert(did, AccessLevel::Public);
}
}
}
@ -211,7 +211,7 @@ fn inherits_doc_hidden(cx: &core::DocContext<'_>, mut node: hir::HirId) -> bool
None => return false,
};
let is_private = !self.cx.renderinfo.access_levels.is_public(res_did);
let is_private = !self.cx.cache.access_levels.is_public(res_did);
let is_hidden = inherits_doc_hidden(self.cx, res_hir_id);
// Only inline if requested or if the item would otherwise be stripped.

View File

@ -25,7 +25,7 @@ impl<'a, 'tcx> LibEmbargoVisitor<'a, 'tcx> {
crate fn new(cx: &'a mut crate::core::DocContext<'tcx>) -> LibEmbargoVisitor<'a, 'tcx> {
LibEmbargoVisitor {
tcx: cx.tcx,
access_levels: &mut cx.renderinfo.access_levels,
access_levels: &mut cx.cache.access_levels,
prev_level: Some(AccessLevel::Public),
visited_mods: FxHashSet::default(),
}

View File

@ -1,6 +1,8 @@
// edition:2018
// compile-flags: --crate-version 1.0.0
// @is nested.json "$.index[*][?(@.name=='nested')].kind" \"module\"
// @is nested.json "$.crate_version" \"1.0.0\"
// @is - "$.index[*][?(@.name=='nested')].kind" \"module\"
// @is - "$.index[*][?(@.name=='nested')].inner.is_crate" true
// @count - "$.index[*][?(@.name=='nested')].inner.items[*]" 1