Do not suggest importing inaccessible items
This commit is contained in:
parent
ac8dd1b2f2
commit
65eb381dec
10 changed files with 163 additions and 119 deletions
|
@ -1700,19 +1700,27 @@ crate fn show_candidates(
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let mut accessible_path_strings: Vec<(String, &str)> = Vec::new();
|
||||||
|
let mut inaccessible_path_strings: Vec<(String, &str)> = Vec::new();
|
||||||
|
|
||||||
|
candidates.iter().for_each(|c| {
|
||||||
|
(if c.accessible { &mut accessible_path_strings } else { &mut inaccessible_path_strings })
|
||||||
|
.push((path_names_to_string(&c.path), c.descr))
|
||||||
|
});
|
||||||
|
|
||||||
// we want consistent results across executions, but candidates are produced
|
// we want consistent results across executions, but candidates are produced
|
||||||
// by iterating through a hash map, so make sure they are ordered:
|
// by iterating through a hash map, so make sure they are ordered:
|
||||||
let mut path_strings: Vec<_> =
|
for path_strings in [&mut accessible_path_strings, &mut inaccessible_path_strings] {
|
||||||
candidates.iter().map(|c| path_names_to_string(&c.path)).collect();
|
|
||||||
|
|
||||||
path_strings.sort();
|
path_strings.sort();
|
||||||
let core_path_strings =
|
let core_path_strings =
|
||||||
path_strings.drain_filter(|p| p.starts_with("core::")).collect::<Vec<String>>();
|
path_strings.drain_filter(|p| p.starts_with("core::")).collect::<Vec<String>>();
|
||||||
path_strings.extend(core_path_strings);
|
path_strings.extend(core_path_strings);
|
||||||
path_strings.dedup();
|
path_strings.dedup();
|
||||||
|
}
|
||||||
|
|
||||||
let (determiner, kind) = if candidates.len() == 1 {
|
if !accessible_path_strings.is_empty() {
|
||||||
("this", candidates[0].descr)
|
let (determiner, kind) = if accessible_path_strings.len() == 1 {
|
||||||
|
("this", accessible_path_strings[0].1)
|
||||||
} else {
|
} else {
|
||||||
("one of these", "items")
|
("one of these", "items")
|
||||||
};
|
};
|
||||||
|
@ -1721,20 +1729,43 @@ crate fn show_candidates(
|
||||||
let mut msg = format!("consider importing {} {}{}", determiner, kind, instead);
|
let mut msg = format!("consider importing {} {}{}", determiner, kind, instead);
|
||||||
|
|
||||||
if let Some(span) = use_placement_span {
|
if let Some(span) = use_placement_span {
|
||||||
for candidate in &mut path_strings {
|
for candidate in &mut accessible_path_strings {
|
||||||
// produce an additional newline to separate the new use statement
|
// produce an additional newline to separate the new use statement
|
||||||
// from the directly following item.
|
// from the directly following item.
|
||||||
let additional_newline = if found_use { "" } else { "\n" };
|
let additional_newline = if found_use { "" } else { "\n" };
|
||||||
*candidate = format!("use {};\n{}", candidate, additional_newline);
|
candidate.0 = format!("use {};\n{}", &candidate.0, additional_newline);
|
||||||
}
|
}
|
||||||
|
|
||||||
err.span_suggestions(span, &msg, path_strings.into_iter(), Applicability::Unspecified);
|
err.span_suggestions(
|
||||||
|
span,
|
||||||
|
&msg,
|
||||||
|
accessible_path_strings.into_iter().map(|a| a.0),
|
||||||
|
Applicability::Unspecified,
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
msg.push(':');
|
msg.push(':');
|
||||||
|
|
||||||
for candidate in path_strings {
|
for candidate in accessible_path_strings {
|
||||||
msg.push('\n');
|
msg.push('\n');
|
||||||
msg.push_str(&candidate);
|
msg.push_str(&candidate.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
err.note(&msg);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
assert!(!inaccessible_path_strings.is_empty());
|
||||||
|
|
||||||
|
let (determiner, kind, verb1, verb2) = if inaccessible_path_strings.len() == 1 {
|
||||||
|
("this", inaccessible_path_strings[0].1, "exists", "is")
|
||||||
|
} else {
|
||||||
|
("these", "items", "exist", "are")
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut msg = format!("{} {} {} but {} inaccessible:", determiner, kind, verb1, verb2);
|
||||||
|
|
||||||
|
for candidate in inaccessible_path_strings {
|
||||||
|
msg.push('\n');
|
||||||
|
msg.push_str(&candidate.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
err.note(&msg);
|
err.note(&msg);
|
||||||
|
|
|
@ -4,7 +4,7 @@ error[E0425]: cannot find function `f` in this scope
|
||||||
LL | f();
|
LL | f();
|
||||||
| ^ not found in this scope
|
| ^ not found in this scope
|
||||||
|
|
|
|
||||||
help: consider importing one of these items
|
help: consider importing this function
|
||||||
|
|
|
|
||||||
LL | use foo::f;
|
LL | use foo::f;
|
||||||
|
|
|
|
||||||
|
@ -37,7 +37,7 @@ LL | n!(f);
|
||||||
LL | n!(f);
|
LL | n!(f);
|
||||||
| ^ not found in this scope
|
| ^ not found in this scope
|
||||||
|
|
|
|
||||||
= note: consider importing one of these items:
|
= note: consider importing this function:
|
||||||
foo::f
|
foo::f
|
||||||
= note: this error originates in the macro `n` (in Nightly builds, run with -Z macro-backtrace for more info)
|
= note: this error originates in the macro `n` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
|
@ -50,7 +50,7 @@ LL | n!(f);
|
||||||
LL | f
|
LL | f
|
||||||
| ^ not found in this scope
|
| ^ not found in this scope
|
||||||
|
|
|
|
||||||
= note: consider importing one of these items:
|
= note: consider importing this function:
|
||||||
foo::f
|
foo::f
|
||||||
= note: this error originates in the macro `n` (in Nightly builds, run with -Z macro-backtrace for more info)
|
= note: this error originates in the macro `n` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
|
|
|
@ -4,10 +4,8 @@ error[E0425]: cannot find function `fpriv` in this scope
|
||||||
LL | fpriv();
|
LL | fpriv();
|
||||||
| ^^^^^ not found in this scope
|
| ^^^^^ not found in this scope
|
||||||
|
|
|
|
||||||
help: consider importing this function
|
= note: this function exists but is inaccessible:
|
||||||
|
|
bar::fpriv
|
||||||
LL | use bar::fpriv;
|
|
||||||
|
|
|
||||||
|
|
||||||
error[E0425]: cannot find function `epriv` in this scope
|
error[E0425]: cannot find function `epriv` in this scope
|
||||||
--> $DIR/glob-resolve1.rs:27:5
|
--> $DIR/glob-resolve1.rs:27:5
|
||||||
|
@ -15,10 +13,8 @@ error[E0425]: cannot find function `epriv` in this scope
|
||||||
LL | epriv();
|
LL | epriv();
|
||||||
| ^^^^^ not found in this scope
|
| ^^^^^ not found in this scope
|
||||||
|
|
|
|
||||||
help: consider importing this function
|
= note: this function exists but is inaccessible:
|
||||||
|
|
bar::epriv
|
||||||
LL | use bar::epriv;
|
|
||||||
|
|
|
||||||
|
|
||||||
error[E0423]: expected value, found enum `B`
|
error[E0423]: expected value, found enum `B`
|
||||||
--> $DIR/glob-resolve1.rs:28:5
|
--> $DIR/glob-resolve1.rs:28:5
|
||||||
|
@ -44,10 +40,8 @@ error[E0425]: cannot find value `C` in this scope
|
||||||
LL | C;
|
LL | C;
|
||||||
| ^ not found in this scope
|
| ^ not found in this scope
|
||||||
|
|
|
|
||||||
help: consider importing this unit struct
|
= note: this unit struct exists but is inaccessible:
|
||||||
|
|
bar::C
|
||||||
LL | use bar::C;
|
|
||||||
|
|
|
||||||
|
|
||||||
error[E0425]: cannot find function `import` in this scope
|
error[E0425]: cannot find function `import` in this scope
|
||||||
--> $DIR/glob-resolve1.rs:30:5
|
--> $DIR/glob-resolve1.rs:30:5
|
||||||
|
@ -67,16 +61,10 @@ LL | pub enum B {
|
||||||
| ---------- similarly named enum `B` defined here
|
| ---------- similarly named enum `B` defined here
|
||||||
...
|
...
|
||||||
LL | foo::<A>();
|
LL | foo::<A>();
|
||||||
| ^
|
| ^ help: an enum with a similar name exists: `B`
|
||||||
|
|
|
||||||
help: an enum with a similar name exists
|
|
||||||
|
|
|
||||||
LL | foo::<B>();
|
|
||||||
| ~
|
|
||||||
help: consider importing this enum
|
|
||||||
|
|
|
||||||
LL | use bar::A;
|
|
||||||
|
|
|
|
||||||
|
= note: this enum exists but is inaccessible:
|
||||||
|
bar::A
|
||||||
|
|
||||||
error[E0412]: cannot find type `C` in this scope
|
error[E0412]: cannot find type `C` in this scope
|
||||||
--> $DIR/glob-resolve1.rs:33:11
|
--> $DIR/glob-resolve1.rs:33:11
|
||||||
|
@ -85,16 +73,10 @@ LL | pub enum B {
|
||||||
| ---------- similarly named enum `B` defined here
|
| ---------- similarly named enum `B` defined here
|
||||||
...
|
...
|
||||||
LL | foo::<C>();
|
LL | foo::<C>();
|
||||||
| ^
|
| ^ help: an enum with a similar name exists: `B`
|
||||||
|
|
|
||||||
help: an enum with a similar name exists
|
|
||||||
|
|
|
||||||
LL | foo::<B>();
|
|
||||||
| ~
|
|
||||||
help: consider importing this struct
|
|
||||||
|
|
|
||||||
LL | use bar::C;
|
|
||||||
|
|
|
|
||||||
|
= note: this struct exists but is inaccessible:
|
||||||
|
bar::C
|
||||||
|
|
||||||
error[E0412]: cannot find type `D` in this scope
|
error[E0412]: cannot find type `D` in this scope
|
||||||
--> $DIR/glob-resolve1.rs:34:11
|
--> $DIR/glob-resolve1.rs:34:11
|
||||||
|
@ -103,16 +85,10 @@ LL | pub enum B {
|
||||||
| ---------- similarly named enum `B` defined here
|
| ---------- similarly named enum `B` defined here
|
||||||
...
|
...
|
||||||
LL | foo::<D>();
|
LL | foo::<D>();
|
||||||
| ^
|
| ^ help: an enum with a similar name exists: `B`
|
||||||
|
|
|
||||||
help: an enum with a similar name exists
|
|
||||||
|
|
|
||||||
LL | foo::<B>();
|
|
||||||
| ~
|
|
||||||
help: consider importing this type alias
|
|
||||||
|
|
|
||||||
LL | use bar::D;
|
|
||||||
|
|
|
|
||||||
|
= note: this type alias exists but is inaccessible:
|
||||||
|
bar::D
|
||||||
|
|
||||||
error: aborting due to 8 previous errors
|
error: aborting due to 8 previous errors
|
||||||
|
|
||||||
|
|
|
@ -4,10 +4,8 @@ error[E0412]: cannot find type `Bar` in this scope
|
||||||
LL | fn sub() -> Bar { 1 }
|
LL | fn sub() -> Bar { 1 }
|
||||||
| ^^^ not found in this scope
|
| ^^^ not found in this scope
|
||||||
|
|
|
|
||||||
help: consider importing this type alias
|
= note: this type alias exists but is inaccessible:
|
||||||
|
|
a::b::Bar
|
||||||
LL | use a::b::Bar;
|
|
||||||
|
|
|
||||||
|
|
||||||
error[E0423]: expected function, found module `foo`
|
error[E0423]: expected function, found module `foo`
|
||||||
--> $DIR/issue-4366-2.rs:25:5
|
--> $DIR/issue-4366-2.rs:25:5
|
||||||
|
|
|
@ -16,10 +16,8 @@ error[E0425]: cannot find function, tuple struct or tuple variant `Bx` in this s
|
||||||
LL | Bx(());
|
LL | Bx(());
|
||||||
| ^^ not found in this scope
|
| ^^ not found in this scope
|
||||||
|
|
|
|
||||||
help: consider importing this tuple struct
|
= note: this tuple struct exists but is inaccessible:
|
||||||
|
|
foo::Bx
|
||||||
LL | use foo::Bx;
|
|
||||||
|
|
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
|
35
src/test/ui/resolve/issue-88472.rs
Normal file
35
src/test/ui/resolve/issue-88472.rs
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
// Regression test for #88472, where a suggestion was issued to
|
||||||
|
// import an inaccessible struct.
|
||||||
|
|
||||||
|
#![warn(unused_imports)]
|
||||||
|
//~^ NOTE: the lint level is defined here
|
||||||
|
|
||||||
|
mod a {
|
||||||
|
struct Foo;
|
||||||
|
}
|
||||||
|
|
||||||
|
mod b {
|
||||||
|
use crate::a::*;
|
||||||
|
//~^ WARNING: unused import
|
||||||
|
type Bar = Foo;
|
||||||
|
//~^ ERROR: cannot find type `Foo` in this scope [E0412]
|
||||||
|
//~| NOTE: not found in this scope
|
||||||
|
//~| NOTE: this struct exists but is inaccessible
|
||||||
|
}
|
||||||
|
|
||||||
|
mod c {
|
||||||
|
enum Eee {}
|
||||||
|
|
||||||
|
mod d {
|
||||||
|
enum Eee {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mod e {
|
||||||
|
type Baz = Eee;
|
||||||
|
//~^ ERROR: cannot find type `Eee` in this scope [E0412]
|
||||||
|
//~| NOTE: not found in this scope
|
||||||
|
//~| NOTE: these items exist but are inaccessible
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
34
src/test/ui/resolve/issue-88472.stderr
Normal file
34
src/test/ui/resolve/issue-88472.stderr
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
error[E0412]: cannot find type `Foo` in this scope
|
||||||
|
--> $DIR/issue-88472.rs:14:16
|
||||||
|
|
|
||||||
|
LL | type Bar = Foo;
|
||||||
|
| ^^^ not found in this scope
|
||||||
|
|
|
||||||
|
= note: this struct exists but is inaccessible:
|
||||||
|
a::Foo
|
||||||
|
|
||||||
|
error[E0412]: cannot find type `Eee` in this scope
|
||||||
|
--> $DIR/issue-88472.rs:29:16
|
||||||
|
|
|
||||||
|
LL | type Baz = Eee;
|
||||||
|
| ^^^ not found in this scope
|
||||||
|
|
|
||||||
|
= note: these items exist but are inaccessible:
|
||||||
|
c::Eee
|
||||||
|
c::d::Eee
|
||||||
|
|
||||||
|
warning: unused import: `crate::a::*`
|
||||||
|
--> $DIR/issue-88472.rs:12:9
|
||||||
|
|
|
||||||
|
LL | use crate::a::*;
|
||||||
|
| ^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
note: the lint level is defined here
|
||||||
|
--> $DIR/issue-88472.rs:4:9
|
||||||
|
|
|
||||||
|
LL | #![warn(unused_imports)]
|
||||||
|
| ^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors; 1 warning emitted
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0412`.
|
|
@ -169,16 +169,10 @@ LL | pub enum E {
|
||||||
| ---------- similarly named enum `E` defined here
|
| ---------- similarly named enum `E` defined here
|
||||||
...
|
...
|
||||||
LL | let _: Z = m::n::Z;
|
LL | let _: Z = m::n::Z;
|
||||||
| ^
|
| ^ help: an enum with a similar name exists: `E`
|
||||||
|
|
|
||||||
help: an enum with a similar name exists
|
|
||||||
|
|
|
||||||
LL | let _: E = m::n::Z;
|
|
||||||
| ~
|
|
||||||
help: consider importing this enum
|
|
||||||
|
|
|
||||||
LL | use m::Z;
|
|
||||||
|
|
|
|
||||||
|
= note: this enum exists but is inaccessible:
|
||||||
|
m::Z
|
||||||
|
|
||||||
error[E0423]: expected value, found enum `m::n::Z`
|
error[E0423]: expected value, found enum `m::n::Z`
|
||||||
--> $DIR/privacy-enum-ctor.rs:57:16
|
--> $DIR/privacy-enum-ctor.rs:57:16
|
||||||
|
@ -215,16 +209,10 @@ LL | pub enum E {
|
||||||
| ---------- similarly named enum `E` defined here
|
| ---------- similarly named enum `E` defined here
|
||||||
...
|
...
|
||||||
LL | let _: Z = m::n::Z::Fn;
|
LL | let _: Z = m::n::Z::Fn;
|
||||||
| ^
|
| ^ help: an enum with a similar name exists: `E`
|
||||||
|
|
|
||||||
help: an enum with a similar name exists
|
|
||||||
|
|
|
||||||
LL | let _: E = m::n::Z::Fn;
|
|
||||||
| ~
|
|
||||||
help: consider importing this enum
|
|
||||||
|
|
|
||||||
LL | use m::Z;
|
|
||||||
|
|
|
|
||||||
|
= note: this enum exists but is inaccessible:
|
||||||
|
m::Z
|
||||||
|
|
||||||
error[E0412]: cannot find type `Z` in this scope
|
error[E0412]: cannot find type `Z` in this scope
|
||||||
--> $DIR/privacy-enum-ctor.rs:64:12
|
--> $DIR/privacy-enum-ctor.rs:64:12
|
||||||
|
@ -233,16 +221,10 @@ LL | pub enum E {
|
||||||
| ---------- similarly named enum `E` defined here
|
| ---------- similarly named enum `E` defined here
|
||||||
...
|
...
|
||||||
LL | let _: Z = m::n::Z::Struct;
|
LL | let _: Z = m::n::Z::Struct;
|
||||||
| ^
|
| ^ help: an enum with a similar name exists: `E`
|
||||||
|
|
|
||||||
help: an enum with a similar name exists
|
|
||||||
|
|
|
||||||
LL | let _: E = m::n::Z::Struct;
|
|
||||||
| ~
|
|
||||||
help: consider importing this enum
|
|
||||||
|
|
|
||||||
LL | use m::Z;
|
|
||||||
|
|
|
|
||||||
|
= note: this enum exists but is inaccessible:
|
||||||
|
m::Z
|
||||||
|
|
||||||
error[E0423]: expected value, found struct variant `m::n::Z::Struct`
|
error[E0423]: expected value, found struct variant `m::n::Z::Struct`
|
||||||
--> $DIR/privacy-enum-ctor.rs:64:16
|
--> $DIR/privacy-enum-ctor.rs:64:16
|
||||||
|
@ -262,16 +244,10 @@ LL | pub enum E {
|
||||||
| ---------- similarly named enum `E` defined here
|
| ---------- similarly named enum `E` defined here
|
||||||
...
|
...
|
||||||
LL | let _: Z = m::n::Z::Unit {};
|
LL | let _: Z = m::n::Z::Unit {};
|
||||||
| ^
|
| ^ help: an enum with a similar name exists: `E`
|
||||||
|
|
|
||||||
help: an enum with a similar name exists
|
|
||||||
|
|
|
||||||
LL | let _: E = m::n::Z::Unit {};
|
|
||||||
| ~
|
|
||||||
help: consider importing this enum
|
|
||||||
|
|
|
||||||
LL | use m::Z;
|
|
||||||
|
|
|
|
||||||
|
= note: this enum exists but is inaccessible:
|
||||||
|
m::Z
|
||||||
|
|
||||||
error[E0603]: enum `Z` is private
|
error[E0603]: enum `Z` is private
|
||||||
--> $DIR/privacy-enum-ctor.rs:57:22
|
--> $DIR/privacy-enum-ctor.rs:57:22
|
||||||
|
|
|
@ -33,10 +33,8 @@ error[E0423]: expected value, found struct `xcrate::S`
|
||||||
LL | xcrate::S;
|
LL | xcrate::S;
|
||||||
| ^^^^^^^^^ constructor is not visible here due to private fields
|
| ^^^^^^^^^ constructor is not visible here due to private fields
|
||||||
|
|
|
|
||||||
help: consider importing this tuple struct instead
|
= note: this tuple struct exists but is inaccessible:
|
||||||
|
|
m::S
|
||||||
LL | use m::S;
|
|
||||||
|
|
|
||||||
|
|
||||||
error[E0603]: tuple struct constructor `Z` is private
|
error[E0603]: tuple struct constructor `Z` is private
|
||||||
--> $DIR/privacy-struct-ctor.rs:18:12
|
--> $DIR/privacy-struct-ctor.rs:18:12
|
||||||
|
|
|
@ -66,10 +66,8 @@ error[E0531]: cannot find unit struct, unit variant or constant `Self` in this s
|
||||||
LL | mut Self => (),
|
LL | mut Self => (),
|
||||||
| ^^^^ not found in this scope
|
| ^^^^ not found in this scope
|
||||||
|
|
|
|
||||||
help: consider importing this unit struct
|
= note: this unit struct exists but is inaccessible:
|
||||||
|
|
foo::Self
|
||||||
LL | use foo::Self;
|
|
||||||
|
|
|
||||||
|
|
||||||
error[E0392]: parameter `'Self` is never used
|
error[E0392]: parameter `'Self` is never used
|
||||||
--> $DIR/self_type_keyword.rs:6:12
|
--> $DIR/self_type_keyword.rs:6:12
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue