Repository: rust
Issue: Borrow checker bug when matching select().await with &mut references
Labels: A-borrow-checker,T-compiler,C-bug,A-async-await,AsyncAwait-Triaged

I've tried to simplify this example to the best of my abilities so here it goes. For some reason borrow checker doesn't treat match as taking ownership / consuming the argument:

```rust
async fn job(value: &mut usize) -> usize {
    *value
}

let mut value1 = 42;
let mut value2 = 42;
let mut future1 = Box::pin(job(&mut value1));
let mut future2 = Box::pin(job(&mut value2));

loop {
    let result = select(future1, future2).await;
    match result {
        Either::Left(e) => println!("{}", e.0),
        Either::Right(e) => println!("{}", e.0),
    }

    future1 = Box::pin(job(&mut value1)); // ERROR: cannot borrow `value1` as mutable more than once at a time [E0499]
    future2 = Box::pin(job(&mut value2)); // ERROR: cannot borrow `value1` as mutable more than once at a time [E0499]
}
```

The most weird thing I found is that this issue can be worked around with a very simple trick:
```rust
async fn job(value: &mut usize) -> usize {
    *value
}

fn noop<T>(value: T) -> T {
    value
}

let mut value1 = 42;
let mut value2 = 42;
let mut future1 = Box::pin(job(&mut value1));
let mut future2 = Box::pin(job(&mut value2));

loop {
    let result = select(future1, future2).await;
    match noop(result) { // explicitly consuming and returning result fixes borrowing errors
        Either::Left(e) => println!("{}", e.0),
        Either::Right(e) => println!("{}", e.0),
    }

    future1 = Box::pin(job(&mut value1)); // NO ERROR
    future2 = Box::pin(job(&mut value2)); // NO ERROR
}
```

I expected to see this happen:
Match must consume all &mut references and allow me to create new &mut references after it.

Instead, this happened:
It seams that borrow checker doesn't think that match consumed &mut references.

### Meta
Bug reproduces on both stable and nightly versions.

`rustc --version --verbose`:
```
rustc 1.71.0 (8ede3aae2 2023-07-12)
binary: rustc
commit-hash: 8ede3aae28fe6e4d52b38157d7bfe0d3bceef225
commit-date: 2023-07-12
host: aarch64-apple-darwin
release: 1.71.0
LLVM version: 16.0.5
```

<details><summary>Backtrace</summary>
<p>

```
    Blocking waiting for file lock on build directory
   Compiling futures-sink v0.3.28
   Compiling pin-project-lite v0.2.10
   Compiling pin-utils v0.1.0
   Compiling futures-core v0.3.28
   Compiling memchr v2.5.0
   Compiling futures-task v0.3.28
   Compiling futures-io v0.3.28
   Compiling slab v0.4.8
   Compiling futures-channel v0.3.28
   Compiling futures-util v0.3.28
   Compiling futures-executor v0.3.28
   Compiling futures v0.3.28
   Compiling rust-test v0.1.0 (/Users/matrixdev/Projects/rust-test)
error[E0499]: cannot borrow `value1` as mutable more than once at a time
  --> src/main.rs:20:32
   |
10 |     let mut future1 = Box::pin(job(&mut value1));
   |                                    ----------- first mutable borrow occurs here
...
20 |         future1 = Box::pin(job(&mut value1));
   |                                ^^^^^^^^^^^ second mutable borrow occurs here
21 |         future2 = Box::pin(job(&mut value2));
22 |     }
   |     - first borrow might be used here, when `result` is dropped and runs the destructor for type `Either<(usize, Pin<Box<impl futures::Future<Output = usize>>>), (usize, Pin<Box<impl futures::Future<Output = usize>>>)>`

error[E0499]: cannot borrow `value2` as mutable more than once at a time
  --> src/main.rs:21:32
   |
11 |     let mut future2 = Box::pin(job(&mut value2));
   |                                    ----------- first mutable borrow occurs here
...
21 |         future2 = Box::pin(job(&mut value2));
   |                                ^^^^^^^^^^^ second mutable borrow occurs here
22 |     }
   |     - first borrow might be used here, when `result` is dropped and runs the destructor for type `Either<(usize, Pin<Box<impl futures::Future<Output = usize>>>), (usize, Pin<Box<impl futures::Future<Output = usize>>>)>`

For more information about this error, try `rustc --explain E0499`.
error: could not compile `rust-test` (bin "rust-test") due to 2 previous errors
```

</p>
</details>