Skip to content

let-chains parsing is not resilient to stray ; between lets #117720

Closed
@estebank

Description

@estebank

Code

#![feature(let_chains)]
fn main() {
    if let () = ()
        && let () = ();
        && let () = ()
    {
    }
}

Current output

error: expected `{`, found `;`
 --> src/main.rs:4:23
  |
4 |         && let () = ();
  |                       ^ expected `{`
  |
note: the `if` expression is missing a block after this condition
 --> src/main.rs:3:8
  |
3 |       if let () = ()
  |  ________^
4 | |         && let () = ();
  | |______________________^

Desired output

error: expected `{`, found `;`
 --> src/main.rs:4:23
  |
4 |         && let () = ();
  |                       ^
  |                       |
  |                       expected `{`
  |                       help: remove it to parse the following `let` as part of the same chain
5 |         && let () = ()
  |         -------------- you likely meant to continue parsing the let-chain here

Rationale and extra context

This is a common typo I make when hoisting an inconditional let binding into the let chain to merge two let-chains that could be one. The parser only needs to do look-ahead 1 and 2 to detect the case and recover.

Other cases

No response

Anything else?

No response

Metadata

Metadata

Assignees

Labels

A-diagnosticsArea: Messages for errors, warnings, and lintsA-parserArea: The lexing & parsing of Rust source code to an ASTD-papercutDiagnostics: An error or lint that needs small tweaks.E-easyCall for participation: Easy difficulty. Experience needed to fix: Not much. Good first issue.F-let_chains`#![feature(let_chains)]`T-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