about summary refs log tree commit diff
path: root/src/librustdoc/core.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/librustdoc/core.rs')
-rw-r--r--src/librustdoc/core.rs90
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(),