Skip to content

Conversation

estebank
Copy link
Contributor

@estebank estebank commented Aug 18, 2025

During let binding parse error and encountering a block, detect if there is a likely missing if or else:

error: expected one of `.`, `;`, `?`, `else`, or an operator, found `{`
  --> $DIR/missing-if-let-or-let-else.rs:14:25
   |
LL |     let Some(x) = foo() {
   |                         ^ expected one of `.`, `;`, `?`, `else`, or an operator
   |
help: you might have meant to use `if let`
   |
LL |     if let Some(x) = foo() {
   |     ++
help: alternatively, you might have meant to use `let else`
   |
LL |     let Some(x) = foo() else {
   |                         ++++

Fix #107806.

@rustbot
Copy link
Collaborator

rustbot commented Aug 18, 2025

r? @SparrowLii

rustbot has assigned @SparrowLii.
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

@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 Aug 18, 2025
@chenyukang
Copy link
Member

I'd like to have a review on it
r? @chenyukang

@rust-log-analyzer

This comment has been minimized.

During `let` binding parse error and encountering a block, detect if there is a likely missing `if` or `else`:

```
error: expected one of `.`, `;`, `?`, `else`, or an operator, found `{`
  --> $DIR/missing-if-let-or-let-else.rs:14:25
   |
LL |     let Some(x) = foo() {
   |                         ^ expected one of `.`, `;`, `?`, `else`, or an operator
   |
help: you might have meant to use `if let`
   |
LL |     if let Some(x) = foo() {
   |     ++
help: alternatively, you might have meant to use `let else`
   |
LL |     let Some(x) = foo() else {
   |                         ++++
```
@estebank
Copy link
Contributor Author

If we wanted to improve the handling of these, then we would have to actually add a new error recovery AST node, with all the information that an if-let would have and perform validation at the resolve or HIR stage. The purely parser approach I think is likely at the right trade-off between complexity and results.

|
help: you might have meant to use `let else`
|
LL | let Some(x) = foo() else {
Copy link
Member

Choose a reason for hiding this comment

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

if we suggest add else here, a following error missing ; will comes after applying the fix.

Copy link
Member

Choose a reason for hiding this comment

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

so the correct code maybe:

 let Some(x) = foo() else { 
        return;
 };  // need `;` here

i'm not sure whether we should also suggest the ; at the same time, maybe goes too far.

Copy link
Member

Choose a reason for hiding this comment

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

emm, this code is also valid 😀

fn b() {
    if let Some(x) = foo() {
        return;
    };
}

}
true
});
// Collect all bindings in pattern and see if they appear in the block. Likely meant
Copy link
Member

Choose a reason for hiding this comment

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

nit: maybe we should move the definition of IdentFinder to here, since it's only used in this function. Otherwise IdentFinder is a too general visitor name.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
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.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Parse error on let followed by a block should suggest likely alternatives if-let or let-else
5 participants