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

Improve syntax error for misplaced lifetime quantifier (for<'a>) outside of APIT type #117882

Closed
kpreid opened this issue Nov 13, 2023 · 0 comments · Fixed by #117891
Closed

Improve syntax error for misplaced lifetime quantifier (for<'a>) outside of APIT type #117882

kpreid opened this issue Nov 13, 2023 · 0 comments · Fixed by #117891
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

@kpreid
Copy link
Contributor

kpreid commented Nov 13, 2023

Code

fn foo(_f: for<'a> impl FnOnce(&'a str)) {}

Current output

error: expected identifier, found keyword `impl`
 --> src/lib.rs:1:20
  |
1 | fn foo(_f: for<'a> impl FnOnce(&'a str)) {}
  |                    ^^^^ expected identifier, found keyword

error: unexpected lifetime `'a` in pattern
 --> src/lib.rs:1:33
  |
1 | fn foo(_f: for<'a> impl FnOnce(&'a str)) {}
  |                                 ^^ help: remove the lifetime

error: expected one of `:` or `|`, found `)`
 --> src/lib.rs:1:40
  |
1 | fn foo(_f: for<'a> impl FnOnce(&'a str)) {}
  |                                        ^ expected one of `:` or `|`

error: expected one of `(`, `)`, ` `, `,`, `::`, or `<`, found `FnOnce`
 --> src/lib.rs:1:25
  |
1 | fn foo(_f: for<'a> impl FnOnce(&'a str)) {}
  |                        -^^^^^^ expected one of `(`, `)`, ` `, `,`, `::`, or `<`
  |                        |
  |                        help: missing `,`

error[E0405]: cannot find trait `r#impl` in this scope
 --> src/lib.rs:1:20
  |
1 | fn foo(_f: for<'a> impl FnOnce(&'a str)) {}
  |                    ^^^^ not found in this scope

error[E0782]: trait objects must include the `dyn` keyword
 --> src/lib.rs:1:12
  |
1 | fn foo(_f: for<'a> impl FnOnce(&'a str)) {}
  |            ^^^^^^^^^^^^
  |
help: add `dyn` keyword before this trait
  |
1 | fn foo(_f: dyn for<'a> impl FnOnce(&'a str)) {}
  |               

Desired output

error: a lifetime quantifier (`for<'a>`) may not be used here
 --> src/lib.rs:1:20
  |
1 | fn foo(_f: for<'a> impl FnOnce(&'a str)) {}
  |            ^^^^^^^ this quantifier
  |
note: lifetime quantifiers may only be used before `fn` pointer types and within `impl Trait` types
help: place this `for<'a>` inside the `impl`:
  |
1 | fn foo(_f: impl for<'a> FnOnce(&'a str)) {}
  |                        

Rationale and extra context

I don't remember what the official name for for<'a> syntax in general is, so I've used "quantifier" in the proposed message.

The main thing I'm filing the issue for is that there's a large cascade of syntax errors, none of which explain the actual problem (the leading "expected identifier" is particularly bad), and which seem to be due to poor recovery (starting to parse the rest of the type as a new function parameter, as if there was a comma); it would be nice to have more concise and more helpful output, particularly because for<'a> is a superficially simple "modifier" syntax that does appear in multiple places in types, just not this one.

I hope that it will be simple to fix by making for<'a> something that is always parsed but not always permitted.

Also, rust-analyzer's current diagnostic for this is significantly better just by being a basic parse error: "expected a function pointer or path". It doesn't point the user to the right fix, but it does actually mention what the non-syntax-error cases would be: a fn pointer with lifetimes — or a pre-2021-unmarked-dyn (sigh).

Other cases

No response

Anything else?

Occurs on stable 1.73 and 1.76.0-nightly (2023-11-12 2b603f9)

@kpreid kpreid 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 Nov 13, 2023
@rustbot rustbot added the needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. label Nov 13, 2023
@compiler-errors compiler-errors self-assigned this Nov 13, 2023
@Noratrieb Noratrieb removed the needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. label Nov 14, 2023
compiler-errors added a commit to compiler-errors/rust that referenced this issue Nov 20, 2023
…=davidtwco

Recover `dyn` and `impl` after `for<...>`

Recover `dyn` and `impl` after `for<...>` in types. Reuses the logic for parsing bare trait objects, so it doesn't fix cases like `for<'a> dyn Trait   dyn Trait` or anything, but that seems somewhat of a different issue.

Parsing recovery logic is a bit involved, but I couldn't find a way to simplify it.

Fixes rust-lang#117882
@bors bors closed this as completed in a7f805d Nov 20, 2023
rust-timer added a commit to rust-lang-ci/rust that referenced this issue Nov 20, 2023
Rollup merge of rust-lang#117891 - compiler-errors:recover-for-dyn, r=davidtwco

Recover `dyn` and `impl` after `for<...>`

Recover `dyn` and `impl` after `for<...>` in types. Reuses the logic for parsing bare trait objects, so it doesn't fix cases like `for<'a> dyn Trait   dyn Trait` or anything, but that seems somewhat of a different issue.

Parsing recovery logic is a bit involved, but I couldn't find a way to simplify it.

Fixes rust-lang#117882
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.

4 participants