Skip to content

Fix bad suggestions when initializing enum as struct #99357

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions compiler/rustc_resolve/src/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1271,6 +1271,7 @@ impl<'a> Resolver<'a> {
let mut seen_modules = FxHashSet::default();
let mut worklist = vec![(start_module, Vec::<ast::PathSegment>::new(), true)];
let mut worklist_via_import = vec![];
let mut seen_exact_match = false;

while let Some((in_module, path_segments, accessible)) = match worklist.pop() {
None => worklist_via_import.pop(),
Expand Down Expand Up @@ -1313,6 +1314,15 @@ impl<'a> Resolver<'a> {
}
}

// Note if we find an in-scope exact match on the identifier we are looking for
if ident.name == lookup_ident.name
&& ns == namespace
&& ptr::eq(in_module, parent_scope.module)
{
seen_exact_match = true;
return;
}

// collect results based on the filter function
// avoid suggesting anything from the same module in which we are resolving
// avoid suggesting anything with a hygienic name
Expand Down Expand Up @@ -1406,6 +1416,12 @@ impl<'a> Resolver<'a> {
})
}

// If we've seen an exact match on the ident, assume correct intent from the user
// (ie. the user meant to use the ident like this) and clear any import candidates
if seen_exact_match {
candidates.clear();
}

// If only some candidates are accessible, take just them
if !candidates.iter().all(|v: &ImportSuggestion| !v.accessible) {
candidates = candidates.into_iter().filter(|x| x.accessible).collect();
Expand Down
4 changes: 0 additions & 4 deletions src/test/ui/hygiene/globs.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,6 @@ LL | n!(f);
LL | n!(f);
| ^ not found in this scope
|
= note: consider importing this function:
foo::f
= note: this error originates in the macro `n` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0425]: cannot find function `f` in this scope
Expand All @@ -50,8 +48,6 @@ LL | n!(f);
LL | f
| ^ not found in this scope
|
= note: consider importing this function:
foo::f
= note: this error originates in the macro `n` (in Nightly builds, run with -Z macro-backtrace for more info)

error: aborting due to 4 previous errors
Expand Down
4 changes: 0 additions & 4 deletions src/test/ui/resolve/issue-3907.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,6 @@ help: you might have meant to use `#![feature(trait_alias)]` instead of a `type`
|
LL | trait Foo = dyn issue_3907::Foo;
|
help: consider importing this trait instead
|
LL | use issue_3907::Foo;
|

error: aborting due to previous error

Expand Down
5 changes: 0 additions & 5 deletions src/test/ui/span/issue-35987.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,6 @@ error[E0404]: expected trait, found type parameter `Add`
|
LL | impl<T: Clone, Add> Add for Foo<T> {
| ^^^ not a trait
|
help: consider importing this trait instead
|
LL | use std::ops::Add;
|

error: aborting due to previous error

Expand Down
23 changes: 23 additions & 0 deletions src/test/ui/suggestions/init-enum-as-struct.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
pub type Foos = i32;

pub enum Foo {
A,
B,
C,
}

mod module0 {
pub struct Foo {
a: i32,
}
}
mod module1 {
pub struct Foo {}
}
mod module2 {
pub enum Foo {}
}

fn main() {
let foo = Foo { b: 0 }; //~ expected struct, variant or union type, found enum `Foo`
}
12 changes: 12 additions & 0 deletions src/test/ui/suggestions/init-enum-as-struct.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
error[E0574]: expected struct, variant or union type, found enum `Foo`
--> $DIR/init-enum-as-struct.rs:22:15
|
LL | pub type Foos = i32;
| -------------------- similarly named type alias `Foos` defined here
...
LL | let foo = Foo { b: 0 };
| ^^^ help: a type alias with a similar name exists: `Foos`

error: aborting due to previous error

For more information about this error, try `rustc --explain E0574`.