diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs index 7c7251c913492..a548b6b4c37cd 100644 --- a/src/librustc_mir/borrow_check/mod.rs +++ b/src/librustc_mir/borrow_check/mod.rs @@ -180,11 +180,14 @@ fn do_mir_borrowck<'a, 'tcx>( let location_table = &LocationTable::new(&body); let mut errors_buffer = Vec::new(); - let (move_data, move_errors): (MoveData<'tcx>, Option, MoveError<'tcx>)>>) = + let (move_data, move_errors): (MoveData<'tcx>, Vec<(Place<'tcx>, MoveError<'tcx>)>) = match MoveData::gather_moves(&body, tcx, param_env) { - Ok(move_data) => (move_data, None), - Err((move_data, move_errors)) => (move_data, Some(move_errors)), + Ok(move_data) => (move_data, Vec::new()), + Err((move_data, move_errors)) => (move_data, move_errors), }; + let promoted_errors = promoted + .iter_enumerated() + .map(|(idx, body)| (idx, MoveData::gather_moves(&body, tcx, param_env))); let mdpe = MoveDataParamEnv { move_data, param_env }; @@ -264,6 +267,41 @@ fn do_mir_borrowck<'a, 'tcx>( _ => true, }; + for (idx, move_data_results) in promoted_errors { + let promoted_body = &promoted[idx]; + let dominators = promoted_body.dominators(); + + if let Err((move_data, move_errors)) = move_data_results { + let mut promoted_mbcx = MirBorrowckCtxt { + infcx, + body: promoted_body, + mir_def_id: def_id.to_def_id(), + move_data: &move_data, + location_table: &LocationTable::new(promoted_body), + movable_generator, + locals_are_invalidated_at_exit, + access_place_error_reported: Default::default(), + reservation_error_reported: Default::default(), + reservation_warnings: Default::default(), + move_error_reported: BTreeMap::new(), + uninitialized_error_reported: Default::default(), + errors_buffer, + regioncx: regioncx.clone(), + used_mut: Default::default(), + used_mut_upvars: SmallVec::new(), + borrow_set: borrow_set.clone(), + dominators, + upvars: Vec::new(), + local_names: IndexVec::from_elem(None, &promoted_body.local_decls), + region_names: RefCell::default(), + next_region_name: RefCell::new(1), + polonius_output: None, + }; + promoted_mbcx.report_move_errors(move_errors); + errors_buffer = promoted_mbcx.errors_buffer; + }; + } + let dominators = body.dominators(); let mut mbcx = MirBorrowckCtxt { @@ -301,9 +339,7 @@ fn do_mir_borrowck<'a, 'tcx>( borrows: flow_borrows, }; - if let Some(errors) = move_errors { - mbcx.report_move_errors(errors); - } + mbcx.report_move_errors(move_errors); dataflow::visit_results( &body, diff --git a/src/test/ui/borrowck/move-error-in-promoted-2.rs b/src/test/ui/borrowck/move-error-in-promoted-2.rs new file mode 100644 index 0000000000000..13da34f3922c2 --- /dev/null +++ b/src/test/ui/borrowck/move-error-in-promoted-2.rs @@ -0,0 +1,10 @@ +// Regression test for #70934 + +struct S; + +fn foo() { + &([S][0],); + //~^ ERROR cannot move out of type `[S; 1]` +} + +fn main() {} diff --git a/src/test/ui/borrowck/move-error-in-promoted-2.stderr b/src/test/ui/borrowck/move-error-in-promoted-2.stderr new file mode 100644 index 0000000000000..38dba94bdd41b --- /dev/null +++ b/src/test/ui/borrowck/move-error-in-promoted-2.stderr @@ -0,0 +1,12 @@ +error[E0508]: cannot move out of type `[S; 1]`, a non-copy array + --> $DIR/move-error-in-promoted-2.rs:6:7 + | +LL | &([S][0],); + | ^^^^^^ + | | + | cannot move out of here + | move occurs because value has type `S`, which does not implement the `Copy` trait + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0508`. diff --git a/src/test/ui/borrowck/move-error-in-promoted.rs b/src/test/ui/borrowck/move-error-in-promoted.rs new file mode 100644 index 0000000000000..b94db64513123 --- /dev/null +++ b/src/test/ui/borrowck/move-error-in-promoted.rs @@ -0,0 +1,17 @@ +// Regression test for #70934 + +fn f() { + const C: [S2; 1] = [S2]; + let _ = S1(C[0]).clone(); + //~^ ERROR cannot move out of type `[S2; 1]` +} + +#[derive(Clone)] +struct S1(S2); + +#[derive(Clone)] +struct S2; + +fn main() { + f(); +} diff --git a/src/test/ui/borrowck/move-error-in-promoted.stderr b/src/test/ui/borrowck/move-error-in-promoted.stderr new file mode 100644 index 0000000000000..a4432e38da0e4 --- /dev/null +++ b/src/test/ui/borrowck/move-error-in-promoted.stderr @@ -0,0 +1,12 @@ +error[E0508]: cannot move out of type `[S2; 1]`, a non-copy array + --> $DIR/move-error-in-promoted.rs:5:16 + | +LL | let _ = S1(C[0]).clone(); + | ^^^^ + | | + | cannot move out of here + | move occurs because value has type `S2`, which does not implement the `Copy` trait + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0508`.