Skip to content

Commit b7654a3

Browse files
Rollup merge of #85749 - GuillaumeGomez:revert-smart-extern-crate-load, r=jyn514
Revert "Don't load all extern crates unconditionally" Fixes #84738. This reverts #83738. For the "smart" load of external crates, we need to be able to access their items in order to check their doc comments, which seems, if not impossible, quite complicated using only the AST. For some context, I first tried to extend the `IntraLinkCrateLoader` visitor by adding `visit_foreign_item`. Unfortunately, it never enters into this call, so definitely not the right place... I then added `visit_use_tree` to then check all the imports outside with something like this: ```rust let mut loader = crate::passes::collect_intra_doc_links::IntraLinkCrateLoader::new(resolver); ast::visit::walk_crate(&mut loader, krate); let mut items = Vec::new(); for import in &loader.imports_to_check { if let Some(item) = krate.items.iter().find(|i| i.id == *import) { items.push(item); } } for item in items { ast::visit::walk_item(&mut item); for attr in &item.attrs { loader.check_attribute(attr); } } ``` This was, of course, a failure. We find the items without problems, but we still can't go into the external crate to check its items' attributes. Finally, `@jyn514` suggested to look into the [`CrateLoader`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_metadata/creader/struct.CrateLoader.html), but it only seems to provide metadata (I went through [`CStore`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_metadata/creader/struct.CStore.html) and [`CrateMetadata`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_metadata/rmeta/decoder/struct.CrateMetadata.html)). I think we are too limited here (with AST only) to be able to determine the crates we actually need to import, but it's very likely that I missed something. Maybe `@petrochenkov` or `@Aaron1011` have an idea? So until we find a way to make it work completely, we need to revert it to fix the ICE. Once merged, we'll need to re-open #68427. r? `@jyn514`
2 parents 1aa6c7c + 5f0c54d commit b7654a3

File tree

9 files changed

+49
-98
lines changed

9 files changed

+49
-98
lines changed

src/librustdoc/core.rs

+34-9
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
use rustc_ast as ast;
21
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
32
use rustc_data_structures::sync::{self, Lrc};
43
use rustc_driver::abort_on_err;
54
use rustc_errors::emitter::{Emitter, EmitterWriter};
65
use rustc_errors::json::JsonEmitter;
76
use rustc_feature::UnstableFeatures;
7+
use rustc_hir::def::Namespace::TypeNS;
88
use rustc_hir::def::Res;
9-
use rustc_hir::def_id::{DefId, LocalDefId};
9+
use rustc_hir::def_id::{DefId, LocalDefId, CRATE_DEF_INDEX};
1010
use rustc_hir::HirId;
1111
use rustc_hir::{
1212
intravisit::{self, NestedVisitorMap, Visitor},
@@ -23,7 +23,7 @@ use rustc_session::DiagnosticOutput;
2323
use rustc_session::Session;
2424
use rustc_span::source_map;
2525
use rustc_span::symbol::sym;
26-
use rustc_span::Span;
26+
use rustc_span::{Span, DUMMY_SP};
2727

2828
use std::cell::RefCell;
2929
use std::mem;
@@ -300,16 +300,41 @@ crate fn create_config(
300300
}
301301

302302
crate fn create_resolver<'a>(
303+
externs: config::Externs,
303304
queries: &Queries<'a>,
304305
sess: &Session,
305306
) -> Rc<RefCell<interface::BoxedResolver>> {
306-
let (krate, resolver, _) = &*abort_on_err(queries.expansion(), sess).peek();
307-
let resolver = resolver.clone();
308-
309-
let mut loader = crate::passes::collect_intra_doc_links::IntraLinkCrateLoader::new(resolver);
310-
ast::visit::walk_crate(&mut loader, krate);
307+
let extern_names: Vec<String> = externs
308+
.iter()
309+
.filter(|(_, entry)| entry.add_prelude)
310+
.map(|(name, _)| name)
311+
.cloned()
312+
.collect();
313+
314+
let (_, resolver, _) = &*abort_on_err(queries.expansion(), sess).peek();
315+
316+
// Before we actually clone it, let's force all the extern'd crates to
317+
// actually be loaded, just in case they're only referred to inside
318+
// intra-doc links
319+
resolver.borrow_mut().access(|resolver| {
320+
sess.time("load_extern_crates", || {
321+
for extern_name in &extern_names {
322+
debug!("loading extern crate {}", extern_name);
323+
if let Err(()) = resolver
324+
.resolve_str_path_error(
325+
DUMMY_SP,
326+
extern_name,
327+
TypeNS,
328+
LocalDefId { local_def_index: CRATE_DEF_INDEX }.to_def_id(),
329+
) {
330+
warn!("unable to resolve external crate {} (do you have an unused `--extern` crate?)", extern_name)
331+
}
332+
}
333+
});
334+
});
311335

312-
loader.resolver
336+
// Now we're good to clone the resolver because everything should be loaded
337+
resolver.clone()
313338
}
314339

315340
crate fn run_global_ctxt(

src/librustdoc/lib.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ extern crate tracing;
3131
// Dependencies listed in Cargo.toml do not need `extern crate`.
3232

3333
extern crate rustc_ast;
34-
extern crate rustc_ast_lowering;
3534
extern crate rustc_ast_pretty;
3635
extern crate rustc_attr;
3736
extern crate rustc_data_structures;
@@ -714,6 +713,7 @@ fn main_options(options: config::Options) -> MainResult {
714713
let default_passes = options.default_passes;
715714
let output_format = options.output_format;
716715
// FIXME: fix this clone (especially render_options)
716+
let externs = options.externs.clone();
717717
let manual_passes = options.manual_passes.clone();
718718
let render_options = options.render_options.clone();
719719
let config = core::create_config(options);
@@ -731,7 +731,7 @@ fn main_options(options: config::Options) -> MainResult {
731731
// We need to hold on to the complete resolver, so we cause everything to be
732732
// cloned for the analysis passes to use. Suboptimal, but necessary in the
733733
// current architecture.
734-
let resolver = core::create_resolver(queries, &sess);
734+
let resolver = core::create_resolver(externs, queries, &sess);
735735

736736
if sess.has_errors() {
737737
sess.fatal("Compilation failed, aborting rustdoc");

src/librustdoc/passes/collect_intra_doc_links.rs

-3
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,6 @@ use crate::html::markdown::{markdown_links, MarkdownLink};
3737
use crate::lint::{BROKEN_INTRA_DOC_LINKS, PRIVATE_INTRA_DOC_LINKS};
3838
use crate::passes::Pass;
3939

40-
mod early;
41-
crate use early::IntraLinkCrateLoader;
42-
4340
crate const COLLECT_INTRA_DOC_LINKS: Pass = Pass {
4441
name: "collect-intra-doc-links",
4542
run: collect_intra_doc_links,

src/librustdoc/passes/collect_intra_doc_links/early.rs

-63
This file was deleted.

src/librustdoc/passes/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ crate use self::unindent_comments::UNINDENT_COMMENTS;
3030
mod propagate_doc_cfg;
3131
crate use self::propagate_doc_cfg::PROPAGATE_DOC_CFG;
3232

33-
crate mod collect_intra_doc_links;
33+
mod collect_intra_doc_links;
3434
crate use self::collect_intra_doc_links::COLLECT_INTRA_DOC_LINKS;
3535

3636
mod doc_test_lints;

src/test/rustdoc-ui/auxiliary/panic-item.rs

-17
This file was deleted.

src/test/rustdoc-ui/unused-extern-crate.rs

-3
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
/// This will be referred to by the test docstring
2+
pub struct Something;

src/test/rustdoc/issue-66159.rs

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// aux-crate:priv:issue_66159_1=issue-66159-1.rs
2+
// compile-flags:-Z unstable-options
3+
4+
// The issue was an ICE which meant that we never actually generated the docs
5+
// so if we have generated the docs, we're okay.
6+
// Since we don't generate the docs for the auxiliary files, we can't actually
7+
// verify that the struct is linked correctly.
8+
9+
// @has issue_66159/index.html
10+
//! [issue_66159_1::Something]

0 commit comments

Comments
 (0)