Repository: rust
Issue: Misleading borrow checker error when accidentally creating self-referential lifetimes
Labels: A-diagnostics,A-borrow-checker,T-compiler,D-confusing

Given the following code:

```rust
use std::borrow::Cow;

struct Buffer {
    buf: Vec<u8>,
    frames: Vec<Message<'static>>,
}

impl Buffer {
    fn pop(&mut self) {
        let mut reader = Reader::new(&self.buf);
        let msg = Message {
            payload: Payload::parse(&mut reader),
        };
        self.frames.push(msg);
        self.buf = self.buf.split_off(10);
    }
}

struct Reader<'a> {
    buf: &'a [u8],
}

impl<'a> Reader<'a> {
    fn new(_: &'a [u8]) -> Self {
        todo!()
    }
}

struct Message<'a> {
    payload: Payload<'a>,
}

struct Payload<'a> {
    data: Cow<'a, [u8]>,
}

impl<'a> Payload<'a> {
    fn parse(_: &mut Reader<'a>) -> Self {
        todo!()
    }
}
```

([Playground](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=31c7a14c81699b4f4ca1b12d48c9ca09).)

The current output is:

```rust
error[[E0521]](https://doc.rust-lang.org/stable/error-index.html#E0521): borrowed data escapes outside of associated function
  --> src/lib.rs:10:26
   |
9  |     fn pop(&mut self) {
   |            ---------
   |            |
   |            `self` is a reference that is only valid in the associated function body
   |            let's call the lifetime of this reference `'1`
10 |         let mut reader = Reader::new(&self.buf);
   |                          ^^^^^^^^^^^^^^^^^^^^^^
   |                          |
   |                          `self` escapes the associated function body here
   |                          argument requires that `'1` must outlive `'static`

error[[E0506]](https://doc.rust-lang.org/stable/error-index.html#E0506): cannot assign to `self.buf` because it is borrowed
  --> src/lib.rs:15:9
   |
10 |         let mut reader = Reader::new(&self.buf);
   |                          ----------------------
   |                          |           |
   |                          |           borrow of `self.buf` occurs here
   |                          argument requires that `self.buf` is borrowed for `'static`
...
15 |         self.buf = self.buf.split_off(10);
   |         ^^^^^^^^ assignment to borrowed `self.buf` occurs here

error[[E0502]](https://doc.rust-lang.org/stable/error-index.html#E0502): cannot borrow `self.buf` as mutable because it is also borrowed as immutable
  --> src/lib.rs:15:20
   |
10 |         let mut reader = Reader::new(&self.buf);
   |                          ----------------------
   |                          |           |
   |                          |           immutable borrow occurs here
   |                          argument requires that `self.buf` is borrowed for `'static`
...
15 |         self.buf = self.buf.split_off(10);
   |                    ^^^^^^^^^^^^^^^^^^^^^^ mutable borrow occurs here

Some errors have detailed explanations: E0502, E0506, E0521.
For more information about an error, try `rustc --explain E0502`.
```

This threw for a loop for quite a long time until I started reducing it in order to file this issue, and realized that I missed that it was essentially creating self-referential borrows by pushing a type containing a reference to `&self.buf` into `self.frames`. However, none of the diagnostics above point to the `self.frames.push()` line, which IMO is the salient issue here. The first one notably points to `&self.buf` "escaping the function body" when instantiating the `Reader` in the function stack. Since the reader itself does not escape the function body at all, that also confused me quite a bit.