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

Misleading diagnostic on missing comma #93867

Closed
notriddle opened this issue Feb 10, 2022 · 3 comments · Fixed by #95211
Closed

Misleading diagnostic on missing comma #93867

notriddle opened this issue Feb 10, 2022 · 3 comments · Fixed by #95211
Assignees
Labels
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.

Comments

@notriddle
Copy link
Contributor

notriddle commented Feb 10, 2022

Given the following code: https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=4f89aeb79b3d5b09db11201a04b0786e

pub struct Entry<'a, K, V> {
    k: &'a mut K,
    v: V,
}

pub fn entry<'a, K, V>() -> Entry<'a K, V> {
//                                  ^ missing comma
    unimplemented!()
}

The current output is:

error: expected one of `,`, `:`, `=`, or `>`, found `K`
 --> src/lib.rs:6:28
  |
6 | pub fn entry() -> Entry<'a K, V> {
  |                            ^ expected one of `,`, `:`, `=`, or `>`

error: could not compile `playground` due to previous error

The : and = suggestions are misleading, because this is a generic invocation, not a generic declaration. You cannot, in fact, write a : or an = here:

When you write a :

This code:

pub struct Entry<'a, K, V> {
    k: &'a mut K,
    v: V,
}

pub fn entry<'a, K, V>() -> Entry<'a: 'static, K, V> {
    unimplemented!()
}

Produces this output: https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=fe71e2beefbe699e32f4d2c91dfb9b4e

error: expected one of `,` or `>`, found `:`
 --> src/lib.rs:6:37
  |
6 | pub fn entry<'a, K, V>() -> Entry<'a: 'static, K, V> {
  |                                     ^ expected one of `,` or `>`
  |
help: expressions must be enclosed in braces to be used as const generic arguments
  |
6 | pub fn entry<'a, K, V>() -> Entry<{ 'a: 'static }, K, V> {
  |                                   +             +

[E0106]: missing lifetime specifier
 --> src/lib.rs:6:35
  |
6 | pub fn entry<'a, K, V>() -> Entry<'a: 'static, K, V> {
  |                                   ^ expected named lifetime parameter
  |
  = help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
help: consider using the `'a` lifetime
  |
6 | pub fn entry<'a, K, V>() -> Entry<'a, 'a: 'static, K, V> {
  |                                   +++

[E0107]: this struct takes 2 generic arguments but 3 generic arguments were supplied
 --> src/lib.rs:6:29
  |
6 | pub fn entry<'a, K, V>() -> Entry<'a: 'static, K, V> {
  |                             ^^^^^                 - help: remove this generic argument
  |                             |
  |                             expected 2 generic arguments
  |
note: struct defined here, with 2 generic parameters: `K`, `V`
 --> src/lib.rs:1:12
  |
1 | pub struct Entry<'a, K, V> {
  |            ^^^^^     -  -

Some errors have detailed explanations: E0106, E0107.
For more information about an error, try `rustc --explain E0106`.
When you write an =

This code:

pub struct Entry<'a, K, V> {
    k: &'a mut K,
    v: V,
}

pub fn entry<'a, K, V>() -> Entry<'a = 'static, K, V> {
    unimplemented!()
}

Produces this output: https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=4eb1f410e20dd4e36879637261f0d859

error: expected one of `,`, `:`, or `>`, found `=`
 --> src/lib.rs:6:38
  |
6 | pub fn entry<'a, K, V>() -> Entry<'a = 'static, K, V> {
  |                                   -- ^ expected one of `,`, `:`, or `>`
  |                                   |
  |                                   maybe try to close unmatched angle bracket
@notriddle notriddle 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 Feb 10, 2022
@compiler-errors
Copy link
Member

Hmm, didn't look that deeply into this, but perhaps we might want to introduce a Parser::check_noexpect that mirrors Parser::eat_keyword_noexpect -- or just compare self.token.kind instead of doing a check call when looking for tokens to recover on.

@compiler-errors
Copy link
Member

I wonder if we want to systemically clean up/work through the parser code to get better at only adding token kinds to expected_tokens on good paths. I've seen issues like this where it misleadingly suggests bad tokens before, and it makes me want to fix it, hehe.

@terrarier2111
Copy link
Contributor

@rustbot claim

JohnTitor added a commit to JohnTitor/rust that referenced this issue Jun 13, 2022
…piler-errors

Improve parser diagnostics

This pr fixes rust-lang#93867 and contains a couple of diagnostics related changes to the parser.
Here is a short list with some of the changes:
- don't suggest the same thing that is the current token
- suggest removing the current token if the following token is one of the suggestions (maybe incorrect)
- tell the user to put a type or lifetime after where if there is none (as a warning)
- reduce the amount of tokens suggested (via the new eat_noexpect and check_noexpect methods)

If any of these changes are undesirable, i can remove them, thanks!
@bors bors closed this as completed in 21fdd54 Jun 14, 2022
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 T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants