mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-13 15:33:53 +00:00
Add re-exports to use suggestions
In the following example, an inaccessible path is suggested via `use foo::bar::X;` whereas an accessible public exported path can be suggested instead. ``` mod foo { mod bar { pub struct X; } pub use self::bar::X; } fn main() { X; } ``` This fixes the issue.
This commit is contained in:
parent
3b1c08c68c
commit
404df1cbbf
@ -643,22 +643,24 @@ impl<'a> Resolver<'a> {
|
||||
let not_local_module = crate_name.name != kw::Crate;
|
||||
let mut worklist =
|
||||
vec![(start_module, Vec::<ast::PathSegment>::new(), true, not_local_module)];
|
||||
let mut worklist_via_import = vec![];
|
||||
|
||||
while let Some((in_module, path_segments, accessible, in_module_is_extern)) = worklist.pop()
|
||||
while let Some((in_module, path_segments, accessible, in_module_is_extern)) =
|
||||
match worklist.pop() {
|
||||
None => worklist_via_import.pop(),
|
||||
Some(x) => Some(x),
|
||||
}
|
||||
{
|
||||
// We have to visit module children in deterministic order to avoid
|
||||
// instabilities in reported imports (#43552).
|
||||
in_module.for_each_child(self, |this, ident, ns, name_binding| {
|
||||
// avoid imports entirely
|
||||
if name_binding.is_import() && !name_binding.is_extern_crate() {
|
||||
return;
|
||||
}
|
||||
|
||||
// avoid non-importable candidates as well
|
||||
// avoid non-importable candidates
|
||||
if !name_binding.is_importable() {
|
||||
return;
|
||||
}
|
||||
|
||||
let via_import = name_binding.is_import() && !name_binding.is_extern_crate();
|
||||
|
||||
let child_accessible =
|
||||
accessible && this.is_accessible_from(name_binding.vis, parent_scope.module);
|
||||
|
||||
@ -667,6 +669,10 @@ impl<'a> Resolver<'a> {
|
||||
return;
|
||||
}
|
||||
|
||||
if via_import && name_binding.is_possibly_imported_variant() {
|
||||
return;
|
||||
}
|
||||
|
||||
// collect results based on the filter function
|
||||
// avoid suggesting anything from the same module in which we are resolving
|
||||
if ident.name == lookup_ident.name
|
||||
@ -724,7 +730,8 @@ impl<'a> Resolver<'a> {
|
||||
let is_extern = in_module_is_extern || name_binding.is_extern_crate();
|
||||
// add the module to the lookup
|
||||
if seen_modules.insert(module.def_id().unwrap()) {
|
||||
worklist.push((module, path_segments, child_accessible, is_extern));
|
||||
if via_import { &mut worklist_via_import } else { &mut worklist }
|
||||
.push((module, path_segments, child_accessible, is_extern));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -711,6 +711,13 @@ impl<'a> NameBinding<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
fn is_possibly_imported_variant(&self) -> bool {
|
||||
match self.kind {
|
||||
NameBindingKind::Import { binding, .. } => binding.is_possibly_imported_variant(),
|
||||
_ => self.is_variant(),
|
||||
}
|
||||
}
|
||||
|
||||
// We sometimes need to treat variants as `pub` for backwards compatibility.
|
||||
fn pseudo_vis(&self) -> ty::Visibility {
|
||||
if self.is_variant() && self.res().def_id().is_local() {
|
||||
|
@ -29,3 +29,7 @@ fn main() {
|
||||
foo::<C>(); //~ ERROR: cannot find type `C` in this scope
|
||||
foo::<D>(); //~ ERROR: cannot find type `D` in this scope
|
||||
}
|
||||
|
||||
mod other {
|
||||
pub fn import() {}
|
||||
}
|
||||
|
@ -42,6 +42,11 @@ error[E0425]: cannot find function `import` in this scope
|
||||
|
|
||||
LL | import();
|
||||
| ^^^^^^ not found in this scope
|
||||
|
|
||||
help: consider importing this function
|
||||
|
|
||||
LL | use other::import;
|
||||
|
|
||||
|
||||
error[E0412]: cannot find type `A` in this scope
|
||||
--> $DIR/glob-resolve1.rs:28:11
|
||||
|
@ -16,7 +16,7 @@ help: consider importing one of these items instead
|
||||
|
|
||||
LL | use m2::S;
|
||||
|
|
||||
LL | use namespace_mix::xm2::S;
|
||||
LL | use xm2::S;
|
||||
|
|
||||
|
||||
error[E0423]: expected value, found type alias `xm1::S`
|
||||
@ -39,7 +39,7 @@ help: consider importing one of these items instead
|
||||
|
|
||||
LL | use m2::S;
|
||||
|
|
||||
LL | use namespace_mix::xm2::S;
|
||||
LL | use xm2::S;
|
||||
|
|
||||
|
||||
error[E0423]: expected value, found struct variant `m7::V`
|
||||
@ -61,7 +61,7 @@ help: consider importing one of these items instead
|
||||
|
|
||||
LL | use m8::V;
|
||||
|
|
||||
LL | use namespace_mix::xm8::V;
|
||||
LL | use xm8::V;
|
||||
|
|
||||
|
||||
error[E0423]: expected value, found struct variant `xm7::V`
|
||||
@ -83,7 +83,7 @@ help: consider importing one of these items instead
|
||||
|
|
||||
LL | use m8::V;
|
||||
|
|
||||
LL | use namespace_mix::xm8::V;
|
||||
LL | use xm8::V;
|
||||
|
|
||||
|
||||
error[E0277]: the trait bound `c::Item: Impossible` is not satisfied
|
||||
|
@ -4,7 +4,9 @@ error[E0405]: cannot find trait `T` in this scope
|
||||
LL | impl T for Foo { }
|
||||
| ^ not found in this scope
|
||||
|
|
||||
help: consider importing this trait
|
||||
help: consider importing one of these items
|
||||
|
|
||||
LL | use baz::T;
|
||||
|
|
||||
LL | use foo::bar::T;
|
||||
|
|
||||
|
@ -132,7 +132,7 @@ LL | let _: E = m::n::Z;
|
||||
| ^
|
||||
help: consider importing this enum
|
||||
|
|
||||
LL | use m::n::Z;
|
||||
LL | use m::Z;
|
||||
|
|
||||
|
||||
error[E0423]: expected value, found enum `m::n::Z`
|
||||
@ -165,7 +165,7 @@ LL | let _: E = m::n::Z::Fn;
|
||||
| ^
|
||||
help: consider importing this enum
|
||||
|
|
||||
LL | use m::n::Z;
|
||||
LL | use m::Z;
|
||||
|
|
||||
|
||||
error[E0412]: cannot find type `Z` in this scope
|
||||
@ -183,7 +183,7 @@ LL | let _: E = m::n::Z::Struct;
|
||||
| ^
|
||||
help: consider importing this enum
|
||||
|
|
||||
LL | use m::n::Z;
|
||||
LL | use m::Z;
|
||||
|
|
||||
|
||||
error[E0423]: expected value, found struct variant `m::n::Z::Struct`
|
||||
@ -212,7 +212,7 @@ LL | let _: E = m::n::Z::Unit {};
|
||||
| ^
|
||||
help: consider importing this enum
|
||||
|
|
||||
LL | use m::n::Z;
|
||||
LL | use m::Z;
|
||||
|
|
||||
|
||||
error[E0603]: enum `Z` is private
|
||||
|
Loading…
Reference in New Issue
Block a user