Repository: rust
Issue: Misleading compiler errors from match expressions inside loops with branches of infallible
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 -->

https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=83112e42531e00a584b38696d5997e54

```rust
enum MyEnum {
    First,
    Second,
    Third,
    Fourth,
}

fn main() {
    let a = MyEnum::First;

    for _ in 0..1 {
        match a {
            First => Err(()),
            Second => Ok(()),
            Third => {
                todo!()
            }
            _ => Ok(()),
        }
    }
}
```

The current output is:

```
error[E0308]: `match` arms have incompatible types
  --> src/main.rs:16:17
   |
12 | /         match a {
13 | |             First => Err(()),
   | |                      ------- this is found to be of type `std::result::Result<(), ()>`
14 | |             Second => Ok(()),
   | |                       ------ this is found to be of type `std::result::Result<(), ()>`
15 | |             Third => {
16 | |                 todo!()
   | |                 ^^^^^^^ expected enum `std::result::Result`, found `()`
17 | |             }
18 | |             _ => Ok(()),
19 | |         }
   | |_________- `match` arms have incompatible types
   |
   = note:   expected enum `std::result::Result<(), ()>`
           found unit type `()`
   = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
help: try using a variant of the expected enum
   |
15 |             Third => Ok({
16 |                 todo!()
17 |             })
   |
15 |             Third => Err({
16 |                 todo!()
17 |             })
   |

error: aborting due to previous error
```

<!--
If the problem is not self-explanatory, please provide a rationale for the
change.
-->

I suspect the infallible branch is instead assigned the type `()` due to the expected type from the for loop. Causing the misleading help and arrows. 

Changing `todo!()` into `Ok(())` produces the expected error output of:
```
error[E0308]: mismatched types
  --> src/main.rs:12:9
   |
12 | /         match a {
13 | |             First => Err(()),
14 | |             Second => Ok(()),
15 | |             Third => Ok(()),
16 | |             _ => Ok(()),
17 | |         }
   | |         ^- help: try adding a semicolon: `;`
   | |_________|
   |           expected `()`, found enum `std::result::Result`
   |
   = note: expected unit type `()`
                   found enum `std::result::Result<(), ()>`

error: aborting due to previous error
```

<!--
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.
-->