about summary refs log tree commit diff
diff options
context:
space:
mode:
authorBasile Desloges <basile.desloges@gmail.com>2017-10-05 11:03:32 +0200
committerBasile Desloges <basile.desloges@gmail.com>2017-10-06 17:44:50 +0200
commitef2f42d04a4c83dd5b50cd672b8a1b0791e00f98 (patch)
tree52daa15a1bfa1fd09d14a9b1aeb3e5e355ad564d
parent456e12ec38f669b26b08414527ee1dc35091da33 (diff)
downloadrust-ef2f42d04a4c83dd5b50cd672b8a1b0791e00f98.tar.gz
rust-ef2f42d04a4c83dd5b50cd672b8a1b0791e00f98.zip
mir-borrowck: Autoderef values followed by a constant index, and fix reported lvalue for constant index
Previously the constant index was reported as `[x of y]` or `[-x of y]` where
`x` was the offset and `y` the minimum length of the slice. The minus sign
wasn't in the right case since for `&[_, x, .., _, _]`, the error reported was
`[-1 of 4]`, and for `&[_, _, .., x, _]`, the error reported was `[2 of 4]`.
This commit fixes the sign so that the indexes 1 and -2 are reported, and
remove the ` of y` part of the message to make it more succinct.
-rw-r--r--src/librustc_mir/borrow_check.rs12
-rw-r--r--src/test/compile-fail/borrowck/borrowck-describe-lvalue.rs35
2 files changed, 43 insertions, 4 deletions
diff --git a/src/librustc_mir/borrow_check.rs b/src/librustc_mir/borrow_check.rs
index 18bb78ef50f..85ecb9d6e36 100644
--- a/src/librustc_mir/borrow_check.rs
+++ b/src/librustc_mir/borrow_check.rs
@@ -1090,10 +1090,14 @@ impl<'c, 'b, 'a: 'b+'c, 'gcx, 'tcx: 'a> MirBorrowckCtxt<'c, 'b, 'a, 'gcx, 'tcx>
                         autoderef = true;
                         ("",   format!(""), Some(index))
                     },
-                    ProjectionElem::ConstantIndex { offset, min_length, from_end: true } =>
-                        ("",   format!("[{} of {}]", offset, min_length), None),
-                    ProjectionElem::ConstantIndex { offset, min_length, from_end: false } =>
-                        ("",   format!("[-{} of {}]", offset, min_length), None),
+                    ProjectionElem::ConstantIndex { offset, from_end: false, .. } => {
+                        autoderef = true;
+                        ("",   format!("[{}]", offset), None)
+                    },
+                    ProjectionElem::ConstantIndex { offset, from_end: true, .. } => {
+                        autoderef = true;
+                        ("",   format!("[-{}]", offset), None)
+                    },
                     ProjectionElem::Subslice { from, to: 0 } =>
                         ("",   format!("[{}:]", from), None),
                     ProjectionElem::Subslice { from: 0, to } =>
diff --git a/src/test/compile-fail/borrowck/borrowck-describe-lvalue.rs b/src/test/compile-fail/borrowck/borrowck-describe-lvalue.rs
index 6de8bda9276..9d1b2b64d85 100644
--- a/src/test/compile-fail/borrowck/borrowck-describe-lvalue.rs
+++ b/src/test/compile-fail/borrowck/borrowck-describe-lvalue.rs
@@ -11,6 +11,8 @@
 // revisions: ast mir
 //[mir]compile-flags: -Z emit-end-regions -Z borrowck-mir
 
+#![feature(advanced_slice_patterns)]
+
 pub struct Foo {
   x: u32
 }
@@ -163,4 +165,37 @@ fn main() {
              //[mir]~^ ERROR cannot use `u.a` because it was mutably borrowed (Ast)
              //[mir]~| ERROR cannot use `u.a` because it was mutably borrowed (Mir)
     }
+    // Constant index
+    {
+        let mut v = &[1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
+        let _v = &mut v;
+        match v {
+            &[x, _, .., _, _] => println!("{}", x),
+                //[ast]~^ ERROR cannot use `v[..]` because it was mutably borrowed
+                //[mir]~^^ ERROR cannot use `v[..]` because it was mutably borrowed (Ast)
+                //[mir]~| ERROR cannot use `v[0]` because it was mutably borrowed (Mir)
+                            _ => panic!("other case"),
+        }
+        match v {
+            &[_, x, .., _, _] => println!("{}", x),
+                //[ast]~^ ERROR cannot use `v[..]` because it was mutably borrowed
+                //[mir]~^^ ERROR cannot use `v[..]` because it was mutably borrowed (Ast)
+                //[mir]~| ERROR cannot use `v[1]` because it was mutably borrowed (Mir)
+                            _ => panic!("other case"),
+        }
+        match v {
+            &[_, _, .., x, _] => println!("{}", x),
+                //[ast]~^ ERROR cannot use `v[..]` because it was mutably borrowed
+                //[mir]~^^ ERROR cannot use `v[..]` because it was mutably borrowed (Ast)
+                //[mir]~| ERROR cannot use `v[-2]` because it was mutably borrowed (Mir)
+                            _ => panic!("other case"),
+        }
+        match v {
+            &[_, _, .., _, x] => println!("{}", x),
+                //[ast]~^ ERROR cannot use `v[..]` because it was mutably borrowed
+                //[mir]~^^ ERROR cannot use `v[..]` because it was mutably borrowed (Ast)
+                //[mir]~| ERROR cannot use `v[-1]` because it was mutably borrowed (Mir)
+                            _ => panic!("other case"),
+        }
+    }
 }