Skip to content

Commit 404df1c

Browse files
committed
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.
1 parent 3b1c08c commit 404df1c

File tree

7 files changed

+42
-17
lines changed

7 files changed

+42
-17
lines changed

src/librustc_resolve/diagnostics.rs

+15-8
Original file line numberDiff line numberDiff line change
@@ -643,22 +643,24 @@ impl<'a> Resolver<'a> {
643643
let not_local_module = crate_name.name != kw::Crate;
644644
let mut worklist =
645645
vec![(start_module, Vec::<ast::PathSegment>::new(), true, not_local_module)];
646+
let mut worklist_via_import = vec![];
646647

647-
while let Some((in_module, path_segments, accessible, in_module_is_extern)) = worklist.pop()
648+
while let Some((in_module, path_segments, accessible, in_module_is_extern)) =
649+
match worklist.pop() {
650+
None => worklist_via_import.pop(),
651+
Some(x) => Some(x),
652+
}
648653
{
649654
// We have to visit module children in deterministic order to avoid
650655
// instabilities in reported imports (#43552).
651656
in_module.for_each_child(self, |this, ident, ns, name_binding| {
652-
// avoid imports entirely
653-
if name_binding.is_import() && !name_binding.is_extern_crate() {
654-
return;
655-
}
656-
657-
// avoid non-importable candidates as well
657+
// avoid non-importable candidates
658658
if !name_binding.is_importable() {
659659
return;
660660
}
661661

662+
let via_import = name_binding.is_import() && !name_binding.is_extern_crate();
663+
662664
let child_accessible =
663665
accessible && this.is_accessible_from(name_binding.vis, parent_scope.module);
664666

@@ -667,6 +669,10 @@ impl<'a> Resolver<'a> {
667669
return;
668670
}
669671

672+
if via_import && name_binding.is_possibly_imported_variant() {
673+
return;
674+
}
675+
670676
// collect results based on the filter function
671677
// avoid suggesting anything from the same module in which we are resolving
672678
if ident.name == lookup_ident.name
@@ -724,7 +730,8 @@ impl<'a> Resolver<'a> {
724730
let is_extern = in_module_is_extern || name_binding.is_extern_crate();
725731
// add the module to the lookup
726732
if seen_modules.insert(module.def_id().unwrap()) {
727-
worklist.push((module, path_segments, child_accessible, is_extern));
733+
if via_import { &mut worklist_via_import } else { &mut worklist }
734+
.push((module, path_segments, child_accessible, is_extern));
728735
}
729736
}
730737
}

src/librustc_resolve/lib.rs

+7
Original file line numberDiff line numberDiff line change
@@ -711,6 +711,13 @@ impl<'a> NameBinding<'a> {
711711
}
712712
}
713713

714+
fn is_possibly_imported_variant(&self) -> bool {
715+
match self.kind {
716+
NameBindingKind::Import { binding, .. } => binding.is_possibly_imported_variant(),
717+
_ => self.is_variant(),
718+
}
719+
}
720+
714721
// We sometimes need to treat variants as `pub` for backwards compatibility.
715722
fn pseudo_vis(&self) -> ty::Visibility {
716723
if self.is_variant() && self.res().def_id().is_local() {

src/test/ui/glob-resolve1.rs

+4
Original file line numberDiff line numberDiff line change
@@ -29,3 +29,7 @@ fn main() {
2929
foo::<C>(); //~ ERROR: cannot find type `C` in this scope
3030
foo::<D>(); //~ ERROR: cannot find type `D` in this scope
3131
}
32+
33+
mod other {
34+
pub fn import() {}
35+
}

src/test/ui/glob-resolve1.stderr

+5
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,11 @@ error[E0425]: cannot find function `import` in this scope
4242
|
4343
LL | import();
4444
| ^^^^^^ not found in this scope
45+
|
46+
help: consider importing this function
47+
|
48+
LL | use other::import;
49+
|
4550

4651
error[E0412]: cannot find type `A` in this scope
4752
--> $DIR/glob-resolve1.rs:28:11

src/test/ui/namespace/namespace-mix.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ help: consider importing one of these items instead
1616
|
1717
LL | use m2::S;
1818
|
19-
LL | use namespace_mix::xm2::S;
19+
LL | use xm2::S;
2020
|
2121

2222
error[E0423]: expected value, found type alias `xm1::S`
@@ -39,7 +39,7 @@ help: consider importing one of these items instead
3939
|
4040
LL | use m2::S;
4141
|
42-
LL | use namespace_mix::xm2::S;
42+
LL | use xm2::S;
4343
|
4444

4545
error[E0423]: expected value, found struct variant `m7::V`
@@ -61,7 +61,7 @@ help: consider importing one of these items instead
6161
|
6262
LL | use m8::V;
6363
|
64-
LL | use namespace_mix::xm8::V;
64+
LL | use xm8::V;
6565
|
6666

6767
error[E0423]: expected value, found struct variant `xm7::V`
@@ -83,7 +83,7 @@ help: consider importing one of these items instead
8383
|
8484
LL | use m8::V;
8585
|
86-
LL | use namespace_mix::xm8::V;
86+
LL | use xm8::V;
8787
|
8888

8989
error[E0277]: the trait bound `c::Item: Impossible` is not satisfied

src/test/ui/resolve/issue-21221-2.stderr

+3-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@ error[E0405]: cannot find trait `T` in this scope
44
LL | impl T for Foo { }
55
| ^ not found in this scope
66
|
7-
help: consider importing this trait
7+
help: consider importing one of these items
8+
|
9+
LL | use baz::T;
810
|
911
LL | use foo::bar::T;
1012
|

src/test/ui/resolve/privacy-enum-ctor.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ LL | let _: E = m::n::Z;
132132
| ^
133133
help: consider importing this enum
134134
|
135-
LL | use m::n::Z;
135+
LL | use m::Z;
136136
|
137137

138138
error[E0423]: expected value, found enum `m::n::Z`
@@ -165,7 +165,7 @@ LL | let _: E = m::n::Z::Fn;
165165
| ^
166166
help: consider importing this enum
167167
|
168-
LL | use m::n::Z;
168+
LL | use m::Z;
169169
|
170170

171171
error[E0412]: cannot find type `Z` in this scope
@@ -183,7 +183,7 @@ LL | let _: E = m::n::Z::Struct;
183183
| ^
184184
help: consider importing this enum
185185
|
186-
LL | use m::n::Z;
186+
LL | use m::Z;
187187
|
188188

189189
error[E0423]: expected value, found struct variant `m::n::Z::Struct`
@@ -212,7 +212,7 @@ LL | let _: E = m::n::Z::Unit {};
212212
| ^
213213
help: consider importing this enum
214214
|
215-
LL | use m::n::Z;
215+
LL | use m::Z;
216216
|
217217

218218
error[E0603]: enum `Z` is private

0 commit comments

Comments
 (0)