Skip to content

Commit ad0fcac

Browse files
Account for an additional reborrow inserted by UniqueImmBorrow and MutBorrow
1 parent 49c4ebc commit ad0fcac

File tree

2 files changed

+35
-3
lines changed

2 files changed

+35
-3
lines changed

compiler/rustc_mir_transform/src/coroutine/by_move_body.rs

+8-3
Original file line numberDiff line numberDiff line change
@@ -289,10 +289,15 @@ impl<'tcx> MutVisitor<'tcx> for MakeByMoveBody<'tcx> {
289289
// generating, we also are taking that field by value. Peel off a deref,
290290
// since a layer of reffing has now become redundant.
291291
let final_deref = if needs_deref {
292-
let [mir::ProjectionElem::Deref] = projection else {
293-
bug!("There should only be a single deref for an upvar local initialization");
292+
let Some((mir::ProjectionElem::Deref, projection)) = projection.split_first()
293+
else {
294+
bug!(
295+
"There should be at least a single deref for an upvar local initialization, found {projection:#?}"
296+
);
294297
};
295-
&[]
298+
// There may be more derefs, since we may also implicitly reborrow
299+
// a captured mut pointer.
300+
projection
296301
} else {
297302
projection
298303
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
//@ aux-build:block-on.rs
2+
//@ run-pass
3+
//@ check-run-results
4+
//@ revisions: e2021 e2018
5+
//@[e2018] edition:2018
6+
//@[e2021] edition:2021
7+
8+
#![feature(async_closure)]
9+
10+
extern crate block_on;
11+
12+
async fn call_once(f: impl async FnOnce()) { f().await; }
13+
14+
pub async fn async_closure(x: &mut i32) {
15+
let c = async move || {
16+
*x += 1;
17+
};
18+
call_once(c).await;
19+
}
20+
21+
fn main() {
22+
block_on::block_on(async {
23+
let mut x = 0;
24+
async_closure(&mut x).await;
25+
assert_eq!(x, 1);
26+
});
27+
}

0 commit comments

Comments
 (0)