about summary refs log tree commit diff
path: root/src/librustc_metadata
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2020-08-30 13:16:38 +0000
committerbors <bors@rust-lang.org>2020-08-30 13:16:38 +0000
commitdb534b3ac286cf45688c3bbae6aa6e77439e52d2 (patch)
treef9faa1856eb502189c86a1513847e754105cf42a /src/librustc_metadata
parentb1d092c15942ab2e59152dde6f1af77e888473c8 (diff)
parent9131d23cc0fb5461050bc19e40a3858b61487069 (diff)
downloadrust-db534b3ac286cf45688c3bbae6aa6e77439e52d2.tar.gz
rust-db534b3ac286cf45688c3bbae6aa6e77439e52d2.zip
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
Diffstat (limited to 'src/librustc_metadata')
-rw-r--r--src/librustc_metadata/creader.rs11
1 files changed, 10 insertions, 1 deletions
diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs
index f8446d83d2b..7562da6d782 100644
--- a/src/librustc_metadata/creader.rs
+++ b/src/librustc_metadata/creader.rs
@@ -222,6 +222,7 @@ impl<'a> CrateLoader<'a> {
         let mut ret = None;
         self.cstore.iter_crate_data(|cnum, data| {
             if data.name() != name {
+                tracing::trace!("{} did not match {}", data.name(), name);
                 return;
             }
 
@@ -230,7 +231,10 @@ impl<'a> CrateLoader<'a> {
                     ret = Some(cnum);
                     return;
                 }
-                Some(..) => return,
+                Some(hash) => {
+                    debug!("actual hash {} did not match expected {}", hash, data.hash());
+                    return;
+                }
                 None => {}
             }
 
@@ -273,6 +277,11 @@ impl<'a> CrateLoader<'a> {
                 .1;
             if kind.matches(prev_kind) {
                 ret = Some(cnum);
+            } else {
+                debug!(
+                    "failed to load existing crate {}; kind {:?} did not match prev_kind {:?}",
+                    name, kind, prev_kind
+                );
             }
         });
         ret