Repository: rust
Issue: Provide pointer to escaped reference
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.
-->

This is a simplified version of the question reported at ebfull/pcap#193. The compiler error message didn't point the reporter to the bug in their code. `pcap`'s API make the problem worse because `Capture::next` doesn't directly return a reference, it returns a struct containing a reference, so it's not obvious from the function signature (`fn next(&mut self) -> Result<Packet>`) that a borrow is happening. I think it might be helpful in this case where the borrow occurred in the previous iteration of the loop to point to the place where the reference escaped the loop body (`packets.push(packet)`, in this case), though I'm not sure how hard that would be. 

Given the following code: <!-- Please provide a link to play.rust-lang.org -->

[Playground](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=a5e2c03c23a2e690db9f99aa2fc092cd)

```rust
use std::error::Error;

struct Packet<'a> {
    // some other fields...
    data: &'a [u8],
}

struct Capture {
    // In reality, there's an opaque handle to a libpcap capture object,
    // and libpcap's C code manages a buffer that's used to hold packet data.
    buf: Vec<u8>,
}

impl Capture {
    fn next(&mut self) -> Result<Packet, Box<dyn Error>> {
        // stuff happens to fill the buffer
        Ok(Packet { data: &self.buf })
    }
}

fn main() {
    let mut cap = Capture { buf: Vec::new() };
    let mut packets = Vec::new();
    while let Ok(packet) = cap.next() {
        packets.push(packet);
    }
    // do something with packets
}
```

The current output is:

```
   Compiling playground v0.0.1 (/playground)
error[E0499]: cannot borrow `cap` as mutable more than once at a time
  --> src/lib.rs:24:28
   |
24 |     while let Ok(packet) = cap.next() {
   |                            ^^^ `cap` was mutably borrowed here in the previous iteration of the loop

For more information about this error, try `rustc --explain E0499`.
error: could not compile `playground` due to previous error
```

<!-- The following is not always necessary. -->
Ideally the output should look like:

```
   Compiling playground v0.0.1 (/playground)
error[E0499]: cannot borrow `cap` as mutable more than once at a time
  --> src/lib.rs:24:28
   |
24 |     while let Ok(packet) = cap.next() {
   |                            ^^^ `cap` was mutably borrowed here in the previous iteration of the loop
25 |        packets.push(packet);
   |                     ^^^^^^ borrow escapes here

For more information about this error, try `rustc --explain E0499`.
error: could not compile `playground` due to previous error
```

I haven't put very much effort into the wording here, so feel free to have it say something completely different. The ultimate goal is to somehow point to the `packets` variable as being the reason the reference escapes the loop.

<!--
If the problem is not self-explanatory, please provide a rationale for the
change.
-->

<!--
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.
-->