Repository: rust
Issue: [diagnostic] Add better diagnostic for Result types
Labels: A-diagnostics,T-compiler

<!--
Thank you for filing a bug report! 🐛 Please provide a short summary of the bug,
along with any information you feel relevant to replicating the bug.

If you cannot produce a minimal reproduction case (something that would work in
isolation), please provide the steps or even link to a repository that causes
the problematic output to occur.
-->

Given the following code: <!-- Please provide a link to play.rust-lang.org -->

```rust
fn parse_num(num: String) -> i32 {
    num.parse()
}
```

The current output is:

```
error[E0308]: mismatched types
 --> <source>:3:5
  |
2 | fn parse_num(num: String) -> i32 {
  |                              --- expected `i32` because of return type
3 |     num.parse() // 
  |     ^^^^^^^^^^^ expected `i32`, found enum `Result`
  |
  = note: expected type `i32`
             found enum `Result<_, _>`

error: aborting due to previous error

For more information about this error, try `rustc --explain E0308`.
Compiler returned: 1
```
https://godbolt.org/z/4KMY53974


<!-- The following is not always necessary. -->
Ideally the output should look like (suggestions appreciated):

```
error[E0308]: mismatched types
 --> parseInt.rs:2:5
  |
1 | pub fn parse_num(num: String) -> i32 {
  |                                  --- expected `i32` because of return type
2 |     num.parse()
  |     ^^^^^^^^^^^
  |     |
  |     expected `i32`, found enum `Result`
  |     help: Either change the return type to `Result<i32, std::num::ParseIntError>` or  use `unwrap`: `num.parse().unwrap()`
  |
  = note: expected type `i32`
             found enum `Result<_, _>`
For more information about this error, try `rustc --explain E0420`.

```

Rationale: 
Rust is known for its fantastic error messages.  One things that many Rust newcomers struggle with is `Result` vs. patterns in other languages (like throwing exceptions).  I feel like this specific situation occurs pretty frequently, so a specific diagnostic would be helpful.  
There's only so much explaining that can be done in a single `help:` line, so I think we should have a specific `rustc --explain` document going in-depth about how `Result` works, and different patterns you can do with it to help resolve common issues programmers have with `Result`.  (such as changing return types and different methods on `Result`)

### To suggest `unwrap` or not suggest `unwrap`:
I've thought a lot about this.

I think it's a difference in opinion.  I understand why someone wouldn't want to recommend `.unwrap()`, because if something can error (like  `String.parse()`)  you _should_ handle it.

Additionally, most of the people reading this message (who don't already know how to fix it) will be _learning_ how to fix it from here.  Since `unwrap` is the easiest (but non-idiomatic) solution, do we want to be teaching new Rust devs this?

That question isn't rhetorical.  I want to help Rust developers be unblocked.  If someone is learning Rust and is frustrated, I can see real value in telling them about `unwrap`.  They'll learn the right way eventually (right?) but for now let's unblock them.

On the other hand, suggesting "either change the return type to `Result` or use `.unwrap`" seems to _encourage_ this practice, and do we want every Rust dev to see this every time they return a `Result<T` when they wanted a `T`?

I think writing a blog/doc about _what_ `Result` is, and alllll the different methods on `Result` you can use to fix your problems, would be a good middle ground

...but it just feels odd that we _know_ something they can do to fix their problem (that's part of the language) but we purposefully **withhold** this information :information_source: 


tl;dr: I think suggesting `.unwrap()` is a **bad** idea because it's not something a Rust pro would do.

<!--
If dramatically different output is caused by small changes, consider also
adding them here.

If you're using the stable version of the compiler, you should also check if the
bug also exists in the beta or nightly versions. The output might also be
different depending on the Edition.
-->