about summary refs log tree commit diff
diff options
context:
space:
mode:
authorDylan DPC <dylan.dpc@gmail.com>2020-05-05 01:49:32 +0200
committerGitHub <noreply@github.com>2020-05-05 01:49:32 +0200
commit4bde46e0e3a77d0ebf657aa110ff613130099ea7 (patch)
treec4e7cb4f4919c7757f4a6afa79a312124a34e714
parent2454a68cfbb63aa7b8e09fe05114d5f98b2f9740 (diff)
parent34eb2c1d4ff61693ab45863ee0f9ee298148a1ab (diff)
downloadrust-4bde46e0e3a77d0ebf657aa110ff613130099ea7.tar.gz
rust-4bde46e0e3a77d0ebf657aa110ff613130099ea7.zip
Rollup merge of #71587 - matthewjasper:promoted-move-errors, r=nikomatsakis
Report cannot move errors in promoted MIR

Closes #70934
-rw-r--r--src/librustc_mir/borrow_check/mod.rs48
-rw-r--r--src/test/ui/borrowck/move-error-in-promoted-2.rs10
-rw-r--r--src/test/ui/borrowck/move-error-in-promoted-2.stderr12
-rw-r--r--src/test/ui/borrowck/move-error-in-promoted.rs17
-rw-r--r--src/test/ui/borrowck/move-error-in-promoted.stderr12
5 files changed, 93 insertions, 6 deletions
diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs
index 7d8a2b540a9..b19d035ab04 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<Vec<(Place<'tcx>, 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 00000000000..13da34f3922
--- /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 00000000000..38dba94bdd4
--- /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 00000000000..b94db645131
--- /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 00000000000..a4432e38da0
--- /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`.