Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

let_chains and typo of == to = produce bad diagnostic #97469

Closed
estebank opened this issue May 27, 2022 · 1 comment
Closed

let_chains and typo of == to = produce bad diagnostic #97469

estebank opened this issue May 27, 2022 · 1 comment
Assignees
Labels
A-diagnostics Area: Messages for errors, warnings, and lints D-confusing Diagnostics: Confusing error or lint that should be reworked. D-newcomer-roadblock Diagnostics: Confusing error or lint; hard to understand for new users. D-verbose Diagnostics: Too much output caused by a single piece of incorrect code. F-let_chains `#![feature(let_chains)]` T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@estebank
Copy link
Contributor

I wrote code like

                            let qself_res = if let hir::TyKind::Path(hir::QPath::Resolved(_, ref path)) = qself.kind 
                                && let [segment] = path.segments
                                && kw::SelfUpper = segment.ident.name
                            {

when I meant

                            let qself_res = if let hir::TyKind::Path(hir::QPath::Resolved(_, ref path)) = qself.kind 
                                && let [segment] = path.segments
                                && kw::SelfUpper == segment.ident.name
                            {

and was confused by the rust-analyzer and rustc output:

error: `let` expressions are not supported here
    --> compiler/rustc_typeck/src/astconv/mod.rs:1812:48
     |
1812 | ...                   let qself_res = if let hir::TyKind::Path(hir::QPath::Resolved(_, ref path)) = qself.kind 
     |                                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
     |
     = note: only supported directly in conditions of `if` and `while` expressions
     = note: as well as when nested within `&&` and parentheses in those conditions

error: `let` expressions are not supported here
    --> compiler/rustc_typeck/src/astconv/mod.rs:1813:36
     |
1813 | ...                   && let [segment] = path.segments
     |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
     |
     = note: only supported directly in conditions of `if` and `while` expressions
     = note: as well as when nested within `&&` and parentheses in those conditions

error[E0433]: failed to resolve: use of undeclared crate or module `kw`
    --> compiler/rustc_typeck/src/astconv/mod.rs:1814:36
     |
1814 | ...                   && kw::SelfUpper = segment.ident.name
     |                          ^^ use of undeclared crate or module `kw`

error[E0308]: mismatched types
    --> compiler/rustc_typeck/src/astconv/mod.rs:1812:48
     |
1812 |   ...                   let qself_res = if let hir::TyKind::Path(hir::QPath::Resolved(_, ref path)) = qself.kind 
     |  __________________________________________^
1813 | | ...                       && let [segment] = path.segments
1814 | | ...                       && kw::SelfUpper = segment.ident.name
     | |_______________________________________________________________^ expected `bool`, found `()`
     |
help: you might have meant to use pattern matching
     |
1812 |                             let qself_res = if let let hir::TyKind::Path(hir::QPath::Resolved(_, ref path)) = qself.kind 
     |                                                +++
@estebank estebank added A-diagnostics Area: Messages for errors, warnings, and lints T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. D-confusing Diagnostics: Confusing error or lint that should be reworked. D-newcomer-roadblock Diagnostics: Confusing error or lint; hard to understand for new users. F-let_chains `#![feature(let_chains)]` D-verbose Diagnostics: Too much output caused by a single piece of incorrect code. labels May 27, 2022
@estebank estebank changed the title let_chains and typo of == to `= produce bad diagnostic let_chains and typo of == to = produce bad diagnostic May 27, 2022
@TaKO8Ki TaKO8Ki self-assigned this Oct 5, 2022
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this issue Oct 6, 2022
…=estebank

Suggest `==` to wrong assign expr

Given the following code:

```rust
fn main() {
    let x = 3;
    let y = 3;
    if x == x && y = y {
        println!("{}", x);
    }
}
```

Current output is:

```
error[E0308]: mismatched types
 --> src/main.rs:4:18
  |
4 |     if x == x && y = y {
  |                  ^ expected `bool`, found integer

error[E0308]: mismatched types
 --> src/main.rs:4:8
  |
4 |     if x == x && y = y {
  |        ^^^^^^^^^^^^^^^ expected `bool`, found `()`
```

This adds a suggestion:

```diff
error[E0308]: mismatched types
 --> src/main.rs:6:18
  |
6 |     if x == x && y = y {
  |                  ^ expected `bool`, found integer

error[E0308]: mismatched types
 --> src/main.rs:6:8
  |
6 |     if x == x && y = y {
  |        ^^^^^^^^^^^^^^^ expected `bool`, found `()`
  |
+ help: you might have meant to compare for equality
+   |
+ 6 |     if x == x && y == y {
+   |                     +
```

And this fixes a part of rust-lang#97469
@Lee-Janggun
Copy link
Contributor

I can confirm the following code now produces the more helpful error:
https://play.rust-lang.org/?version=nightly&mode=release&edition=2021&gist=cc13cfcbb4f7aa698bec48eb1c63af52

#![feature(let_chains)]

fn temp(b1 : bool, b2 : bool, o1 : Option<usize>, o2 : Option<usize>) -> Option<usize> {
    let res = if let Some(u1) = o1 
                  && let Some(u2) = o2 
                  && b1 = b2
                {
                    Some(u1 + u2)
                } else {
                    None
                };
                    
    res
}
Compiling playground v0.0.1 (/playground)
error: `let` expressions are not supported here
 --> src/lib.rs:4:18
  |
4 |     let res = if let Some(u1) = o1 && let Some(u2) = o2 && b1 = b2
  |                  ^^^^^^^^^^^^^^^^^
  |
  = note: only supported directly in conditions of `if` and `while` expressions

error: `let` expressions are not supported here
 --> src/lib.rs:4:39
  |
4 |     let res = if let Some(u1) = o1 && let Some(u2) = o2 && b1 = b2
  |                                       ^^^^^^^^^^^^^^^^^
  |
  = note: only supported directly in conditions of `if` and `while` expressions

error[[E0308]](https://doc.rust-lang.org/nightly/error-index.html#E0308): mismatched types
 --> src/lib.rs:4:18
  |
4 |     let res = if let Some(u1) = o1 && let Some(u2) = o2 && b1 = b2
  |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `bool`, found `()`
  |
help: you might have meant to compare for equality
  |
4 |     let res = if let Some(u1) = o1 && let Some(u2) = o2 && b1 == b2
  |                                                                +

For more information about this error, try `rustc --explain E0308`.
error: could not compile `playground` due to 3 previous errors

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-diagnostics Area: Messages for errors, warnings, and lints D-confusing Diagnostics: Confusing error or lint that should be reworked. D-newcomer-roadblock Diagnostics: Confusing error or lint; hard to understand for new users. D-verbose Diagnostics: Too much output caused by a single piece of incorrect code. F-let_chains `#![feature(let_chains)]` T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

3 participants