mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-26 05:44:26 +00:00
Improve diagnostics for inaccessible items
This commit is contained in:
parent
65eb381dec
commit
750018e16e
@ -949,7 +949,15 @@ impl<'a> Resolver<'a> {
|
||||
|
||||
let import_suggestions =
|
||||
self.lookup_import_candidates(ident, Namespace::MacroNS, parent_scope, is_expected);
|
||||
show_candidates(err, None, &import_suggestions, false, true);
|
||||
show_candidates(
|
||||
&self.definitions,
|
||||
self.session,
|
||||
err,
|
||||
None,
|
||||
&import_suggestions,
|
||||
false,
|
||||
true,
|
||||
);
|
||||
|
||||
if macro_kind == MacroKind::Derive && (ident.name == sym::Send || ident.name == sym::Sync) {
|
||||
let msg = format!("unsafe traits like `{}` should be implemented explicitly", ident);
|
||||
@ -1689,6 +1697,8 @@ fn find_span_immediately_after_crate_name(
|
||||
/// entities with that name in all crates. This method allows outputting the
|
||||
/// results of this search in a programmer-friendly way
|
||||
crate fn show_candidates(
|
||||
definitions: &rustc_hir::definitions::Definitions,
|
||||
session: &Session,
|
||||
err: &mut DiagnosticBuilder<'_>,
|
||||
// This is `None` if all placement locations are inside expansions
|
||||
use_placement_span: Option<Span>,
|
||||
@ -1700,22 +1710,22 @@ crate fn show_candidates(
|
||||
return;
|
||||
}
|
||||
|
||||
let mut accessible_path_strings: Vec<(String, &str)> = Vec::new();
|
||||
let mut inaccessible_path_strings: Vec<(String, &str)> = Vec::new();
|
||||
let mut accessible_path_strings: Vec<(String, &str, Option<DefId>)> = Vec::new();
|
||||
let mut inaccessible_path_strings: Vec<(String, &str, Option<DefId>)> = 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))
|
||||
.push((path_names_to_string(&c.path), c.descr, c.did))
|
||||
});
|
||||
|
||||
// we want consistent results across executions, but candidates are produced
|
||||
// by iterating through a hash map, so make sure they are ordered:
|
||||
for path_strings in [&mut accessible_path_strings, &mut inaccessible_path_strings] {
|
||||
path_strings.sort();
|
||||
path_strings.sort_by(|a, b| a.0.cmp(&b.0));
|
||||
let core_path_strings =
|
||||
path_strings.drain_filter(|p| p.starts_with("core::")).collect::<Vec<String>>();
|
||||
path_strings.drain_filter(|p| p.0.starts_with("core::")).collect::<Vec<_>>();
|
||||
path_strings.extend(core_path_strings);
|
||||
path_strings.dedup();
|
||||
path_strings.dedup_by(|a, b| a.0 == b.0);
|
||||
}
|
||||
|
||||
if !accessible_path_strings.is_empty() {
|
||||
@ -1755,19 +1765,56 @@ crate fn show_candidates(
|
||||
} 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")
|
||||
if inaccessible_path_strings.len() == 1 {
|
||||
let (name, descr, def_id) = &inaccessible_path_strings[0];
|
||||
let msg = format!("{} `{}` exists but is inaccessible", descr, name);
|
||||
|
||||
if let Some(local_def_id) = def_id.and_then(|did| did.as_local()) {
|
||||
let span = definitions.def_span(local_def_id);
|
||||
let span = session.source_map().guess_head_span(span);
|
||||
let mut multi_span = MultiSpan::from_span(span);
|
||||
multi_span.push_span_label(span, "not accessible".to_string());
|
||||
err.span_note(multi_span, &msg);
|
||||
} else {
|
||||
err.note(&msg);
|
||||
}
|
||||
} else {
|
||||
("these", "items", "exist", "are")
|
||||
};
|
||||
let (_, descr_first, _) = &inaccessible_path_strings[0];
|
||||
let descr = if inaccessible_path_strings
|
||||
.iter()
|
||||
.skip(1)
|
||||
.all(|(_, descr, _)| descr == descr_first)
|
||||
{
|
||||
format!("{}", descr_first)
|
||||
} else {
|
||||
"item".to_string()
|
||||
};
|
||||
|
||||
let mut msg = format!("{} {} {} but {} inaccessible:", determiner, kind, verb1, verb2);
|
||||
let mut msg = format!("these {}s exist but are inaccessible", descr);
|
||||
let mut has_colon = false;
|
||||
|
||||
for candidate in inaccessible_path_strings {
|
||||
msg.push('\n');
|
||||
msg.push_str(&candidate.0);
|
||||
let mut spans = Vec::new();
|
||||
for (name, _, def_id) in &inaccessible_path_strings {
|
||||
if let Some(local_def_id) = def_id.and_then(|did| did.as_local()) {
|
||||
let span = definitions.def_span(local_def_id);
|
||||
let span = session.source_map().guess_head_span(span);
|
||||
spans.push((name, span));
|
||||
} else {
|
||||
if !has_colon {
|
||||
msg.push(':');
|
||||
has_colon = true;
|
||||
}
|
||||
msg.push('\n');
|
||||
msg.push_str(name);
|
||||
}
|
||||
}
|
||||
|
||||
let mut multi_span = MultiSpan::from_spans(spans.iter().map(|(_, sp)| *sp).collect());
|
||||
for (name, span) in spans {
|
||||
multi_span.push_span_label(span, format!("`{}`: not accessible", name));
|
||||
}
|
||||
|
||||
err.span_note(multi_span, &msg);
|
||||
}
|
||||
|
||||
err.note(&msg);
|
||||
}
|
||||
}
|
||||
|
@ -2966,7 +2966,15 @@ impl<'a> Resolver<'a> {
|
||||
(None, false)
|
||||
};
|
||||
if !candidates.is_empty() {
|
||||
diagnostics::show_candidates(&mut err, span, &candidates, instead, found_use);
|
||||
diagnostics::show_candidates(
|
||||
&self.definitions,
|
||||
self.session,
|
||||
&mut err,
|
||||
span,
|
||||
&candidates,
|
||||
instead,
|
||||
found_use,
|
||||
);
|
||||
} else if let Some((span, msg, sugg, appl)) = suggestion {
|
||||
err.span_suggestion(span, msg, sugg, appl);
|
||||
}
|
||||
|
@ -4,8 +4,11 @@ error[E0425]: cannot find function `fpriv` in this scope
|
||||
LL | fpriv();
|
||||
| ^^^^^ not found in this scope
|
||||
|
|
||||
= note: this function exists but is inaccessible:
|
||||
bar::fpriv
|
||||
note: function `bar::fpriv` exists but is inaccessible
|
||||
--> $DIR/glob-resolve1.rs:7:5
|
||||
|
|
||||
LL | fn fpriv() {}
|
||||
| ^^^^^^^^^^ not accessible
|
||||
|
||||
error[E0425]: cannot find function `epriv` in this scope
|
||||
--> $DIR/glob-resolve1.rs:27:5
|
||||
@ -13,8 +16,11 @@ error[E0425]: cannot find function `epriv` in this scope
|
||||
LL | epriv();
|
||||
| ^^^^^ not found in this scope
|
||||
|
|
||||
= note: this function exists but is inaccessible:
|
||||
bar::epriv
|
||||
note: function `bar::epriv` exists but is inaccessible
|
||||
--> $DIR/glob-resolve1.rs:9:9
|
||||
|
|
||||
LL | fn epriv();
|
||||
| ^^^^^^^^^^^ not accessible
|
||||
|
||||
error[E0423]: expected value, found enum `B`
|
||||
--> $DIR/glob-resolve1.rs:28:5
|
||||
@ -40,8 +46,11 @@ error[E0425]: cannot find value `C` in this scope
|
||||
LL | C;
|
||||
| ^ not found in this scope
|
||||
|
|
||||
= note: this unit struct exists but is inaccessible:
|
||||
bar::C
|
||||
note: unit struct `bar::C` exists but is inaccessible
|
||||
--> $DIR/glob-resolve1.rs:18:5
|
||||
|
|
||||
LL | struct C;
|
||||
| ^^^^^^^^^ not accessible
|
||||
|
||||
error[E0425]: cannot find function `import` in this scope
|
||||
--> $DIR/glob-resolve1.rs:30:5
|
||||
@ -63,8 +72,11 @@ LL | pub enum B {
|
||||
LL | foo::<A>();
|
||||
| ^ help: an enum with a similar name exists: `B`
|
||||
|
|
||||
= note: this enum exists but is inaccessible:
|
||||
bar::A
|
||||
note: enum `bar::A` exists but is inaccessible
|
||||
--> $DIR/glob-resolve1.rs:11:5
|
||||
|
|
||||
LL | enum A {
|
||||
| ^^^^^^ not accessible
|
||||
|
||||
error[E0412]: cannot find type `C` in this scope
|
||||
--> $DIR/glob-resolve1.rs:33:11
|
||||
@ -75,8 +87,11 @@ LL | pub enum B {
|
||||
LL | foo::<C>();
|
||||
| ^ help: an enum with a similar name exists: `B`
|
||||
|
|
||||
= note: this struct exists but is inaccessible:
|
||||
bar::C
|
||||
note: struct `bar::C` exists but is inaccessible
|
||||
--> $DIR/glob-resolve1.rs:18:5
|
||||
|
|
||||
LL | struct C;
|
||||
| ^^^^^^^^^ not accessible
|
||||
|
||||
error[E0412]: cannot find type `D` in this scope
|
||||
--> $DIR/glob-resolve1.rs:34:11
|
||||
@ -87,8 +102,11 @@ LL | pub enum B {
|
||||
LL | foo::<D>();
|
||||
| ^ help: an enum with a similar name exists: `B`
|
||||
|
|
||||
= note: this type alias exists but is inaccessible:
|
||||
bar::D
|
||||
note: type alias `bar::D` exists but is inaccessible
|
||||
--> $DIR/glob-resolve1.rs:20:5
|
||||
|
|
||||
LL | type D = isize;
|
||||
| ^^^^^^^^^^^^^^^ not accessible
|
||||
|
||||
error: aborting due to 8 previous errors
|
||||
|
||||
|
@ -4,8 +4,11 @@ error[E0412]: cannot find type `Bar` in this scope
|
||||
LL | fn sub() -> Bar { 1 }
|
||||
| ^^^ not found in this scope
|
||||
|
|
||||
= note: this type alias exists but is inaccessible:
|
||||
a::b::Bar
|
||||
note: type alias `a::b::Bar` exists but is inaccessible
|
||||
--> $DIR/issue-4366-2.rs:11:9
|
||||
|
|
||||
LL | type Bar = isize;
|
||||
| ^^^^^^^^^^^^^^^^^ not accessible
|
||||
|
||||
error[E0423]: expected function, found module `foo`
|
||||
--> $DIR/issue-4366-2.rs:25:5
|
||||
|
@ -16,8 +16,11 @@ error[E0425]: cannot find function, tuple struct or tuple variant `Bx` in this s
|
||||
LL | Bx(());
|
||||
| ^^ not found in this scope
|
||||
|
|
||||
= note: this tuple struct exists but is inaccessible:
|
||||
foo::Bx
|
||||
note: tuple struct `foo::Bx` exists but is inaccessible
|
||||
--> $DIR/issue-42944.rs:2:5
|
||||
|
|
||||
LL | pub struct Bx(());
|
||||
| ^^^^^^^^^^^^^^^^^^ not accessible
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
@ -6,6 +6,8 @@
|
||||
|
||||
mod a {
|
||||
struct Foo;
|
||||
//~^ NOTE: struct `a::Foo` exists but is inaccessible
|
||||
//~| NOTE: not accessible
|
||||
}
|
||||
|
||||
mod b {
|
||||
@ -14,14 +16,16 @@ mod b {
|
||||
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 {}
|
||||
//~^ NOTE: these enums exist but are inaccessible
|
||||
//~| NOTE: `c::Eee`: not accessible
|
||||
|
||||
mod d {
|
||||
enum Eee {}
|
||||
//~^ NOTE: `c::d::Eee`: not accessible
|
||||
}
|
||||
}
|
||||
|
||||
@ -29,7 +33,6 @@ 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() {}
|
||||
|
@ -1,24 +1,32 @@
|
||||
error[E0412]: cannot find type `Foo` in this scope
|
||||
--> $DIR/issue-88472.rs:14:16
|
||||
--> $DIR/issue-88472.rs:16:16
|
||||
|
|
||||
LL | type Bar = Foo;
|
||||
| ^^^ not found in this scope
|
||||
|
|
||||
= note: this struct exists but is inaccessible:
|
||||
a::Foo
|
||||
note: struct `a::Foo` exists but is inaccessible
|
||||
--> $DIR/issue-88472.rs:8:5
|
||||
|
|
||||
LL | struct Foo;
|
||||
| ^^^^^^^^^^^ not accessible
|
||||
|
||||
error[E0412]: cannot find type `Eee` in this scope
|
||||
--> $DIR/issue-88472.rs:29:16
|
||||
--> $DIR/issue-88472.rs:33:16
|
||||
|
|
||||
LL | type Baz = Eee;
|
||||
| ^^^ not found in this scope
|
||||
|
|
||||
= note: these items exist but are inaccessible:
|
||||
c::Eee
|
||||
c::d::Eee
|
||||
note: these enums exist but are inaccessible
|
||||
--> $DIR/issue-88472.rs:22:5
|
||||
|
|
||||
LL | enum Eee {}
|
||||
| ^^^^^^^^ `c::Eee`: not accessible
|
||||
...
|
||||
LL | enum Eee {}
|
||||
| ^^^^^^^^ `c::d::Eee`: not accessible
|
||||
|
||||
warning: unused import: `crate::a::*`
|
||||
--> $DIR/issue-88472.rs:12:9
|
||||
--> $DIR/issue-88472.rs:14:9
|
||||
|
|
||||
LL | use crate::a::*;
|
||||
| ^^^^^^^^^^^
|
||||
|
@ -171,8 +171,11 @@ LL | pub enum E {
|
||||
LL | let _: Z = m::n::Z;
|
||||
| ^ help: an enum with a similar name exists: `E`
|
||||
|
|
||||
= note: this enum exists but is inaccessible:
|
||||
m::Z
|
||||
note: enum `m::Z` exists but is inaccessible
|
||||
--> $DIR/privacy-enum-ctor.rs:11:9
|
||||
|
|
||||
LL | pub(in m) enum Z {
|
||||
| ^^^^^^^^^^^^^^^^ not accessible
|
||||
|
||||
error[E0423]: expected value, found enum `m::n::Z`
|
||||
--> $DIR/privacy-enum-ctor.rs:57:16
|
||||
@ -211,8 +214,11 @@ LL | pub enum E {
|
||||
LL | let _: Z = m::n::Z::Fn;
|
||||
| ^ help: an enum with a similar name exists: `E`
|
||||
|
|
||||
= note: this enum exists but is inaccessible:
|
||||
m::Z
|
||||
note: enum `m::Z` exists but is inaccessible
|
||||
--> $DIR/privacy-enum-ctor.rs:11:9
|
||||
|
|
||||
LL | pub(in m) enum Z {
|
||||
| ^^^^^^^^^^^^^^^^ not accessible
|
||||
|
||||
error[E0412]: cannot find type `Z` in this scope
|
||||
--> $DIR/privacy-enum-ctor.rs:64:12
|
||||
@ -223,8 +229,11 @@ LL | pub enum E {
|
||||
LL | let _: Z = m::n::Z::Struct;
|
||||
| ^ help: an enum with a similar name exists: `E`
|
||||
|
|
||||
= note: this enum exists but is inaccessible:
|
||||
m::Z
|
||||
note: enum `m::Z` exists but is inaccessible
|
||||
--> $DIR/privacy-enum-ctor.rs:11:9
|
||||
|
|
||||
LL | pub(in m) enum Z {
|
||||
| ^^^^^^^^^^^^^^^^ not accessible
|
||||
|
||||
error[E0423]: expected value, found struct variant `m::n::Z::Struct`
|
||||
--> $DIR/privacy-enum-ctor.rs:64:16
|
||||
@ -246,8 +255,11 @@ LL | pub enum E {
|
||||
LL | let _: Z = m::n::Z::Unit {};
|
||||
| ^ help: an enum with a similar name exists: `E`
|
||||
|
|
||||
= note: this enum exists but is inaccessible:
|
||||
m::Z
|
||||
note: enum `m::Z` exists but is inaccessible
|
||||
--> $DIR/privacy-enum-ctor.rs:11:9
|
||||
|
|
||||
LL | pub(in m) enum Z {
|
||||
| ^^^^^^^^^^^^^^^^ not accessible
|
||||
|
||||
error[E0603]: enum `Z` is private
|
||||
--> $DIR/privacy-enum-ctor.rs:57:22
|
||||
|
@ -33,8 +33,11 @@ error[E0423]: expected value, found struct `xcrate::S`
|
||||
LL | xcrate::S;
|
||||
| ^^^^^^^^^ constructor is not visible here due to private fields
|
||||
|
|
||||
= note: this tuple struct exists but is inaccessible:
|
||||
m::S
|
||||
note: tuple struct `m::S` exists but is inaccessible
|
||||
--> $DIR/privacy-struct-ctor.rs:6:5
|
||||
|
|
||||
LL | pub struct S(u8);
|
||||
| ^^^^^^^^^^^^^^^^^ not accessible
|
||||
|
||||
error[E0603]: tuple struct constructor `Z` is private
|
||||
--> $DIR/privacy-struct-ctor.rs:18:12
|
||||
|
@ -66,8 +66,11 @@ error[E0531]: cannot find unit struct, unit variant or constant `Self` in this s
|
||||
LL | mut Self => (),
|
||||
| ^^^^ not found in this scope
|
||||
|
|
||||
= note: this unit struct exists but is inaccessible:
|
||||
foo::Self
|
||||
note: unit struct `foo::Self` exists but is inaccessible
|
||||
--> $DIR/self_type_keyword.rs:2:3
|
||||
|
|
||||
LL | struct Self;
|
||||
| ^^^^^^^^^^^^ not accessible
|
||||
|
||||
error[E0392]: parameter `'Self` is never used
|
||||
--> $DIR/self_type_keyword.rs:6:12
|
||||
|
Loading…
Reference in New Issue
Block a user