Repository: rust
Issue: Unhelpful (misleading?) diagnostic when a type that must implement `'static` bound and `Iterator` trait are conflicting requirements.
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.
-->

## Code
Given the following code: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=b562df48ba9075e56f954f71ac031d2c

```rust
use core::marker::PhantomData;

struct Foo<C> {
    _marker: PhantomData<C>,
}

impl<Coord: Clone + 'static> Iterator for Foo<Coord> {
    type Item = ();

    fn next(&mut self) -> Option<Self::Item> {
        unimplemented!()
    }
}

impl<Coord> Foo<Coord> {
    pub fn new<I: IntoIterator<Item = Coord>>(_iter: I) -> Self {
        unimplemented!()
    }
}

impl<Coord> Default for Foo<Coord> {
    fn default() -> Self {
        unimplemented!()
    }
}

fn main() {
    let res = vec![(0, 0), (1, 1), (2, 4), (3, 9)];
    let res_x = res.iter().map(|(x, _)| x).collect::<Vec<&u32>>();
    let res_y = res.iter().map(|(_, y)| y).collect::<Vec<&u32>>();

    let my_foo = Foo::new(res_x.iter().zip(res_y.iter()));
    consume_iter(my_foo);
    
    // This is fine.
    // let my_foo2: Foo<(&&u32, &&u32)> = Default::default();
    //consume_iter(my_foo2);
}

fn consume_iter<E, I>(_series: I) where I: IntoIterator<Item = E> {
    unimplemented!()
}
```

## Output
The current output is:

```
   Compiling playground v0.0.1 (/playground)
error[E0597]: `res` does not live long enough
  --> src/main.rs:29:17
   |
29 |     let res_x = res.iter().map(|(x, _)| x).collect::<Vec<&u32>>();
   |                 ^^^                     - returning this value requires that `res` is borrowed for `'static`
   |                 |
   |                 borrowed value does not live long enough
...
38 | }
   | - `res` dropped here while still borrowed

error[E0597]: `res` does not live long enough
  --> src/main.rs:30:17
   |
30 |     let res_y = res.iter().map(|(_, y)| y).collect::<Vec<&u32>>();
   |                 ^^^                     - returning this value requires that `res` is borrowed for `'static`
   |                 |
   |                 borrowed value does not live long enough
...
38 | }
   | - `res` dropped here while still borrowed

error[E0597]: `res_x` does not live long enough
  --> src/main.rs:32:27
   |
32 |     let my_foo = Foo::new(res_x.iter().zip(res_y.iter()));
   |                           ^^^^^-------
   |                           |
   |                           borrowed value does not live long enough
   |                           argument requires that `res_x` is borrowed for `'static`
...
38 | }
   | - `res_x` dropped here while still borrowed

error[E0597]: `res_y` does not live long enough
  --> src/main.rs:32:44
   |
32 |     let my_foo = Foo::new(res_x.iter().zip(res_y.iter()));
   |                                            ^^^^^-------
   |                                            |
   |                                            borrowed value does not live long enough
   |                                            argument requires that `res_y` is borrowed for `'static`
...
38 | }
   | - `res_y` dropped here while still borrowed

For more information about this error, try `rustc --explain E0597`.
error: could not compile `playground` due to 4 previous errors
```

## What Is Happening
I'm not sure what the error output of this should look like offhand. However, I spent an hour minimizing the above from my actual code before it became obvious what the actual problem is with my code. The actual problem is that "`Foo<(&&u32, &&u32)>` cannot implement `'static`, and therefore cannot implement `Iterator` based on `Coord: Clone + 'static` bound. An error like "this type cannot simultaneously implement `'static` and `Iterator` based on the requirements of `Foo::new()`" would've made debugging far more quick.

What Rust appears to be doing is trying to extend the lifetimes contained within the return value from the `zip` call to `'static` (`&'static &'static u32`). This allows `Iterator` to be implemented, but will fail once the borrow checker runs with the above 4 errors.

## Analysis Of Errors
I don't think any of the 4 errors are particularly helpful:

>returning this value requires that `res` is borrowed for `'static`

Neither of these errors are anywhere close to the site where the `'static` bound is required in `Foo::new()`. Additionally, I don't see how specifically returning _this_ value requires that `res` is borrowed for `'static`. It's only when `res_x` and `res_y` are used in `Foo:new()` that the requirement for a `'static` bound _propagates back up_ to the assignments to `res_x` and `res_y` that borrow `res`. Assigning to `res_x` and `res_y` isn't a problem in and of itself AFAICT.

>argument requires that `res_y` is borrowed for `'static`

The carets made me think that the `res_x.iter()` or `res_x.iter().zip()` call<sup>1</sup> was to blame, but this seems like another case where the requirement for a `'static` bound propagates up from passing the expression into `Foo::new()`.

>argument requires that `res_x` is borrowed for `'static`

This puts the carets in the correct place, but `res_x` made me think that there was something wrong with using `res_x` specifically, rather than "passing in the return type of the expression `res_x.iter().zip(res_y.iter())` to `Foo::new()` is to blame". If I saw carets and dashes<sup>1</sup> over the entire expression, I think I would've figured out the problem more quickly.

1. What is the logic behind the number of carets/dashes when printing a diagnostic, btw? I'm not sure whether the carets _and_ dashes are supposed to provide context or just the carets.