Skip to content

Conversation

@Unique-Usman
Copy link
Contributor

No description provided.

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Jan 22, 2026
@rustbot
Copy link
Collaborator

rustbot commented Jan 22, 2026

r? @chenyukang

rustbot has assigned @chenyukang.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

@Unique-Usman
Copy link
Contributor Author

My approach seems not to be perfect and I have been stucked on this for a while. This is the issue this is supposed to fix - >#117977

@Unique-Usman Unique-Usman marked this pull request as draft January 22, 2026 15:06
@rustbot rustbot added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Jan 22, 2026
@Unique-Usman
Copy link
Contributor Author

@estebank

@rust-log-analyzer

This comment has been minimized.

@rust-bors

This comment has been minimized.

@Unique-Usman Unique-Usman marked this pull request as ready for review January 27, 2026 21:35
@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Jan 27, 2026
@Unique-Usman
Copy link
Contributor Author

r? @estebank

@rustbot rustbot assigned estebank and unassigned chenyukang Jan 27, 2026
@Unique-Usman
Copy link
Contributor Author

This is an improvement for

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

initially it gives

error: expected expression, found `let` statement
 --> foo.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
 --> foo.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
 --> foo.rs:3:8
  |
3 |       if let Some(_) = x
  |  ________^
4 | |         && Some(x) = x
  | |______________________^ expected `bool`, found `()`

error: aborting due to 3 previous errors

For more information about this error, try `rustc --explain E0308`.

but now it gives

error: expected expression, found `let` statement
 --> foo.rs:3:8
  |
3 |     if let Some(_) = x
  |        ^^^^^^^^^^^^^^^
  |
  = note: -Ztrack-diagnostics: created at compiler/rustc_parse/src/parser/expr.rs:4263:51
  = 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: aborting due to 1 previous error

@Unique-Usman
Copy link
Contributor Author

Interestingly,

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

still give the same result.

error: expected expression, found `let` statement
 --> foo.rs:4:12
  |
4 |         && let Some(x) = x
  |            ^^^
  |
  = note: only supported directly in conditions of `if` and `while` expressions

error[E0308]: mismatched types
 --> foo.rs:3:18
  |
3 |     if Some(_) = x
  |                  ^ expected `bool`, found `Option<{integer}>`
  |
  = note: expected type `bool`
             found enum `Option<{integer}>`

error[E0308]: mismatched types
 --> foo.rs:3:8
  |
3 |       if Some(_) = x
  |  ________^^^^^^^___-
  | |        |
  | |        expected `bool`, found `Option<_>`
4 | |         && let Some(x) = x
  | |__________________________- this expression has type `bool`
  |
  = note: expected type `bool`
             found enum `Option<_>`

error[E0308]: mismatched types
 --> foo.rs:3:8
  |
3 |       if Some(_) = x
  |  ________^
4 | |         && let Some(x) = x
  | |__________________________^ expected `bool`, found `()`
  |
help: consider adding `let`
  |
3 |     if let Some(_) = x
  |        +++

error: aborting due to 4 previous errors

For more information about this error, try `rustc --explain E0308`.

Copy link
Contributor

@estebank estebank left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure I follow your last comment. The diagnostic you're showing doesn't correspond with the code. I think you meant the following?

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

If so, this is the output I see:

error: expected expression, found `let` statement
 --> foo.rs:4:12
  |
4 |         && let Some(x) = x
  |            ^^^
  |
  = note: -Ztrack-diagnostics: created at /rustc-dev/4fa80a5e733e2202d7ca4c203c2fdfda41cfe7dc/compiler/rustc_parse/src/parser/expr.rs:2775:43
  = note: only supported directly in conditions of `if` and `while` expressions

error[E0308]: mismatched types
 --> foo.rs:3:18
  |
3 |     if Some(_) = x
  |                  ^ expected `bool`, found `Option<{integer}>`
  |
  = note: -Ztrack-diagnostics: created at /rustc-dev/4fa80a5e733e2202d7ca4c203c2fdfda41cfe7dc/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs:1905:35
  = note: expected type `bool`
             found enum `Option<{integer}>`

error[E0308]: mismatched types
 --> foo.rs:3:8
  |
3 |       if Some(_) = x
  |  ________^^^^^^^___-
  | |        |
  | |        expected `bool`, found `Option<_>`
4 | |         && let Some(x) = x
  | |__________________________- this expression has type `bool`
  |
  = note: -Ztrack-diagnostics: created at /rustc-dev/4fa80a5e733e2202d7ca4c203c2fdfda41cfe7dc/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs:1905:35
  = note: expected type `bool`
             found enum `Option<_>`

error[E0308]: mismatched types
 --> foo.rs:3:8
  |
3 |       if Some(_) = x
  |  ________^
4 | |         && let Some(x) = x
  | |__________________________^ expected `bool`, found `()`
  |
  = note: -Ztrack-diagnostics: created at /rustc-dev/4fa80a5e733e2202d7ca4c203c2fdfda41cfe7dc/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs:1905:35
help: consider adding `let`
  |
3 |     if let Some(_) = x
  |        +++

And I think it's coming from a different part of the parser, in parse_expr_let, so it would require different specific handling.

View changes since this review

Comment on lines 26 to 30
help: a function with a similar name exists
|
LL - if (i + j) = i {}
LL + if (a + j) = i {}
|
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unrelated: Noticing this suggestion and it is quite bad :-/

Comment on lines 25 to 37
error: binary assignment operation `+=` cannot be used in a let chain
--> $DIR/let-chains-assign-add-incorrect.rs:8:31
|
LL | if let _ = 1 && true && y += 2 {};
| ---------------------- ^^ cannot use `+=` in a let chain
| |
| you are add-assigning the right-hand side expression to the result of this let-chain
|
help: you might have meant to compare with `==` instead of assigning with `+=`
|
LL - if let _ = 1 && true && y += 2 {};
LL + if let _ = 1 && true && y == 2 {};
|
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change makes me think that we might want to restrict the silencing to cases where we had any suggestions. The need to remove the run-rustfix generally points at us giving less ideal output. That being said, this code as is is not great to begin with, and == would likely be intended... Can you see if we can make it so that we don't cause changes on this output while still silencing the others?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, that is valid. Looks quite weird to me also, I knew we had to do some restrictions, I will do that.

missing_let: self.missing_let,
comparison: self.comparison,
});
self.found_incorrect_let_chain = Some(guar);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think all you'd have to do is gate this behind missing_let or comparison being Some.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, thanks. I did gate it earlier, but not around Some parts, so it didn’t work. I’ll gate it around it now.

@Unique-Usman
Copy link
Contributor Author

I'm not sure I follow your last comment. The diagnostic you're showing doesn't correspond with the code. I think you meant the following?

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

If so, this is the output I see:

error: expected expression, found `let` statement
 --> foo.rs:4:12
  |
4 |         && let Some(x) = x
  |            ^^^
  |
  = note: -Ztrack-diagnostics: created at /rustc-dev/4fa80a5e733e2202d7ca4c203c2fdfda41cfe7dc/compiler/rustc_parse/src/parser/expr.rs:2775:43
  = note: only supported directly in conditions of `if` and `while` expressions

error[E0308]: mismatched types
 --> foo.rs:3:18
  |
3 |     if Some(_) = x
  |                  ^ expected `bool`, found `Option<{integer}>`
  |
  = note: -Ztrack-diagnostics: created at /rustc-dev/4fa80a5e733e2202d7ca4c203c2fdfda41cfe7dc/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs:1905:35
  = note: expected type `bool`
             found enum `Option<{integer}>`

error[E0308]: mismatched types
 --> foo.rs:3:8
  |
3 |       if Some(_) = x
  |  ________^^^^^^^___-
  | |        |
  | |        expected `bool`, found `Option<_>`
4 | |         && let Some(x) = x
  | |__________________________- this expression has type `bool`
  |
  = note: -Ztrack-diagnostics: created at /rustc-dev/4fa80a5e733e2202d7ca4c203c2fdfda41cfe7dc/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs:1905:35
  = note: expected type `bool`
             found enum `Option<_>`

error[E0308]: mismatched types
 --> foo.rs:3:8
  |
3 |       if Some(_) = x
  |  ________^
4 | |         && let Some(x) = x
  | |__________________________^ expected `bool`, found `()`
  |
  = note: -Ztrack-diagnostics: created at /rustc-dev/4fa80a5e733e2202d7ca4c203c2fdfda41cfe7dc/compiler/rustc_trait_selection/src/error_reYeahporting/infer/mod.rs:1905:35
help: consider adding `let`
  |
3 |     if let Some(_) = x
  |        +++

And I think it's coming from a different part of the parser, in parse_expr_let, so it would require different specific handling.

View changes since this review

Yeah, I meant this. Yeah, it needs to be handle in different part of the code.

Signed-off-by: Usman Akinyemi <usmanakinyemi202@gmail.com>
@estebank
Copy link
Contributor

@bors r+

@Unique-Usman would you want to take a look at improving the case that is left (where the first condition is an assignment/not a let and then a let is found later)? It is ok if you find that it might require a more significant refactor and then decide it isn't worth it.

@rust-bors
Copy link
Contributor

rust-bors bot commented Jan 28, 2026

📌 Commit 9ca8ed3 has been approved by estebank

It is now in the queue for this repository.

@rust-bors rust-bors bot added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Jan 28, 2026
@Unique-Usman
Copy link
Contributor Author

@bors r+

@Unique-Usman would you want to take a look at improving the case that is left (where the first condition is an assignment/not a let and then a let is found later)? It is ok if you find that it might require a more significant refactor and then decide it isn't worth it.

Definitely, I will take a look, thanks for the review.

@estebank estebank changed the title [RFC] rustc_parse: improve the error diagnostic for "missing let in let chain" rustc_parse: improve the error diagnostic for "missing let in let chain" Jan 28, 2026
rust-bors bot pushed a commit that referenced this pull request Jan 28, 2026
…uwer

Rollup of 12 pull requests

Successful merges:

 - #150491 (resolve: Mark items under exported ambiguous imports as exported)
 - #150720 (Do not suggest `derive` if there is already an impl)
 - #150968 (compiler-builtins: Remove the no-f16-f128 feature)
 - #151493 ([RFC] rustc_parse: improve the error diagnostic for "missing let in let chain")
 - #151660 (Bump `std`'s `backtrace`'s `rustc-demangle`)
 - #151696 (Borrowck: Simplify SCC annotation computation, placeholder rewriting)
 - #151704 (Implement `set_output_kind` for Emscripten linker)
 - #151706 (Remove Fuchsia from target OS list in unix.rs for sleep)
 - #151769 (fix undefined behavior in VecDeque::splice)
 - #151779 (stdarch subtree update)
 - #151449 ([rustdoc] Add regression test for #151411)
 - #151773 (clean up checks for constant promotion of integer division/remainder operations)
@rust-bors rust-bors bot merged commit 41caa6e into rust-lang:main Jan 29, 2026
11 checks passed
rust-timer added a commit that referenced this pull request Jan 29, 2026
Rollup merge of #151493 - Unique-Usman:ua/missinglet, r=estebank

[RFC] rustc_parse: improve the error diagnostic for "missing let in let chain"
github-actions bot pushed a commit to rust-lang/compiler-builtins that referenced this pull request Jan 29, 2026
…uwer

Rollup of 12 pull requests

Successful merges:

 - rust-lang/rust#150491 (resolve: Mark items under exported ambiguous imports as exported)
 - rust-lang/rust#150720 (Do not suggest `derive` if there is already an impl)
 - rust-lang/rust#150968 (compiler-builtins: Remove the no-f16-f128 feature)
 - rust-lang/rust#151493 ([RFC] rustc_parse: improve the error diagnostic for "missing let in let chain")
 - rust-lang/rust#151660 (Bump `std`'s `backtrace`'s `rustc-demangle`)
 - rust-lang/rust#151696 (Borrowck: Simplify SCC annotation computation, placeholder rewriting)
 - rust-lang/rust#151704 (Implement `set_output_kind` for Emscripten linker)
 - rust-lang/rust#151706 (Remove Fuchsia from target OS list in unix.rs for sleep)
 - rust-lang/rust#151769 (fix undefined behavior in VecDeque::splice)
 - rust-lang/rust#151779 (stdarch subtree update)
 - rust-lang/rust#151449 ([rustdoc] Add regression test for rust-lang/rust#151411)
 - rust-lang/rust#151773 (clean up checks for constant promotion of integer division/remainder operations)
tgross35 pushed a commit to rust-lang/compiler-builtins that referenced this pull request Jan 31, 2026
…uwer

Rollup of 12 pull requests

Successful merges:

 - rust-lang/rust#150491 (resolve: Mark items under exported ambiguous imports as exported)
 - rust-lang/rust#150720 (Do not suggest `derive` if there is already an impl)
 - rust-lang/rust#150968 (compiler-builtins: Remove the no-f16-f128 feature)
 - rust-lang/rust#151493 ([RFC] rustc_parse: improve the error diagnostic for "missing let in let chain")
 - rust-lang/rust#151660 (Bump `std`'s `backtrace`'s `rustc-demangle`)
 - rust-lang/rust#151696 (Borrowck: Simplify SCC annotation computation, placeholder rewriting)
 - rust-lang/rust#151704 (Implement `set_output_kind` for Emscripten linker)
 - rust-lang/rust#151706 (Remove Fuchsia from target OS list in unix.rs for sleep)
 - rust-lang/rust#151769 (fix undefined behavior in VecDeque::splice)
 - rust-lang/rust#151779 (stdarch subtree update)
 - rust-lang/rust#151449 ([rustdoc] Add regression test for rust-lang/rust#151411)
 - rust-lang/rust#151773 (clean up checks for constant promotion of integer division/remainder operations)
github-actions bot pushed a commit to rust-lang/stdarch that referenced this pull request Feb 5, 2026
…uwer

Rollup of 12 pull requests

Successful merges:

 - rust-lang/rust#150491 (resolve: Mark items under exported ambiguous imports as exported)
 - rust-lang/rust#150720 (Do not suggest `derive` if there is already an impl)
 - rust-lang/rust#150968 (compiler-builtins: Remove the no-f16-f128 feature)
 - rust-lang/rust#151493 ([RFC] rustc_parse: improve the error diagnostic for "missing let in let chain")
 - rust-lang/rust#151660 (Bump `std`'s `backtrace`'s `rustc-demangle`)
 - rust-lang/rust#151696 (Borrowck: Simplify SCC annotation computation, placeholder rewriting)
 - rust-lang/rust#151704 (Implement `set_output_kind` for Emscripten linker)
 - rust-lang/rust#151706 (Remove Fuchsia from target OS list in unix.rs for sleep)
 - rust-lang/rust#151769 (fix undefined behavior in VecDeque::splice)
 - rust-lang/rust#151779 (stdarch subtree update)
 - rust-lang/rust#151449 ([rustdoc] Add regression test for rust-lang/rust#151411)
 - rust-lang/rust#151773 (clean up checks for constant promotion of integer division/remainder operations)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants