Skip to content

Commit 0c475a6

Browse files
committed
Update all_traits query to load more crates.
This commit updates the `all_traits` query to speculatively load all crates that have an `--extern` flag for the purpose of diagnostics.
1 parent fc4ae1d commit 0c475a6

File tree

7 files changed

+72
-17
lines changed

7 files changed

+72
-17
lines changed

src/librustc_typeck/check/method/suggest.rs

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use errors::{Applicability, DiagnosticBuilder};
99
use rustc_data_structures::sync::Lrc;
1010
use rustc::hir::{self, ExprKind, Node, QPath};
1111
use rustc::hir::def::Def;
12-
use rustc::hir::def_id::{CRATE_DEF_INDEX, LOCAL_CRATE, DefId};
12+
use rustc::hir::def_id::{CRATE_DEF_INDEX, LOCAL_CRATE, CrateNum, DefId};
1313
use rustc::hir::map as hir_map;
1414
use rustc::hir::print;
1515
use rustc::infer::type_variable::TypeVariableOrigin;
@@ -774,7 +774,28 @@ fn compute_all_traits<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Vec<DefId>
774774
_ => {}
775775
}
776776
}
777+
778+
let mut cnums: FxHashSet<CrateNum> = FxHashSet::default();
779+
780+
// Attempt to load all crates that we have `--extern` flags for, this means
781+
// we will be able to make suggestions for traits they define. Particularly useful
782+
// in Rust 2018 as there aren't `extern crate` lines that import a crate even if it isn't
783+
// otherwise used.
784+
for name in tcx.extern_prelude.keys() {
785+
let cnum = tcx.maybe_load_extern_crate(*name);
786+
debug!("compute_all_traits: (attempt load) name={:?} cnum={:?}", name, cnum);
787+
if let Some(cnum) = cnum {
788+
let _ = cnums.insert(cnum);
789+
}
790+
}
791+
792+
// Add all crates that we already know about.
777793
for &cnum in tcx.crates().iter() {
794+
let _ = cnums.insert(cnum);
795+
}
796+
797+
for cnum in cnums {
798+
debug!("compute_all_traits: cnum={:?} name={:?}", cnum, tcx.crate_name(cnum));
778799
let def_id = DefId {
779800
krate: cnum,
780801
index: CRATE_DEF_INDEX,
Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
1-
// This file is used as part of the local-path-suggestions.rs test.
1+
// This file is used as part of the local-path-suggestions.rs and
2+
// the trait-import-suggestions.rs test.
23

34
pub mod foobar {
45
pub struct Baz;
56
}
7+
8+
pub trait BazTrait {
9+
fn extern_baz(&self) { }
10+
}
11+
12+
impl BazTrait for u32 { }

src/test/ui/rust-2018/auxiliary/trait-import-suggestions.rs

Lines changed: 0 additions & 5 deletions
This file was deleted.
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// edition:2018
2+
// aux-build:baz.rs
3+
// compile-flags:--extern baz
4+
5+
// Don't use anything from baz - making suggestions from it when the only reference to it
6+
// is an `--extern` flag is what is tested by this test.
7+
8+
struct Local;
9+
10+
fn main() {
11+
let local = Local;
12+
local.extern_baz(); //~ ERROR no method named `extern_baz`
13+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
error[E0599]: no method named `extern_baz` found for type `Local` in the current scope
2+
--> $DIR/extern-trait-impl-suggestions.rs:12:11
3+
|
4+
LL | struct Local;
5+
| ------------- method `extern_baz` not found for this
6+
...
7+
LL | local.extern_baz(); //~ ERROR no method named `extern_baz`
8+
| ^^^^^^^^^^
9+
|
10+
= help: items from traits can only be used if the trait is implemented and in scope
11+
= note: the following trait defines an item `extern_baz`, perhaps you need to implement it:
12+
candidate #1: `baz::BazTrait`
13+
14+
error: aborting due to previous error
15+
16+
For more information about this error, try `rustc --explain E0599`.

src/test/ui/rust-2018/trait-import-suggestions.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
// edition:2018
2-
// aux-build:trait-import-suggestions.rs
3-
// compile-flags:--extern trait-import-suggestions
2+
// aux-build:baz.rs
3+
// compile-flags:--extern baz
4+
5+
// Don't use anything from baz - making suggestions from it when the only reference to it
6+
// is an `--extern` flag is one of the things tested by this test.
47

58
mod foo {
69
mod foobar {
@@ -26,6 +29,6 @@ mod foo {
2629
fn main() {
2730
let x: u32 = 22;
2831
x.bar(); //~ ERROR no method named `bar`
29-
x.baz(); //~ ERROR no method named `baz`
32+
x.extern_baz(); //~ ERROR no method named `extern_baz`
3033
let y = u32::from_str("33"); //~ ERROR no function or associated item named `from_str`
3134
}

src/test/ui/rust-2018/trait-import-suggestions.stderr

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error[E0599]: no method named `foobar` found for type `u32` in the current scope
2-
--> $DIR/trait-import-suggestions.rs:22:11
2+
--> $DIR/trait-import-suggestions.rs:25:11
33
|
44
LL | x.foobar(); //~ ERROR no method named `foobar`
55
| ^^^^^^
@@ -9,7 +9,7 @@ LL | x.foobar(); //~ ERROR no method named `foobar`
99
`use crate::foo::foobar::Foobar;`
1010

1111
error[E0599]: no method named `bar` found for type `u32` in the current scope
12-
--> $DIR/trait-import-suggestions.rs:28:7
12+
--> $DIR/trait-import-suggestions.rs:31:7
1313
|
1414
LL | x.bar(); //~ ERROR no method named `bar`
1515
| ^^^
@@ -20,14 +20,14 @@ help: the following trait is implemented but not in scope, perhaps add a `use` f
2020
LL | use crate::foo::Bar;
2121
|
2222

23-
error[E0599]: no method named `baz` found for type `u32` in the current scope
24-
--> $DIR/trait-import-suggestions.rs:29:7
23+
error[E0599]: no method named `extern_baz` found for type `u32` in the current scope
24+
--> $DIR/trait-import-suggestions.rs:32:7
2525
|
26-
LL | x.baz(); //~ ERROR no method named `baz`
27-
| ^^^
26+
LL | x.extern_baz(); //~ ERROR no method named `extern_baz`
27+
| ^^^^^^^^^^
2828

2929
error[E0599]: no function or associated item named `from_str` found for type `u32` in the current scope
30-
--> $DIR/trait-import-suggestions.rs:30:18
30+
--> $DIR/trait-import-suggestions.rs:33:18
3131
|
3232
LL | let y = u32::from_str("33"); //~ ERROR no function or associated item named `from_str`
3333
| -----^^^^^^^^

0 commit comments

Comments
 (0)