Repository: rust
Issue: Better help message for "Mismatched types" [E0308] when the issue is function implicitly returning `()`
Labels: A-diagnostics,T-compiler

While working through [rustlings](https://github.com/rust-lang/rustlings) I noticed a place where the error Rust prints is unclear unless you already know more or less what the problem is.

Given the following code: [[playground](https://play.rust-lang.org/?version=stable&mode=release&edition=2021&gist=63f7359f8201cb656f63f74c7f01db39)] [this is a cut-down version of [rustlings/exercises/functions/functions5.rs](https://github.com/rust-lang/rustlings/blob/main/exercises/functions/functions5.rs); the point of the exercise is to familiarize people with the error that I'm about to suggest improvements to]

```rust
pub fn square (n: i32) -> i32 {
    n * n;
}
```

The current output is:

```
error[E0308]: mismatched types
 --> src/lib.rs:1:27
  |
1 | pub fn square (n: i32) -> i32 {
  |        ------             ^^^ expected `i32`, found `()`
  |        |
  |        implicitly returns `()` as its body has no tail or `return` expression
2 |     n * n;
  |          - help: remove this semicolon

For more information about this error, try `rustc --explain E0308`.
```

The problem with this is, if you're _completely_ new to the language you may have no idea what `()` means in this context, you may be unfamiliar with the difference between an "expression" and a "statement", and you may not know what a "tail" is or why, in Rust, putting a semicolon after (what appears to be) the last expression in a block makes it _not be_ the last expression in that block.  "expected `i32`, found `()`" with a pointer to the token `i32` confuses things further.

The `--explain` output for E0308 is all about _why it doesn't work to have mismatched types_, which is fine for more typical cases where you'd get E0308 (e.g. `"string" + 23`) but in _this_ case what the programmer is probably wondering is _why there would be a type mismatch in the first place_ in this code.

The error message for

```rust
pub fn returns_val() -> i32 {
    return;
}
```

is much clearer and I would like to suggest that this case of E0308 be reworked along those lines: something like

```
error[E????]: empty tail expression in a function whose return type is not `()`
 --> src/lib.rs:2:10
1 | pub fn square (n: i32) -> i32 {
  |                           --- expected `i32` because of this return type
2 |     n * n;
  |          | ^ this empty expression makes `square` implicitly return `()`
  |          - help: remove this semicolon
```

Note: If the function is completely empty you get almost the same confusing error as the original example:

```rust
pub fn returns_val () -> i32 {}
```

produces

```
error[E0308]: mismatched types
 --> src/lib.rs:1:26
  |
1 | pub fn returns_val () -> i32 {}
  |        -----------       ^^^ expected `i32`, found `()`
  |        |
  |        implicitly returns `()` as its body has no tail or `return` expression
```

Here I suggest

```
error[E????]: empty body in a function whose return type is not `()`
 --> src/lib.rs:1:26
  |
1 | pub fn returns_val () -> i32 {}
  |                          |   ^^ empty function body
  |                          --- expected `i32` because of this return type
```