diff options
Diffstat (limited to 'src/librustdoc/core.rs')
| -rw-r--r-- | src/librustdoc/core.rs | 90 | 
1 files changed, 34 insertions, 56 deletions
| diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 32b66278bf4..22f59d39799 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -1,30 +1,23 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::sync::{self, Lrc}; -use rustc_driver::abort_on_err; use rustc_errors::emitter::{Emitter, EmitterWriter}; use rustc_errors::json::JsonEmitter; use rustc_feature::UnstableFeatures; use rustc_hir::def::Res; use rustc_hir::def_id::{DefId, LocalDefId}; -use rustc_hir::HirId; -use rustc_hir::{ - intravisit::{self, NestedVisitorMap, Visitor}, - Path, -}; -use rustc_interface::{interface, Queries}; +use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor}; +use rustc_hir::{HirId, Path}; +use rustc_interface::interface; use rustc_middle::hir::map::Map; use rustc_middle::middle::privacy::AccessLevels; use rustc_middle::ty::{ParamEnv, Ty, TyCtxt}; use rustc_resolve as resolve; -use rustc_resolve::Namespace::TypeNS; use rustc_session::config::{self, CrateType, ErrorOutputType}; use rustc_session::lint; use rustc_session::DiagnosticOutput; use rustc_session::Session; -use rustc_span::def_id::CRATE_DEF_INDEX; -use rustc_span::source_map; use rustc_span::symbol::sym; -use rustc_span::{Span, DUMMY_SP}; +use rustc_span::{source_map, Span}; use std::cell::RefCell; use std::lazy::SyncLazy; @@ -39,14 +32,20 @@ use crate::passes::{self, Condition::*}; crate use rustc_session::config::{DebuggingOptions, Input, Options}; +crate struct ResolverCaches { + pub all_traits: Option<Vec<DefId>>, + pub all_trait_impls: Option<Vec<DefId>>, +} + crate struct DocContext<'tcx> { crate tcx: TyCtxt<'tcx>, /// Name resolver. Used for intra-doc links. /// /// The `Rc<RefCell<...>>` wrapping is needed because that is what's returned by - /// [`Queries::expansion()`]. + /// [`rustc_interface::Queries::expansion()`]. // FIXME: see if we can get rid of this RefCell somehow crate resolver: Rc<RefCell<interface::BoxedResolver>>, + crate resolver_caches: ResolverCaches, /// Used for normalization. /// /// Most of this logic is copied from rustc_lint::late. @@ -123,6 +122,18 @@ impl<'tcx> DocContext<'tcx> { _ => None, } } + + crate fn with_all_traits(&mut self, f: impl FnOnce(&mut Self, &[DefId])) { + let all_traits = self.resolver_caches.all_traits.take(); + f(self, all_traits.as_ref().expect("`all_traits` are already borrowed")); + self.resolver_caches.all_traits = all_traits; + } + + crate fn with_all_trait_impls(&mut self, f: impl FnOnce(&mut Self, &[DefId])) { + let all_trait_impls = self.resolver_caches.all_trait_impls.take(); + f(self, all_trait_impls.as_ref().expect("`all_trait_impls` are already borrowed")); + self.resolver_caches.all_trait_impls = all_trait_impls; + } } /// Creates a new diagnostic `Handler` that can be used to emit warnings and errors. @@ -284,49 +295,10 @@ crate fn create_config( } } -crate fn create_resolver<'a>( - externs: config::Externs, - queries: &Queries<'a>, - sess: &Session, -) -> Rc<RefCell<interface::BoxedResolver>> { - let (krate, resolver, _) = &*abort_on_err(queries.expansion(), sess).peek(); - let resolver = resolver.clone(); - - let resolver = crate::passes::collect_intra_doc_links::load_intra_link_crates(resolver, krate); - - // FIXME: somehow rustdoc is still missing crates even though we loaded all - // the known necessary crates. Load them all unconditionally until we find a way to fix this. - // DO NOT REMOVE THIS without first testing on the reproducer in - // https://github.com/jyn514/objr/commit/edcee7b8124abf0e4c63873e8422ff81beb11ebb - let extern_names: Vec<String> = externs - .iter() - .filter(|(_, entry)| entry.add_prelude) - .map(|(name, _)| name) - .cloned() - .collect(); - resolver.borrow_mut().access(|resolver| { - sess.time("load_extern_crates", || { - for extern_name in &extern_names { - debug!("loading extern crate {}", extern_name); - if let Err(()) = resolver - .resolve_str_path_error( - DUMMY_SP, - extern_name, - TypeNS, - LocalDefId { local_def_index: CRATE_DEF_INDEX }.to_def_id(), - ) { - warn!("unable to resolve external crate {} (do you have an unused `--extern` crate?)", extern_name) - } - } - }); - }); - - resolver -} - crate fn run_global_ctxt( tcx: TyCtxt<'_>, resolver: Rc<RefCell<interface::BoxedResolver>>, + resolver_caches: ResolverCaches, show_coverage: bool, render_options: RenderOptions, output_format: OutputFormat, @@ -355,6 +327,14 @@ crate fn run_global_ctxt( }); rustc_passes::stability::check_unused_or_stable_features(tcx); + let auto_traits = resolver_caches + .all_traits + .as_ref() + .expect("`all_traits` are already borrowed") + .iter() + .copied() + .filter(|&trait_def_id| tcx.trait_is_auto(trait_def_id)) + .collect(); let access_levels = AccessLevels { map: tcx.privacy_access_levels(()).map.iter().map(|(k, v)| (k.to_def_id(), *v)).collect(), }; @@ -362,16 +342,14 @@ crate fn run_global_ctxt( let mut ctxt = DocContext { tcx, resolver, + resolver_caches, param_env: ParamEnv::empty(), external_traits: Default::default(), active_extern_traits: Default::default(), substs: Default::default(), impl_trait_bounds: Default::default(), generated_synthetics: Default::default(), - auto_traits: tcx - .all_traits() - .filter(|&trait_def_id| tcx.trait_is_auto(trait_def_id)) - .collect(), + auto_traits, module_trait_cache: FxHashMap::default(), cache: Cache::new(access_levels, render_options.document_private), inlined: FxHashSet::default(), | 
