about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMatthew Jasper <mjjasper1@gmail.com>2018-07-22 21:38:31 +0100
committerMatthew Jasper <mjjasper1@gmail.com>2018-07-26 22:06:12 +0100
commitb32caef1ad605c8607ad0c3ccc682f6536f0e812 (patch)
tree1529de7a35c7002ae024a94448d815c227c2a89b
parent71637c293768052e73940a0eb1ddb71ce9d24c40 (diff)
downloadrust-b32caef1ad605c8607ad0c3ccc682f6536f0e812.tar.gz
rust-b32caef1ad605c8607ad0c3ccc682f6536f0e812.zip
Use better spans for cannot-move errors
-rw-r--r--src/librustc_mir/borrow_check/move_errors.rs43
-rw-r--r--src/test/ui/issue-20801.nll.stderr20
-rw-r--r--src/test/ui/nll/cannot-move-block-spans.nll.stderr85
-rw-r--r--src/test/ui/nll/cannot-move-block-spans.rs32
-rw-r--r--src/test/ui/nll/cannot-move-block-spans.stderr58
5 files changed, 210 insertions, 28 deletions
diff --git a/src/librustc_mir/borrow_check/move_errors.rs b/src/librustc_mir/borrow_check/move_errors.rs
index 4aa38fb5f37..215ade5bd4d 100644
--- a/src/librustc_mir/borrow_check/move_errors.rs
+++ b/src/librustc_mir/borrow_check/move_errors.rs
@@ -87,6 +87,10 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
                 cannot_move_out_of: IllegalMoveOrigin { location, kind },
             } => {
                 let stmt_source_info = self.mir.source_info(location);
+                // Note: that the only time we assign a place isn't a temporary
+                // to a user variable is when initializing it.
+                // If that ever stops being the case, then the ever initialized
+                // flow could be used.
                 if let Some(StatementKind::Assign(
                     Place::Local(local),
                     Rvalue::Use(Operand::Move(move_from)),
@@ -109,26 +113,16 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
                         opt_ty_info: _,
                     }))) = local_decl.is_user_variable
                     {
-                        // HACK use scopes to determine if this assignment is
-                        // the initialization of a variable.
-                        // FIXME(matthewjasper) This would probably be more
-                        // reliable if it used the ever initialized dataflow
-                        // but move errors are currently reported before the
-                        // rest of borrowck has run.
-                        if self
-                            .mir
-                            .is_sub_scope(local_decl.source_info.scope, stmt_source_info.scope)
-                        {
-                            self.append_binding_error(
-                                grouped_errors,
-                                kind,
-                                move_from,
-                                *local,
-                                opt_match_place,
-                                match_span,
-                            );
-                            return;
-                        }
+                        self.append_binding_error(
+                            grouped_errors,
+                            kind,
+                            move_from,
+                            *local,
+                            opt_match_place,
+                            match_span,
+                            stmt_source_info.span,
+                        );
+                        return;
                     }
                 }
                 grouped_errors.push(GroupedMoveError::OtherIllegalMove {
@@ -147,6 +141,7 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
         bind_to: Local,
         match_place: &Option<Place<'tcx>>,
         match_span: Span,
+        statement_span: Span,
     ) {
         debug!(
             "append_to_grouped_errors(match_place={:?}, match_span={:?})",
@@ -173,13 +168,13 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
                 debug!("found a new move error location");
 
                 // Don't need to point to x in let x = ... .
-                let binds_to = if from_simple_let {
-                    vec![]
+                let (binds_to, span) = if from_simple_let {
+                    (vec![], statement_span)
                 } else {
-                    vec![bind_to]
+                    (vec![bind_to], match_span)
                 };
                 grouped_errors.push(GroupedMoveError::MovesFromMatchPlace {
-                    span: match_span,
+                    span,
                     move_from: match_place.clone(),
                     kind,
                     binds_to,
diff --git a/src/test/ui/issue-20801.nll.stderr b/src/test/ui/issue-20801.nll.stderr
index 0394309a6e2..fc94cc423c5 100644
--- a/src/test/ui/issue-20801.nll.stderr
+++ b/src/test/ui/issue-20801.nll.stderr
@@ -2,25 +2,37 @@ error[E0507]: cannot move out of borrowed content
   --> $DIR/issue-20801.rs:36:22
    |
 LL |     let a = unsafe { *mut_ref() };
-   |                      ^^^^^^^^^^ cannot move out of borrowed content
+   |                      ^^^^^^^^^^
+   |                      |
+   |                      cannot move out of borrowed content
+   |                      help: consider using a reference instead: `&*mut_ref()`
 
 error[E0507]: cannot move out of borrowed content
   --> $DIR/issue-20801.rs:39:22
    |
 LL |     let b = unsafe { *imm_ref() };
-   |                      ^^^^^^^^^^ cannot move out of borrowed content
+   |                      ^^^^^^^^^^
+   |                      |
+   |                      cannot move out of borrowed content
+   |                      help: consider using a reference instead: `&*imm_ref()`
 
 error[E0507]: cannot move out of borrowed content
   --> $DIR/issue-20801.rs:42:22
    |
 LL |     let c = unsafe { *mut_ptr() };
-   |                      ^^^^^^^^^^ cannot move out of borrowed content
+   |                      ^^^^^^^^^^
+   |                      |
+   |                      cannot move out of borrowed content
+   |                      help: consider using a reference instead: `&*mut_ptr()`
 
 error[E0507]: cannot move out of borrowed content
   --> $DIR/issue-20801.rs:45:22
    |
 LL |     let d = unsafe { *const_ptr() };
-   |                      ^^^^^^^^^^^^ cannot move out of borrowed content
+   |                      ^^^^^^^^^^^^
+   |                      |
+   |                      cannot move out of borrowed content
+   |                      help: consider using a reference instead: `&*const_ptr()`
 
 error: aborting due to 4 previous errors
 
diff --git a/src/test/ui/nll/cannot-move-block-spans.nll.stderr b/src/test/ui/nll/cannot-move-block-spans.nll.stderr
new file mode 100644
index 00000000000..814e11b6f06
--- /dev/null
+++ b/src/test/ui/nll/cannot-move-block-spans.nll.stderr
@@ -0,0 +1,85 @@
+error[E0507]: cannot move out of borrowed content
+  --> $DIR/cannot-move-block-spans.rs:15:15
+   |
+LL |     let x = { *r }; //~ ERROR
+   |               ^^
+   |               |
+   |               cannot move out of borrowed content
+   |               help: consider removing this dereference operator: `r`
+
+error[E0507]: cannot move out of borrowed content
+  --> $DIR/cannot-move-block-spans.rs:16:22
+   |
+LL |     let y = unsafe { *r }; //~ ERROR
+   |                      ^^
+   |                      |
+   |                      cannot move out of borrowed content
+   |                      help: consider removing this dereference operator: `r`
+
+error[E0507]: cannot move out of borrowed content
+  --> $DIR/cannot-move-block-spans.rs:17:26
+   |
+LL |     let z = loop { break *r; }; //~ ERROR
+   |                          ^^
+   |                          |
+   |                          cannot move out of borrowed content
+   |                          help: consider removing this dereference operator: `r`
+
+error[E0508]: cannot move out of type `[std::string::String; 2]`, a non-copy array
+  --> $DIR/cannot-move-block-spans.rs:21:15
+   |
+LL |     let x = { arr[0] }; //~ ERROR
+   |               ^^^^^^
+   |               |
+   |               cannot move out of here
+   |               help: consider using a reference instead: `&arr[0]`
+
+error[E0508]: cannot move out of type `[std::string::String; 2]`, a non-copy array
+  --> $DIR/cannot-move-block-spans.rs:22:22
+   |
+LL |     let y = unsafe { arr[0] }; //~ ERROR
+   |                      ^^^^^^
+   |                      |
+   |                      cannot move out of here
+   |                      help: consider using a reference instead: `&arr[0]`
+
+error[E0508]: cannot move out of type `[std::string::String; 2]`, a non-copy array
+  --> $DIR/cannot-move-block-spans.rs:23:26
+   |
+LL |     let z = loop { break arr[0]; }; //~ ERROR
+   |                          ^^^^^^
+   |                          |
+   |                          cannot move out of here
+   |                          help: consider using a reference instead: `&arr[0]`
+
+error[E0507]: cannot move out of borrowed content
+  --> $DIR/cannot-move-block-spans.rs:27:38
+   |
+LL |     let x = { let mut u = 0; u += 1; *r }; //~ ERROR
+   |                                      ^^
+   |                                      |
+   |                                      cannot move out of borrowed content
+   |                                      help: consider removing this dereference operator: `r`
+
+error[E0507]: cannot move out of borrowed content
+  --> $DIR/cannot-move-block-spans.rs:28:45
+   |
+LL |     let y = unsafe { let mut u = 0; u += 1; *r }; //~ ERROR
+   |                                             ^^
+   |                                             |
+   |                                             cannot move out of borrowed content
+   |                                             help: consider removing this dereference operator: `r`
+
+error[E0507]: cannot move out of borrowed content
+  --> $DIR/cannot-move-block-spans.rs:29:49
+   |
+LL |     let z = loop { let mut u = 0; u += 1; break *r; u += 2; }; //~ ERROR
+   |                                                 ^^
+   |                                                 |
+   |                                                 cannot move out of borrowed content
+   |                                                 help: consider removing this dereference operator: `r`
+
+error: aborting due to 9 previous errors
+
+Some errors occurred: E0507, E0508.
+For more information about an error, try `rustc --explain E0507`.
diff --git a/src/test/ui/nll/cannot-move-block-spans.rs b/src/test/ui/nll/cannot-move-block-spans.rs
new file mode 100644
index 00000000000..5a84a4ca48e
--- /dev/null
+++ b/src/test/ui/nll/cannot-move-block-spans.rs
@@ -0,0 +1,32 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Test that the we point to the inner expression when moving out to initialize
+// a variable, and that we don't give a useless suggestion such as &{ *r }.
+
+pub fn deref(r: &String) {
+    let x = { *r }; //~ ERROR
+    let y = unsafe { *r }; //~ ERROR
+    let z = loop { break *r; }; //~ ERROR
+}
+
+pub fn index(arr: [String; 2]) {
+    let x = { arr[0] }; //~ ERROR
+    let y = unsafe { arr[0] }; //~ ERROR
+    let z = loop { break arr[0]; }; //~ ERROR
+}
+
+pub fn additional_statement_cases(r: &String) {
+    let x = { let mut u = 0; u += 1; *r }; //~ ERROR
+    let y = unsafe { let mut u = 0; u += 1; *r }; //~ ERROR
+    let z = loop { let mut u = 0; u += 1; break *r; u += 2; }; //~ ERROR
+}
+
+fn main() {}
diff --git a/src/test/ui/nll/cannot-move-block-spans.stderr b/src/test/ui/nll/cannot-move-block-spans.stderr
new file mode 100644
index 00000000000..d4956900239
--- /dev/null
+++ b/src/test/ui/nll/cannot-move-block-spans.stderr
@@ -0,0 +1,58 @@
+error[E0507]: cannot move out of borrowed content
+  --> $DIR/cannot-move-block-spans.rs:15:15
+   |
+LL |     let x = { *r }; //~ ERROR
+   |               ^^ cannot move out of borrowed content
+
+error[E0507]: cannot move out of borrowed content
+  --> $DIR/cannot-move-block-spans.rs:16:22
+   |
+LL |     let y = unsafe { *r }; //~ ERROR
+   |                      ^^ cannot move out of borrowed content
+
+error[E0507]: cannot move out of borrowed content
+  --> $DIR/cannot-move-block-spans.rs:17:26
+   |
+LL |     let z = loop { break *r; }; //~ ERROR
+   |                          ^^ cannot move out of borrowed content
+
+error[E0508]: cannot move out of type `[std::string::String; 2]`, a non-copy array
+  --> $DIR/cannot-move-block-spans.rs:21:15
+   |
+LL |     let x = { arr[0] }; //~ ERROR
+   |               ^^^^^^ cannot move out of here
+
+error[E0508]: cannot move out of type `[std::string::String; 2]`, a non-copy array
+  --> $DIR/cannot-move-block-spans.rs:22:22
+   |
+LL |     let y = unsafe { arr[0] }; //~ ERROR
+   |                      ^^^^^^ cannot move out of here
+
+error[E0508]: cannot move out of type `[std::string::String; 2]`, a non-copy array
+  --> $DIR/cannot-move-block-spans.rs:23:26
+   |
+LL |     let z = loop { break arr[0]; }; //~ ERROR
+   |                          ^^^^^^ cannot move out of here
+
+error[E0507]: cannot move out of borrowed content
+  --> $DIR/cannot-move-block-spans.rs:27:38
+   |
+LL |     let x = { let mut u = 0; u += 1; *r }; //~ ERROR
+   |                                      ^^ cannot move out of borrowed content
+
+error[E0507]: cannot move out of borrowed content
+  --> $DIR/cannot-move-block-spans.rs:28:45
+   |
+LL |     let y = unsafe { let mut u = 0; u += 1; *r }; //~ ERROR
+   |                                             ^^ cannot move out of borrowed content
+
+error[E0507]: cannot move out of borrowed content
+  --> $DIR/cannot-move-block-spans.rs:29:49
+   |
+LL |     let z = loop { let mut u = 0; u += 1; break *r; u += 2; }; //~ ERROR
+   |                                                 ^^ cannot move out of borrowed content
+
+error: aborting due to 9 previous errors
+
+Some errors occurred: E0507, E0508.
+For more information about an error, try `rustc --explain E0507`.