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

Improve "if and else have incompatible types" error #57348

Closed
estebank opened this issue Jan 4, 2019 · 2 comments
Closed

Improve "if and else have incompatible types" error #57348

estebank opened this issue Jan 4, 2019 · 2 comments
Labels
A-diagnostics Area: Messages for errors, warnings, and lints

Comments

@estebank
Copy link
Contributor

estebank commented Jan 4, 2019

When if and else arms have incompatible types, like below, the compiler should point at both arms with the evaluated type and also suggest removal of trailing semicolon if relevant.

fn main() {
    let a = if false { "x" } else { "y"; };
}

Current:

error[E0308]: if and else have incompatible types
 --> src/main.rs:2:13
  |
2 |     let a = if false { "x" } else { "y"; };
  |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected &str, found ()
  |
  = note: expected type `&str`
             found type `()`

Suggested:

error[E0308]: if and else have incompatible types
 --> src/main.rs:2:13
  |
2 |     let a = if false { "x" } else { "y"; };
  |                        ---          ^^^- help: remove this semicolon
  |                        |              |
  |                        |              expected &str, found ()
  |                        this arm evaluates to &str
  = note: expected type `&str`
             found type `()`

Example taken from lessons learned in Converting a Python library to Rust article

@estebank estebank added the A-diagnostics Area: Messages for errors, warnings, and lints label Jan 4, 2019
@ishitatsuyuki
Copy link
Contributor

I think we don't even need the "expected type" and "found type" lines here. The biggest issue is that "expected" and "found" are unclear and doesn't easily map to "if" and "else" arms, so we should move to "this arm has" completely.

@estebank
Copy link
Contributor Author

estebank commented Jan 5, 2019

It would be a good time to give this error its own error code, where we can document the behavior in a teachable way, instead of lumping it into the generic "type mismatch" bag.

bors added a commit that referenced this issue Jan 14, 2019
Tweak output of type mismatch between "then" and `else` `if` arms

```
error[E0308]: if and else have incompatible types
  --> $DIR/if-else-type-mismatch.rs:5:9
   |
LL |       let _ = if true {
   |  _____________-
LL | |         42i32
   | |         ----- expected because of this
LL | |     } else {
LL | |         42u32
   | |         ^^^^^ expected i32, found u32
LL | |     };
   | |_____- if and else have incompatible types
   |
   = note: expected type `i32`
              found type `u32`

error[E0308]: if and else have incompatible types
  --> file.rs:2:38
   |
LL |     let _ = if false { 3u8; } else { 3u8 };
   |                        ----          ^^^ expected (), found u8
   |                        |  |
   |                        |  help: consider removing this semicolon
   |                        expected because of this
   |
   = note: expected type `()`
              found type `u8`

error[E0308]: if and else have incompatible types
  --> file.rs:3:37
   |
LL |     let _ = if false { 3u8 } else { 3u8; };
   |                        ---          ^^^-
   |                        |            |  |
   |                        |            |  help: consider removing this semicolon
   |                        |            expected u8, found ()
   |                        expected because of this
   |
   = note: expected type `u8`
              found type `()`

error[E0308]: if and else have incompatible types
  --> file.rs:4:37
   |
LL |     let _ = if false { 3i8 } else { 3u8 };
   |                        ---          ^^^ expected i8, found u8
   |                        |
   |                        expected because of this
   |
   = note: expected type `i8`
              found type `u8`
```

Fix #57348.
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
Projects
None yet
Development

No branches or pull requests

2 participants