Account for an additional reborrow inserted by UniqueImmBorrow and MutBorrow
diff --git a/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs b/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs
index d94441b..320d8fd3 100644
--- a/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs
+++ b/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs
@@ -289,10 +289,15 @@
// generating, we also are taking that field by value. Peel off a deref,
// since a layer of reffing has now become redundant.
let final_deref = if needs_deref {
- let [mir::ProjectionElem::Deref] = projection else {
- bug!("There should only be a single deref for an upvar local initialization");
+ let Some((mir::ProjectionElem::Deref, projection)) = projection.split_first()
+ else {
+ bug!(
+ "There should be at least a single deref for an upvar local initialization, found {projection:#?}"
+ );
};
- &[]
+ // There may be more derefs, since we may also implicitly reborrow
+ // a captured mut pointer.
+ projection
} else {
projection
};
diff --git a/tests/ui/async-await/async-closures/mut-ref-reborrow.rs b/tests/ui/async-await/async-closures/mut-ref-reborrow.rs
new file mode 100644
index 0000000..9f2cbd7
--- /dev/null
+++ b/tests/ui/async-await/async-closures/mut-ref-reborrow.rs
@@ -0,0 +1,27 @@
+//@ aux-build:block-on.rs
+//@ run-pass
+//@ check-run-results
+//@ revisions: e2021 e2018
+//@[e2018] edition:2018
+//@[e2021] edition:2021
+
+#![feature(async_closure)]
+
+extern crate block_on;
+
+async fn call_once(f: impl async FnOnce()) { f().await; }
+
+pub async fn async_closure(x: &mut i32) {
+ let c = async move || {
+ *x += 1;
+ };
+ call_once(c).await;
+}
+
+fn main() {
+ block_on::block_on(async {
+ let mut x = 0;
+ async_closure(&mut x).await;
+ assert_eq!(x, 1);
+ });
+}