about summary refs log tree commit diff
diff options
context:
space:
mode:
authorKeith Yeung <kungfukeith11@gmail.com>2017-09-24 03:56:57 -0700
committerKeith Yeung <kungfukeith11@gmail.com>2017-09-26 22:20:53 -0700
commit6d4989b821632086c7a84c36eedc8f55d1c878a4 (patch)
treefdc300d7fecdf4402294597de96a33c254232226
parentf71b37bc28326e272a37b938e835d4f99113eec2 (diff)
downloadrust-6d4989b821632086c7a84c36eedc8f55d1c878a4.tar.gz
rust-6d4989b821632086c7a84c36eedc8f55d1c878a4.zip
Add span label to E0384 for MIR borrowck
-rw-r--r--src/librustc_mir/borrow_check.rs30
-rw-r--r--src/test/compile-fail/borrowck/borrowck-match-binding-is-assignment.rs23
2 files changed, 42 insertions, 11 deletions
diff --git a/src/librustc_mir/borrow_check.rs b/src/librustc_mir/borrow_check.rs
index 9e261d60248..9201e0e2553 100644
--- a/src/librustc_mir/borrow_check.rs
+++ b/src/librustc_mir/borrow_check.rs
@@ -580,7 +580,19 @@ impl<'c, 'b, 'a: 'b+'c, 'gcx, 'tcx: 'a> MirBorrowckCtxt<'c, 'b, 'a, 'gcx, 'tcx>
             if flow_state.inits.curr_state.contains(&mpi) {
                 // may already be assigned before reaching this statement;
                 // report error.
-                self.report_illegal_reassignment(context, (lvalue, span));
+                // FIXME: Not ideal, it only finds the assignment that lexically comes first
+                let assigned_lvalue = &move_data.move_paths[mpi].lvalue;
+                let assignment_stmt = self.mir.basic_blocks().iter().filter_map(|bb| {
+                    bb.statements.iter().find(|stmt| {
+                        if let StatementKind::Assign(ref lv, _) = stmt.kind {
+                            *lv == *assigned_lvalue
+                        } else {
+                            false
+                        }
+                    })
+                }).next().unwrap();
+                self.report_illegal_reassignment(
+                    context, (lvalue, span), assignment_stmt.source_info.span);
             }
         }
     }
@@ -982,11 +994,17 @@ impl<'c, 'b, 'a: 'b+'c, 'gcx, 'tcx: 'a> MirBorrowckCtxt<'c, 'b, 'a, 'gcx, 'tcx>
         err.emit();
     }
 
-    fn report_illegal_reassignment(&mut self, _context: Context, (lvalue, span): (&Lvalue, Span)) {
-        let mut err = self.tcx.cannot_reassign_immutable(
-            span, &self.describe_lvalue(lvalue), Origin::Mir);
-        // FIXME: add span labels for borrow and assignment points
-        err.emit();
+    fn report_illegal_reassignment(&mut self,
+                                   _context: Context,
+                                   (lvalue, span): (&Lvalue, Span),
+                                   assigned_span: Span) {
+        self.tcx.cannot_reassign_immutable(span,
+                                           &self.describe_lvalue(lvalue),
+                                           Origin::Mir)
+                .span_label(span, "re-assignment of immutable variable")
+                .span_label(assigned_span, format!("first assignment to `{}`",
+                                                   self.describe_lvalue(lvalue)))
+                .emit();
     }
 
     fn report_assignment_to_static(&mut self, _context: Context, (lvalue, span): (&Lvalue, Span)) {
diff --git a/src/test/compile-fail/borrowck/borrowck-match-binding-is-assignment.rs b/src/test/compile-fail/borrowck/borrowck-match-binding-is-assignment.rs
index c219b7c5424..3639db5cfc4 100644
--- a/src/test/compile-fail/borrowck/borrowck-match-binding-is-assignment.rs
+++ b/src/test/compile-fail/borrowck/borrowck-match-binding-is-assignment.rs
@@ -8,6 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// revisions: ast mir
+//[mir]compile-flags: -Zemit-end-regions -Zborrowck-mir
+
 // Test that immutable pattern bindings cannot be reassigned.
 
 #![feature(slice_patterns)]
@@ -23,31 +26,41 @@ struct S {
 pub fn main() {
     match 1 {
         x => {
-            x += 1; //~ ERROR re-assignment of immutable variable `x`
+            x += 1; //[ast]~ ERROR re-assignment of immutable variable `x`
+                    //[mir]~^ ERROR (Mir) [E0384]
+                    //[mir]~| ERROR (Ast) [E0384]
         }
     }
 
     match E::Foo(1) {
         E::Foo(x) => {
-            x += 1; //~ ERROR re-assignment of immutable variable `x`
+            x += 1; //[ast]~ ERROR re-assignment of immutable variable `x`
+                    //[mir]~^ ERROR (Mir) [E0384]
+                    //[mir]~| ERROR (Ast) [E0384]
         }
     }
 
     match (S { bar: 1 }) {
         S { bar: x } => {
-            x += 1; //~ ERROR re-assignment of immutable variable `x`
+            x += 1; //[ast]~ ERROR re-assignment of immutable variable `x`
+                    //[mir]~^ ERROR (Mir) [E0384]
+                    //[mir]~| ERROR (Ast) [E0384]
         }
     }
 
     match (1,) {
         (x,) => {
-            x += 1; //~ ERROR re-assignment of immutable variable `x`
+            x += 1; //[ast]~ ERROR re-assignment of immutable variable `x`
+                    //[mir]~^ ERROR (Mir) [E0384]
+                    //[mir]~| ERROR (Ast) [E0384]
         }
     }
 
     match [1,2,3] {
         [x,_,_] => {
-            x += 1; //~ ERROR re-assignment of immutable variable `x`
+            x += 1; //[ast]~ ERROR re-assignment of immutable variable `x`
+                    //[mir]~^ ERROR (Mir) [E0384]
+                    //[mir]~| ERROR (Ast) [E0384]
         }
     }
 }