Repository: rust
Issue: Suggest `slice::from_ref` on mismatched reference errors related to `[x].iter()`
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: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=50dffed5d14b18cdf6a1661a34c1d000

```rust
enum VecOrOption<T> {
    Vec(Vec<T>),
    Option(Option<T>)
}

fn foo<'a>(v: &'a VecOrOption<u32>) -> impl Iterator<Item=&'a u32> {
    match v {
        VecOrOption::Vec(v) => v.iter(),
        VecOrOption::Option(Some(s)) => [s].iter(),
        _ => (&[]).iter()
    }
}
```

The current output is:

```
error[[E0308]](https://doc.rust-lang.org/stable/error-index.html#E0308): `match` arms have incompatible types
  --> src/lib.rs:9:41
   |
7  | /     match v {
8  | |         VecOrOption::Vec(v) => v.iter(),
   | |                                -------- this is found to be of type `std::slice::Iter<'_, u32>`
9  | |         VecOrOption::Option(Some(s)) => [s].iter(),
   | |                                         ^^^^^^^^^^ expected `u32`, found `&u32`
10 | |         _ => (&[]).iter()
11 | |     }
   | |_____- `match` arms have incompatible types
   |
   = note: expected struct `std::slice::Iter<'_, u32>`
              found struct `std::slice::Iter<'_, &u32>`
```

<!-- The following is not always necessary. -->
Ideally the output should look like:

```
error[[E0308]](https://doc.rust-lang.org/stable/error-index.html#E0308): `match` arms have incompatible types
  --> src/lib.rs:9:41
   |
7  | /     match v {
8  | |         VecOrOption::Vec(v) => v.iter(),
   | |                                -------- this is found to be of type `std::slice::Iter<'_, u32>`
9  | |         VecOrOption::Option(Some(s)) => [s].iter(),
   | |                                         ^^^^^^^^^^ expected `u32`, found `&u32`
10 | |         _ => (&[]).iter()
11 | |     }
   | |_____- `match` arms have incompatible types
   |
   = note: expected struct `std::slice::Iter<'_, u32>`
  |          found struct `std::slice::Iter<'_, &u32>`
  |
  = help: use `slice::from_ref` instead: `slice::from_ref(s).iter()` 
```

<!--
If the problem is not self-explanatory, please provide a rationale for the
change.
-->

The problem here comes from creating a new temporary array and returning an iterator that references it. Creating a slice instead avoids the issue, but is very hard to discover; it's not immediately obvious that a function `&T -> &[T]` would exist. It would be nice to point people to it directly.

This should only trigger when the slice is one element, and only when that element is already a reference.

Consider also the borrowck version of this, which fixes the type error above:
```rust
fn foo<'a>(v: &'a VecOrOption<u32>) -> impl Iterator<Item=&'a u32> {
    match v {
        VecOrOption::Vec(v) => v.iter(),
        VecOrOption::Option(Some(s)) => [*s].iter(),
        _ => (&[]).iter()
    }
}
```
```
error[E0308]: `match` arms have incompatible types
  --> src/lib.rs:9:41
   |
7  | /     match v {
8  | |         VecOrOption::Vec(v) => v.iter(),
   | |                                -------- this is found to be of type `std::slice::Iter<'_, u32>`
9  | |         VecOrOption::Option(Some(s)) => [s].iter(),
   | |                                         ^^^^^^^^^^ expected `u32`, found `&u32`
10 | |         _ => (&[]).iter()
11 | |     }
   | |_____- `match` arms have incompatible types
   |
   = note: expected struct `std::slice::Iter<'_, u32>`
              found struct `std::slice::Iter<'_, &u32>`
```