Skip to content
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

incorrectly ignoring a field with { _ } yields suggestion that assumes _ is a valid field name #83263

Closed
Lotterleben opened this issue Mar 18, 2021 · 3 comments
Assignees
Labels
A-diagnostics Area: Messages for errors, warnings, and lints A-parser Area: The parsing of Rust source code to an AST A-suggestion-diagnostics Area: Suggestions generated by the compiler applied by `cargo fix` C-enhancement Category: An issue proposing an enhancement or a PR with one. D-papercut Diagnostics: An error or lint that needs small tweaks. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@Lotterleben
Copy link
Contributor

hi,
I think I ran into a bit of an error reporting hickup with my erroneous code.

Given the following code: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=cb47de4bf36f023caa0c21fc77ec4271

enum TopException {
    HardFault { stack_overflow: bool },
    Other,
}

fn main() {
    let top_exception = Some(TopException::Other);

    if let Some(TopException::HardFault {_}) = top_exception {
     //                                  ^^ oh no
        todo!();
    }
}

The current output is:

error: expected identifier, found reserved identifier `_`
  --> src/main.rs:10:42
   |
10 |     if let Some(TopException::HardFault {_}) = top_exception {
   |                                          ^ expected identifier, found reserved identifier

error[E0026]: variant `TopException::HardFault` does not have a field named `_`
  --> src/main.rs:10:42
   |
10 |     if let Some(TopException::HardFault {_}) = top_exception {
   |                                          ^ variant `TopException::HardFault` does not have this field

error[E0027]: pattern does not mention field `stack_overflow`
  --> src/main.rs:10:17
   |
10 |     if let Some(TopException::HardFault {_}) = top_exception {
   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing field `stack_overflow`
   |
help: include the missing field in the pattern
   |
10 |     if let Some(TopException::HardFault {_, stack_overflow}) = top_exception {
   |                                           ^^^^^^^^^^^^^^^^
help: if you don't care about this missing field, you can explicitly ignore it
   |
10 |     if let Some(TopException::HardFault {_, ..}) = top_exception {
   |                                           ^^^^

error: aborting due to 3 previous errors

Some errors have detailed explanations: E0026, E0027.
For more information about an error, try `rustc --explain E0026`.
error: could not compile `playground`

To learn more, run the command again with --verbose.

Applying this suggestion yields


error: expected identifier, found reserved identifier `_`
  --> src/main.rs:10:42
   |
10 |     if let Some(TopException::HardFault {_, stack_overflow}) = top_exception {
   |                                          ^ expected identifier, found reserved identifier

error[E0026]: variant `TopException::HardFault` does not have a field named `_`
  --> src/main.rs:10:42
   |
10 |     if let Some(TopException::HardFault {_, stack_overflow}) = top_exception {
   |                                          ^ variant `TopException::HardFault` does not have this field

Instead, I would've expected the suggestion to be along the lines of:

if let Some(TopException::HardFault {stack_overflow: _}) = top_exception {

or at least

    if let Some(TopException::HardFault {stack_overflow}) = top_exception {

@jonas-schievink pointed out to me that this is likely caused by rustc recognizing that _ is not a valid field pattern, trying to recover from it by treating it as something like _: _, which also fails because there's no field named _ – but of course this is not a valid field name at all, which should be recognized as such?

@Lotterleben Lotterleben added A-diagnostics Area: Messages for errors, warnings, and lints T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Mar 18, 2021
@jonas-schievink jonas-schievink added A-suggestion-diagnostics Area: Suggestions generated by the compiler applied by `cargo fix` C-enhancement Category: An issue proposing an enhancement or a PR with one. labels Mar 18, 2021
@estebank estebank added A-parser Area: The parsing of Rust source code to an AST D-papercut Diagnostics: An error or lint that needs small tweaks. labels Mar 18, 2021
@estebank
Copy link
Contributor

We could at least not emit E0026 in this case.

@Lotterleben
Copy link
Contributor Author

Hrmmm. I just noticed that I'd totally forgotten to check out what the error looks like on nightly, which imo is already much more helpful because it explicitly states that _ is reserved:

error: expected identifier, found reserved identifier `_`
  --> src/main.rs:10:42
   |
10 |     if let Some(TopException::HardFault {_}) = top_exception {
   |                                          ^ expected identifier, found reserved identifier

error[E0026]: variant `TopException::HardFault` does not have a field named `_`
  --> src/main.rs:10:42
   |
10 |     if let Some(TopException::HardFault {_}) = top_exception {
   |                                          ^ variant `TopException::HardFault` does not have this field

error[E0027]: pattern does not mention field `stack_overflow`
  --> src/main.rs:10:17
   |
10 |     if let Some(TopException::HardFault {_}) = top_exception {
   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing field `stack_overflow`
   |
help: include the missing field in the pattern
   |
10 |     if let Some(TopException::HardFault {_, stack_overflow }) = top_exception {
   |                                           ^^^^^^^^^^^^^^^^^^
help: if you don't care about this missing field, you can explicitly ignore it
   |
10 |     if let Some(TopException::HardFault {_, .. }) = top_exception {

And the E0027 error message adds some extra context. My only remaining nitpick would be the misleading help: suggestion.
(The reason I arrived at this error in the first place at all was because I keep forgetting that I can't use _ to denote "I don't care, throw it away" like that, but need to be explicit about what I want to ignore. So I'm not 100% sure I would've made the connection from the hints as they are now.)

@TaKO8Ki TaKO8Ki self-assigned this Mar 18, 2022
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this issue Mar 23, 2022
…uct-enum-with-underscore, r=estebank

Stop emitting E0026 for struct enums with underscores

This patch resolves a part of rust-lang#83263;

r? `@estebank`
@compiler-errors
Copy link
Member

Triage:

error: expected field pattern, found `_`
  --> src/main.rs:10:42
   |
10 |     if let Some(TopException::HardFault {_}) = top_exception {
   |                                          ^
   |
help: to omit remaining fields, use `..`
   |
10 |     if let Some(TopException::HardFault {..}) = top_exception {
   |                                          ~~

I consider this to be sufficiently fixed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-diagnostics Area: Messages for errors, warnings, and lints A-parser Area: The parsing of Rust source code to an AST A-suggestion-diagnostics Area: Suggestions generated by the compiler applied by `cargo fix` C-enhancement Category: An issue proposing an enhancement or a PR with one. D-papercut Diagnostics: An error or lint that needs small tweaks. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

5 participants