Skip to content

Commit 0a17ac2

Browse files
authored
Rollup merge of rust-lang#73652 - da-x:add-reexported-to-use-suggestions, r=petrochenkov
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. ```rust mod foo { mod bar { pub struct X; } pub use self::bar::X; } fn main() { X; } ``` This fixes the issue.
2 parents b71464c + 037e930 commit 0a17ac2

File tree

7 files changed

+47
-17
lines changed

7 files changed

+47
-17
lines changed

src/librustc_resolve/diagnostics.rs

+20-8
Original file line numberDiff line numberDiff line change
@@ -643,18 +643,18 @@ 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
}
@@ -667,6 +667,17 @@ impl<'a> Resolver<'a> {
667667
return;
668668
}
669669

670+
let via_import = name_binding.is_import() && !name_binding.is_extern_crate();
671+
672+
// There is an assumption elsewhere that paths of variants are in the enum's
673+
// declaration and not imported. With this assumption, the variant component is
674+
// chopped and the rest of the path is assumed to be the enum's own path. For
675+
// errors where a variant is used as the type instead of the enum, this causes
676+
// funny looking invalid suggestions, i.e `foo` instead of `foo::MyEnum`.
677+
if via_import && name_binding.is_possibly_imported_variant() {
678+
return;
679+
}
680+
670681
// collect results based on the filter function
671682
// avoid suggesting anything from the same module in which we are resolving
672683
if ident.name == lookup_ident.name
@@ -724,7 +735,8 @@ impl<'a> Resolver<'a> {
724735
let is_extern = in_module_is_extern || name_binding.is_extern_crate();
725736
// add the module to the lookup
726737
if seen_modules.insert(module.def_id().unwrap()) {
727-
worklist.push((module, path_segments, child_accessible, is_extern));
738+
if via_import { &mut worklist_via_import } else { &mut worklist }
739+
.push((module, path_segments, child_accessible, is_extern));
728740
}
729741
}
730742
}

src/librustc_resolve/lib.rs

+7
Original file line numberDiff line numberDiff line change
@@ -703,6 +703,13 @@ impl<'a> NameBinding<'a> {
703703
}
704704
}
705705

706+
fn is_possibly_imported_variant(&self) -> bool {
707+
match self.kind {
708+
NameBindingKind::Import { binding, .. } => binding.is_possibly_imported_variant(),
709+
_ => self.is_variant(),
710+
}
711+
}
712+
706713
// We sometimes need to treat variants as `pub` for backwards compatibility.
707714
fn pseudo_vis(&self) -> ty::Visibility {
708715
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)