rust-lang / rust-lang/rust

let-chain with missing `let` in the middle causes multiple errors

Open
#117,977 5 comments 4 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

A-diagnostics D-papercut D-verbose F-let_chains P-low T-compiler
Dominant language
Rust
Stars
119k
Forks
16.2k
PR merge metrics
PR metrics pending

Description

Edit: only remaining case is eliminating the first error in

fn main() {
    let x = Some(42);
    if Some(_) = x
        && let Some(x) = x
    {}
}
error: expected expression, found `let` statement
 --> src/main.rs:4:12
  |
4 |         && let Some(x) = x
  |            ^^^
  |
  = note: only supported directly in conditions of `if` and `while` expressions

error: let-chain with missing `let`
 --> src/main.rs:3:8
  |
3 |     if Some(_) = x
  |        ^^^^^^^----
  |        |
  |        expected `let` expression, found assignment
4 |         && let Some(x) = x
  |            --------------- let expression later in the condition
  |
help: add `let` before the expression
  |
3 |     if let Some(_) = x
  |        +++

Code
fn main() {
    let x = Some(42);
    if let Some(_) = x
        && Some(x) = x
    {}
}
Current output

Update:

error: expected expression, found `let` statement
 --> src/main.rs:3:8
  |
3 |     if let Some(_) = x
  |        ^^^^^^^^^^^^^^^
  |
  = note: only supported directly in conditions of `if` and `while` expressions
help: you might have meant to continue the let-chain
  |
4 |         && let Some(x) = x
  |            +++
help: you might have meant to compare for equality
  |
4 |         && Some(x) == x
  |                     +

error[E0308]: mismatched types
 --> src/main.rs:4:12
  |
4 |         && Some(x) = x
  |            ^^^^^^^ expected `bool`, found `Option<Option<{integer}>>`
  |
  = note: expected type `bool`
             found enum `Option<Option<{integer}>>`
help: use `Option::is_some` to test if the `Option` has a value
  |
4 |         && Some(x).is_some() = x
  |                   ++++++++++

error[E0308]: mismatched types
 --> src/main.rs:3:8
  |
3 |       if let Some(_) = x
  |  ________^
4 | |         && Some(x) = x
  | |______________________^ expected `bool`, found `()`

Previously:

error: expected expression, found `let` statement
 --> src/main.rs:3:8
  |
3 |     if let Some(_) = x
  |        ^^^^^^^^^^^^^^^
  |
  = note: only supported directly in conditions of `if` and `while` expressions

error[E0308]: mismatched types
 --> src/main.rs:4:12
  |
4 |         && Some(x) = x
  |            ^^^^^^^ expected `bool`, found `Option<Option<{integer}>>`
  |
  = note: expected type `bool`
             found enum `Option<Option<{integer}>>`
help: use `Option::is_some` to test if the `Option` has a value
  |
4 |         && Some(x).is_some() = x
  |                   ++++++++++

error[E0308]: mismatched types
 --> src/main.rs:3:8
  |
3 |       if let Some(_) = x
  |  ________^
4 | |         && Some(x) = x
  | |______________________^ expected `bool`, found `()`
Desired output

Edit: we now provide appropriate suggestions in the first diagnostic, but we should notice that this should have been a let chain and silence the E0308 errors.

error: let-chain with missing `let`
 --> src/main.rs:3:8
  |
3 |     if let Some(_) = x
  |        --------------- let-chain starting here
4 |         && Some(x) = x
  |            ^^^^^^^^^^^ expected `let` expression, found assignment
  |
help: add `let` before the expression
  |
4 |         && let Some(x) = x
  |            +++
Rationale and extra context

No response

Other cases

No response

Anything else?

No response

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the Rust reproducer in src/main.rs and compare its compiler diagnostics with the linked Rust Playground example. Trace the let-chain diagnostic handling for a missing let in the middle of a condition. Done means the missing-let diagnostic is retained and the resulting E0308 errors are silenced.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
compilers
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
52/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.