X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=src%2Flibrustdoc%2Fcore.rs;h=1c2d2ad626c5a6999ff3cda3d25a4bdbbb812450;hb=163b01aa140299ca5934031e5edf17cb23184941;hp=e20c84ba053f6efac8fdd74b2905d3cd4d96c85e;hpb=36a348bdc085543c4f6d3cf27b9ddd156c950e2e;p=rust.git diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index e20c84ba053..1d55fa42a3a 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -26,50 +26,48 @@ use std::mem; use std::rc::Rc; -use std::{ - cell::{Cell, RefCell}, - collections::hash_map::Entry, -}; +use std::{cell::RefCell, collections::hash_map::Entry}; use crate::clean; -use crate::clean::{AttributesExt, MAX_DEF_IDX}; -use crate::config::{Options as RustdocOptions, RenderOptions}; -use crate::config::{OutputFormat, RenderInfo}; +use crate::clean::inline::build_external_trait; +use crate::clean::{AttributesExt, TraitWithExtraInfo, MAX_DEF_IDX}; +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, clean::TypeKind)>; - crate struct DocContext<'tcx> { crate tcx: TyCtxt<'tcx>, + /// Name resolver. Used for intra-doc links. + /// + /// The `Rc>` wrapping is needed because that is what's returned by + /// [`Queries::expansion()`]. + // FIXME: see if we can get rid of this RefCell somehow crate resolver: Rc>, /// Used for normalization. /// /// Most of this logic is copied from rustc_lint::late. - crate param_env: Cell>, - /// Later on moved into `cache` - crate renderinfo: RefCell, + crate param_env: ParamEnv<'tcx>, /// Later on moved through `clean::Crate` into `cache` - crate external_traits: Rc>>, + crate external_traits: Rc>>, /// Used while populating `external_traits` to ensure we don't process the same trait twice at /// the same time. - crate active_extern_traits: RefCell>, + crate active_extern_traits: FxHashSet, // The current set of type and lifetime substitutions, // for expanding type aliases at the HIR level: /// Table `DefId` of type parameter -> substituted type - crate ty_substs: RefCell>, + crate ty_substs: FxHashMap, /// Table `DefId` of lifetime parameter -> substituted lifetime - crate lt_substs: RefCell>, + crate lt_substs: FxHashMap, /// Table `DefId` of const parameter -> substituted const - crate ct_substs: RefCell>, + crate ct_substs: FxHashMap, /// Table synthetic type parameter for `impl Trait` in argument position -> bounds - crate impl_trait_bounds: RefCell>>, - crate fake_def_ids: RefCell>, + crate impl_trait_bounds: FxHashMap>, + crate fake_def_ids: FxHashMap, /// Auto-trait or blanket impls processed so far, as `(self_ty, trait_def_id)`. // FIXME(eddyb) make this a `ty::TraitRef<'tcx>` set. - crate generated_synthetics: RefCell, DefId)>>, + crate generated_synthetics: FxHashSet<(Ty<'tcx>, DefId)>, crate auto_traits: Vec, /// The options given to rustdoc that could be relevant to a pass. crate render_options: RenderOptions, @@ -78,19 +76,23 @@ /// See `collect_intra_doc_links::traits_implemented_by` for more details. /// `map>` crate module_trait_cache: RefCell>>, - /// 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, + /// Used by `calculate_doc_coverage`. + crate output_format: OutputFormat, } impl<'tcx> DocContext<'tcx> { - crate fn sess(&self) -> &Session { + crate fn sess(&self) -> &'tcx Session { &self.tcx.sess } - crate fn with_param_env T>(&self, def_id: DefId, f: F) -> T { - let old_param_env = self.param_env.replace(self.tcx.param_env(def_id)); - let ret = f(); - self.param_env.set(old_param_env); + crate fn with_param_env T>(&mut self, def_id: DefId, f: F) -> T { + let old_param_env = mem::replace(&mut self.param_env, self.tcx.param_env(def_id)); + let ret = f(self); + self.param_env = old_param_env; ret } @@ -104,24 +106,24 @@ impl<'tcx> DocContext<'tcx> { /// Call the closure with the given parameters set as /// the substitutions for a type alias' RHS. crate fn enter_alias( - &self, + &mut self, ty_substs: FxHashMap, lt_substs: FxHashMap, ct_substs: FxHashMap, f: F, ) -> R where - F: FnOnce() -> R, + F: FnOnce(&mut Self) -> R, { let (old_tys, old_lts, old_cts) = ( - mem::replace(&mut *self.ty_substs.borrow_mut(), ty_substs), - mem::replace(&mut *self.lt_substs.borrow_mut(), lt_substs), - mem::replace(&mut *self.ct_substs.borrow_mut(), ct_substs), + mem::replace(&mut self.ty_substs, ty_substs), + mem::replace(&mut self.lt_substs, lt_substs), + mem::replace(&mut self.ct_substs, ct_substs), ); - let r = f(); - *self.ty_substs.borrow_mut() = old_tys; - *self.lt_substs.borrow_mut() = old_lts; - *self.ct_substs.borrow_mut() = old_cts; + let r = f(self); + self.ty_substs = old_tys; + self.lt_substs = old_lts; + self.ct_substs = old_cts; r } @@ -139,16 +141,14 @@ impl<'tcx> DocContext<'tcx> { /// [`RefCell`]: std::cell::RefCell /// [`Debug`]: std::fmt::Debug /// [`clean::Item`]: crate::clean::types::Item - crate fn next_def_id(&self, crate_num: CrateNum) -> DefId { - let mut fake_ids = self.fake_def_ids.borrow_mut(); - - let def_index = match fake_ids.entry(crate_num) { + crate fn next_def_id(&mut self, crate_num: CrateNum) -> DefId { + let def_index = match self.fake_def_ids.entry(crate_num) { Entry::Vacant(e) => { let num_def_idx = { let num_def_idx = if crate_num == LOCAL_CRATE { self.tcx.hir().definitions().def_path_table().num_def_ids() } else { - self.enter_resolver(|r| r.cstore().num_def_ids(crate_num)) + self.resolver.borrow_mut().access(|r| r.cstore().num_def_ids(crate_num)) }; DefIndex::from_usize(num_def_idx) @@ -464,7 +464,7 @@ pub(crate) fn init_lints( mut manual_passes: Vec, 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. @@ -503,17 +503,12 @@ pub(crate) fn init_lints( .collect(), }; - let mut renderinfo = RenderInfo::default(); - renderinfo.access_levels = access_levels; - renderinfo.output_format = output_format; - let mut ctxt = DocContext { tcx, resolver, - param_env: Cell::new(ParamEnv::empty()), + param_env: ParamEnv::empty(), external_traits: Default::default(), active_extern_traits: Default::default(), - renderinfo: RefCell::new(renderinfo), ty_substs: Default::default(), lt_substs: Default::default(), ct_substs: Default::default(), @@ -526,10 +521,25 @@ pub(crate) fn init_lints( .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. + // + // Note that in case of `#![no_core]`, the trait is not available. + if let Some(sized_trait_did) = ctxt.tcx.lang_items().sized_trait() { + let mut sized_trait = build_external_trait(&mut ctxt, sized_trait_did); + sized_trait.is_auto = true; + ctxt.external_traits.borrow_mut().insert( + sized_trait_did, + TraitWithExtraInfo { trait_: sized_trait, is_spotlight: false }, + ); + } + debug!("crate: {:?}", tcx.hir().krate()); let mut krate = tcx.sess.time("clean_crate", || clean::krate(&mut ctxt)); @@ -627,16 +637,22 @@ fn report_deprecated_attr(name: &str, diag: &rustc_errors::Handler) { }; if run { debug!("running pass {}", p.pass.name); - krate = ctxt.tcx.sess.time(p.pass.name, || (p.pass.run)(krate, &ctxt)); + krate = ctxt.tcx.sess.time(p.pass.name, || (p.pass.run)(krate, &mut ctxt)); } } 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.into_inner(), ctxt.render_options) + (krate, render_options, cache) } /// Due to ,