mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 14:55:26 +00:00
Auto merge of #75176 - jyn514:impl-link, r=GuillaumeGomez,petrochenkov
Fix intra-doc links for cross-crate re-exports of default trait methods The original fix for this was very simple: https://github.com/rust-lang/rust/pull/58972 ignored `extern_traits` because before https://github.com/rust-lang/rust/issues/65983 was fixed, they would always fail to resolve, giving spurious warnings. So the first commit just undoes that change, so extern traits are now seen by the `collect_intra_doc_links` pass. There are also some minor changes in `librustdoc/fold.rs` to avoid borrowing the `extern_traits` RefCell more than once at a time. However, that brought up a much more thorny problem. `rustc_resolve` started giving 'error: cannot find a built-in macro with name `cfg`' when documenting `libproc_macro` (I still haven't been able to reproduce on anything smaller than the full standard library). The chain of events looked like this (thanks @eddyb for the help debugging!): 0. `x.py build --stage 1` builds the standard library and creates a sysroot 1. `cargo doc` does something like `cargo check` to create `rmeta`s for all the crates (unrelated to what was built above) 2. the `cargo check`-like `libcore-*.rmeta` is loaded as a transitive dependency *and claims ownership* of builtin macros 3. `rustdoc` later tries to resolve some path in a doc link 4. suggestion logic fires and loads "extern prelude" crates by name 5. the sysroot `libcore-*.rlib` is loaded and *fails to claim ownership* of builtin macros `rustc_resolve` gives the error after step 5. However, `rustdoc` doesn't need suggestions at all - `resolve_str_path_error` completely discards the `ResolutionError`! The fix implemented in this PR is to skip the suggestion logic for `resolve_ast_path`: pass `record_used: false` and skip `lookup_import_candidates` when `record_used` isn't set. It's possible that if/when https://github.com/rust-lang/rust/issues/74207 is implemented this will need a more in-depth fix which returns a `ResolutionError` from `compile_macro`, to allow rustdoc to reuse the suggestions from rustc_resolve. However, that's a much larger change and there's no need for it yet, so I haven't implemented it here. Fixes https://github.com/rust-lang/rust/issues/73829. r? @GuillaumeGomez
This commit is contained in:
commit
db534b3ac2
@ -222,6 +222,7 @@ impl<'a> CrateLoader<'a> {
|
|||||||
let mut ret = None;
|
let mut ret = None;
|
||||||
self.cstore.iter_crate_data(|cnum, data| {
|
self.cstore.iter_crate_data(|cnum, data| {
|
||||||
if data.name() != name {
|
if data.name() != name {
|
||||||
|
tracing::trace!("{} did not match {}", data.name(), name);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -230,7 +231,10 @@ impl<'a> CrateLoader<'a> {
|
|||||||
ret = Some(cnum);
|
ret = Some(cnum);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Some(..) => return,
|
Some(hash) => {
|
||||||
|
debug!("actual hash {} did not match expected {}", hash, data.hash());
|
||||||
|
return;
|
||||||
|
}
|
||||||
None => {}
|
None => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -273,6 +277,11 @@ impl<'a> CrateLoader<'a> {
|
|||||||
.1;
|
.1;
|
||||||
if kind.matches(prev_kind) {
|
if kind.matches(prev_kind) {
|
||||||
ret = Some(cnum);
|
ret = Some(cnum);
|
||||||
|
} else {
|
||||||
|
debug!(
|
||||||
|
"failed to load existing crate {}; kind {:?} did not match prev_kind {:?}",
|
||||||
|
name, kind, prev_kind
|
||||||
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
ret
|
ret
|
||||||
|
@ -2385,8 +2385,12 @@ impl<'a> Resolver<'a> {
|
|||||||
Res::Def(DefKind::Mod, _) => true,
|
Res::Def(DefKind::Mod, _) => true,
|
||||||
_ => false,
|
_ => false,
|
||||||
};
|
};
|
||||||
let mut candidates =
|
// Don't look up import candidates if this is a speculative resolve
|
||||||
self.lookup_import_candidates(ident, TypeNS, parent_scope, is_mod);
|
let mut candidates = if record_used {
|
||||||
|
self.lookup_import_candidates(ident, TypeNS, parent_scope, is_mod)
|
||||||
|
} else {
|
||||||
|
Vec::new()
|
||||||
|
};
|
||||||
candidates.sort_by_cached_key(|c| {
|
candidates.sort_by_cached_key(|c| {
|
||||||
(c.path.segments.len(), pprust::path_to_string(&c.path))
|
(c.path.segments.len(), pprust::path_to_string(&c.path))
|
||||||
});
|
});
|
||||||
@ -3200,7 +3204,7 @@ impl<'a> Resolver<'a> {
|
|||||||
&Segment::from_path(path),
|
&Segment::from_path(path),
|
||||||
Some(ns),
|
Some(ns),
|
||||||
parent_scope,
|
parent_scope,
|
||||||
true,
|
false,
|
||||||
path.span,
|
path.span,
|
||||||
CrateLint::No,
|
CrateLint::No,
|
||||||
) {
|
) {
|
||||||
|
@ -628,7 +628,9 @@ pub fn record_extern_trait(cx: &DocContext<'_>, did: DefId) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
cx.active_extern_traits.borrow_mut().insert(did);
|
cx.active_extern_traits.borrow_mut().insert(did);
|
||||||
|
}
|
||||||
|
|
||||||
debug!("record_extern_trait: {:?}", did);
|
debug!("record_extern_trait: {:?}", did);
|
||||||
let trait_ = build_external_trait(cx, did);
|
let trait_ = build_external_trait(cx, did);
|
||||||
|
@ -439,6 +439,7 @@ pub fn run_core(
|
|||||||
resolver.borrow_mut().access(|resolver| {
|
resolver.borrow_mut().access(|resolver| {
|
||||||
sess.time("load_extern_crates", || {
|
sess.time("load_extern_crates", || {
|
||||||
for extern_name in &extern_names {
|
for extern_name in &extern_names {
|
||||||
|
debug!("loading extern crate {}", extern_name);
|
||||||
resolver
|
resolver
|
||||||
.resolve_str_path_error(
|
.resolve_str_path_error(
|
||||||
DUMMY_SP,
|
DUMMY_SP,
|
||||||
|
@ -93,15 +93,11 @@ pub trait DocFolder: Sized {
|
|||||||
c.module = c.module.take().and_then(|module| self.fold_item(module));
|
c.module = c.module.take().and_then(|module| self.fold_item(module));
|
||||||
|
|
||||||
{
|
{
|
||||||
let mut guard = c.external_traits.borrow_mut();
|
let external_traits = { std::mem::take(&mut *c.external_traits.borrow_mut()) };
|
||||||
let external_traits = std::mem::replace(&mut *guard, Default::default());
|
for (k, mut v) in external_traits {
|
||||||
*guard = external_traits
|
|
||||||
.into_iter()
|
|
||||||
.map(|(k, mut v)| {
|
|
||||||
v.items = v.items.into_iter().filter_map(|i| self.fold_item(i)).collect();
|
v.items = v.items.into_iter().filter_map(|i| self.fold_item(i)).collect();
|
||||||
(k, v)
|
c.external_traits.borrow_mut().insert(k, v);
|
||||||
})
|
}
|
||||||
.collect();
|
|
||||||
}
|
}
|
||||||
c
|
c
|
||||||
}
|
}
|
||||||
|
@ -161,6 +161,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
|
|||||||
return Some(res.map_id(|_| panic!("unexpected id")));
|
return Some(res.map_id(|_| panic!("unexpected id")));
|
||||||
}
|
}
|
||||||
if let Some(module_id) = parent_id {
|
if let Some(module_id) = parent_id {
|
||||||
|
debug!("resolving {} as a macro in the module {:?}", path_str, module_id);
|
||||||
if let Ok((_, res)) =
|
if let Ok((_, res)) =
|
||||||
resolver.resolve_str_path_error(DUMMY_SP, path_str, MacroNS, module_id)
|
resolver.resolve_str_path_error(DUMMY_SP, path_str, MacroNS, module_id)
|
||||||
{
|
{
|
||||||
@ -972,15 +973,6 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> {
|
|||||||
self.fold_item_recur(item)
|
self.fold_item_recur(item)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: if we can resolve intra-doc links from other crates, we can use the stock
|
|
||||||
// `fold_crate`, but until then we should avoid scanning `krate.external_traits` since those
|
|
||||||
// will never resolve properly
|
|
||||||
fn fold_crate(&mut self, mut c: Crate) -> Crate {
|
|
||||||
c.module = c.module.take().and_then(|module| self.fold_item(module));
|
|
||||||
|
|
||||||
c
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
// ignore-test
|
|
||||||
// ^ this is https://github.com/rust-lang/rust/issues/73829
|
|
||||||
// aux-build:traits.rs
|
// aux-build:traits.rs
|
||||||
// build-aux-docs
|
// build-aux-docs
|
||||||
// ignore-tidy-line-length
|
// ignore-tidy-line-length
|
||||||
|
Loading…
Reference in New Issue
Block a user