Skip to content

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

Closed
@kpreid

Description

@kpreid

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)

Metadata

Metadata

Labels

A-diagnosticsArea: Messages for errors, warnings, and lintsT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions