From 51345a83aaa99d1ec1a64e09c4e3280051e9cfa2 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Mon, 1 Nov 2021 23:01:39 +0000 Subject: [PATCH] Go back to loading all external crates unconditionally This *continues* to cause regressions. This code will be unnecessary once access to the resolver happens fully before creating the tyctxt (#83761), so load all crates unconditionally for now. --- src/librustdoc/core.rs | 36 ++++++++++++++++++++++++++++++++++-- src/librustdoc/lib.rs | 3 ++- 2 files changed, 36 insertions(+), 3 deletions(-) diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index b7251e8f57151..089ffb1dc26aa 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -16,13 +16,15 @@ 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; +use rustc_span::{Span, DUMMY_SP}; use std::cell::RefCell; use std::lazy::SyncLazy; @@ -299,13 +301,43 @@ crate fn create_config( } crate fn create_resolver<'a>( + externs: config::Externs, queries: &Queries<'a>, sess: &Session, ) -> Rc> { let (krate, resolver, _) = &*abort_on_err(queries.expansion(), sess).peek(); let resolver = resolver.clone(); - crate::passes::collect_intra_doc_links::load_intra_link_crates(resolver, krate) + 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 = 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( diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 7eeb9d1fcaa55..90ada38323886 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -755,6 +755,7 @@ fn main_options(options: config::Options) -> MainResult { let default_passes = options.default_passes; let output_format = options.output_format; // FIXME: fix this clone (especially render_options) + let externs = options.externs.clone(); let manual_passes = options.manual_passes.clone(); let render_options = options.render_options.clone(); let scrape_examples_options = options.scrape_examples_options.clone(); @@ -773,7 +774,7 @@ fn main_options(options: config::Options) -> MainResult { // We need to hold on to the complete resolver, so we cause everything to be // cloned for the analysis passes to use. Suboptimal, but necessary in the // current architecture. - let resolver = core::create_resolver(queries, sess); + let resolver = core::create_resolver(externs, queries, sess); if sess.has_errors() { sess.fatal("Compilation failed, aborting rustdoc");