Repository: rust
Issue: Cannot return value from loop when temporary mutable access occurs before.
Labels: A-borrow-checker,C-bug,T-types,fixed-by-polonius

<!--
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.
-->

I tried this code:

```rust

struct A {
    buf: [u8; 32],
}

struct Ref<'a> {
    slice: &'a [u8]
}

pub fn mkref(buf: &[u8]) -> Option<Ref> {
    Some(Ref {
        slice: &buf[1..8]
    })
}

impl A {
    // Borrowck error
    pub fn read<'a>(&'a mut self) -> Option<Ref<'a>> {
        loop {
            self.buf.rotate_left(4);

            match mkref(&self.buf) {
                Some(rf) => return Some(rf),
                None => continue,
            }

        }

        None
    }

    // Borrowck error
    pub fn read_break<'a>(&'a mut self) -> Option<Ref<'a>> {
        let r = loop {
            self.buf.rotate_left(4);

            match mkref(&self.buf) {
                Some(rf) => break Some(rf),
                None => continue,
            }
        };

        r
    }

    // OK
    pub fn read_inline<'a>(&'a mut self) -> Option<Ref<'a>> {
        loop {
            self.buf.rotate_left(4);

            return Some(Ref { slice: &self.buf[..] });
        }

        None
    }

    // OK
    pub fn read_noloop<'a>(&'a mut self) -> Option<Ref<'a>> {
        self.buf.rotate_left(4);

        match mkref(&self.buf) {
            Some(rf) => return Some(rf),
            None => return None,
        }
    }
}

```

I expected to see this happen: No errors

Instead, this happened: Cannot return value from loop when temporary mutable access occurs before.
```
error[E0502]: cannot borrow `self.buf` as mutable because it is also borrowed as immutable
  --> src/lib.rs:23:13
   |
21 |     pub fn read<'a>(&'a mut self) -> Option<Ref<'a>> {
   |                 -- lifetime `'a` defined here
22 |         loop {
23 |             self.buf.rotate_left(4);
   |             ^^^^^^^^ mutable borrow occurs here
24 |
25 |             match mkref(&self.buf) {
   |                         --------- immutable borrow occurs here
26 |                 Some(rf) => return Some(rf),
   |                                    -------- returning this value requires that `self.buf` is borrowed for `'a`

error[E0502]: cannot borrow `self.buf` as mutable because it is also borrowed as immutable
  --> src/lib.rs:38:13
   |
36 |     pub fn read_break<'a>(&'a mut self) -> Option<Ref<'a>> {
   |                       -- lifetime `'a` defined here
37 |         let r = loop {
38 |             self.buf.rotate_left(4);
   |             ^^^^^^^^ mutable borrow occurs here
39 |
40 |             match mkref(&self.buf) {
   |                         --------- immutable borrow occurs here
...
46 |         r
   |         - returning this value requires that `self.buf` is borrowed for `'a`
```

### Meta
<!--
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.
-->

`rustc --version --verbose`:
```
rustc 1.85.0-nightly (dff3e7ccd 2024-11-26)
binary: rustc
commit-hash: dff3e7ccd4a18958c938136c4ccdc853fcc86194
commit-date: 2024-11-26
host: x86_64-pc-windows-msvc
release: 1.85.0-nightly
LLVM version: 19.1.4
```


</p>
</details>