Skip to content

Commit

Permalink
resolve: Don't speculatively load crates if this is a speculative res…
Browse files Browse the repository at this point in the history
…olution

This avoids a rare rustdoc bug where loading `core` twice caused a
'cannot find a built-in macro' error:

1. `x.py build --stage 1` builds the standard library and creates a sysroot
2. `cargo doc` does something like `cargo check` to create `rmeta`s for all the crates (unrelated to what was built above)
3. the `cargo check`-like `libcore-*.rmeta` is loaded as a transitive dependency *and claims ownership* of builtin macros
4. `rustdoc` later tries to resolve some path in a doc link
5. suggestion logic fires and loads "extern prelude" crates by name
6. the sysroot `libcore-*.rlib` is loaded and *fails to claim ownership* of builtin macros

This fixes step 5. by not running suggestion logic if this is a
speculative resolution. Additionally, it marks `resolve_ast_path` as a
speculative resolution.
  • Loading branch information
jyn514 committed Aug 30, 2020
1 parent a1c71a1 commit 9131d23
Showing 1 changed file with 7 additions and 3 deletions.
10 changes: 7 additions & 3 deletions src/librustc_resolve/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2385,8 +2385,12 @@ impl<'a> Resolver<'a> {
Res::Def(DefKind::Mod, _) => true,
_ => false,
};
let mut candidates =
self.lookup_import_candidates(ident, TypeNS, parent_scope, is_mod);
// Don't look up import candidates if this is a speculative resolve
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| {
(c.path.segments.len(), pprust::path_to_string(&c.path))
});
Expand Down Expand Up @@ -3200,7 +3204,7 @@ impl<'a> Resolver<'a> {
&Segment::from_path(path),
Some(ns),
parent_scope,
true,
false,
path.span,
CrateLint::No,
) {
Expand Down

0 comments on commit 9131d23

Please sign in to comment.