about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEduard Burtescu <edy.burt@gmail.com>2016-05-26 22:09:48 +0300
committerEduard Burtescu <edy.burt@gmail.com>2016-06-05 14:41:04 +0300
commit1447fbf183e2c6c7889257bb363de3228324fb6e (patch)
treee095608c1ba935b6cd2af4c57dd4427d1b5f9ae3
parentafc598e07543cc0c927e976c7e3621e44843135c (diff)
downloadrust-1447fbf183e2c6c7889257bb363de3228324fb6e.tar.gz
rust-1447fbf183e2c6c7889257bb363de3228324fb6e.zip
rustc_const_eval: track the length and index in IndexOutOfBounds.
-rw-r--r--src/librustc_const_eval/eval.rs19
-rw-r--r--src/librustc_trans/consts.rs5
-rw-r--r--src/librustc_trans/mir/constant.rs9
-rw-r--r--src/test/compile-fail/array_const_index-0.rs2
-rw-r--r--src/test/compile-fail/array_const_index-1.rs3
-rw-r--r--src/test/compile-fail/const-array-oob.rs4
-rw-r--r--src/test/compile-fail/const-err-early.rs6
-rw-r--r--src/test/compile-fail/const-err.rs6
-rw-r--r--src/test/compile-fail/const-slice-oob.rs3
9 files changed, 40 insertions, 17 deletions
diff --git a/src/librustc_const_eval/eval.rs b/src/librustc_const_eval/eval.rs
index b7cdb05a5d7..785b734b799 100644
--- a/src/librustc_const_eval/eval.rs
+++ b/src/librustc_const_eval/eval.rs
@@ -390,7 +390,7 @@ pub enum ErrKind {
     IndexedNonVec,
     IndexNegative,
     IndexNotInt,
-    IndexOutOfBounds,
+    IndexOutOfBounds { len: u64, index: u64 },
     RepeatCountNotNatural,
     RepeatCountNotInt,
 
@@ -441,7 +441,10 @@ impl ConstEvalErr {
             IndexedNonVec => "indexing is only supported for arrays".into_cow(),
             IndexNegative => "indices must be non-negative integers".into_cow(),
             IndexNotInt => "indices must be integers".into_cow(),
-            IndexOutOfBounds => "array index out of bounds".into_cow(),
+            IndexOutOfBounds { len, index } => {
+                format!("index out of bounds: the len is {} but the index is {}",
+                        len, index).into_cow()
+            }
             RepeatCountNotNatural => "repeat count must be a natural number".into_cow(),
             RepeatCountNotInt => "repeat count must be integers".into_cow(),
 
@@ -835,7 +838,9 @@ pub fn eval_const_expr_partial<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
         };
         assert_eq!(idx as usize as u64, idx);
         match arr {
-            Array(_, n) if idx >= n => signal!(e, IndexOutOfBounds),
+            Array(_, n) if idx >= n => {
+                signal!(e, IndexOutOfBounds { len: n, index: idx })
+            }
             Array(v, n) => if let hir::ExprVec(ref v) = tcx.map.expect_expr(v).node {
                 assert_eq!(n as usize as u64, n);
                 eval_const_expr_partial(tcx, &v[idx as usize], ty_hint, fn_args)?
@@ -843,7 +848,9 @@ pub fn eval_const_expr_partial<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                 bug!()
             },
 
-            Repeat(_, n) if idx >= n => signal!(e, IndexOutOfBounds),
+            Repeat(_, n) if idx >= n => {
+                signal!(e, IndexOutOfBounds { len: n, index: idx })
+            }
             Repeat(elem, _) => eval_const_expr_partial(
                 tcx,
                 &tcx.map.expect_expr(elem),
@@ -851,7 +858,9 @@ pub fn eval_const_expr_partial<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                 fn_args,
             )?,
 
-            ByteStr(ref data) if idx >= data.len() as u64 => signal!(e, IndexOutOfBounds),
+            ByteStr(ref data) if idx >= data.len() as u64 => {
+                signal!(e, IndexOutOfBounds { len: data.len() as u64, index: idx })
+            }
             ByteStr(data) => {
                 Integral(U8(data[idx as usize]))
             },
diff --git a/src/librustc_trans/consts.rs b/src/librustc_trans/consts.rs
index bd36c18a47e..6788d5de6d8 100644
--- a/src/librustc_trans/consts.rs
+++ b/src/librustc_trans/consts.rs
@@ -716,7 +716,10 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
             if iv >= len {
                 // FIXME #3170: report this earlier on in the const-eval
                 // pass. Reporting here is a bit late.
-                const_err(cx, e.span, Err(ErrKind::IndexOutOfBounds), trueconst)?;
+                const_err(cx, e.span, Err(ErrKind::IndexOutOfBounds {
+                    len: len,
+                    index: iv
+                }), trueconst)?;
                 C_undef(val_ty(arr).element_type())
             } else {
                 const_get_elt(arr, &[iv as c_uint])
diff --git a/src/librustc_trans/mir/constant.rs b/src/librustc_trans/mir/constant.rs
index e73d02a1e29..e32e542ed89 100644
--- a/src/librustc_trans/mir/constant.rs
+++ b/src/librustc_trans/mir/constant.rs
@@ -298,8 +298,13 @@ impl<'a, 'tcx> MirConstContext<'a, 'tcx> {
                     let cond_bool = common::const_to_uint(cond.llval) != 0;
                     if cond_bool != expected {
                         let err = match *msg {
-                            mir::AssertMessage::BoundsCheck {..} => {
-                                ErrKind::IndexOutOfBounds
+                            mir::AssertMessage::BoundsCheck { ref len, ref index } => {
+                                let len = self.const_operand(len, span)?;
+                                let index = self.const_operand(index, span)?;
+                                ErrKind::IndexOutOfBounds {
+                                    len: common::const_to_uint(len.llval),
+                                    index: common::const_to_uint(index.llval)
+                                }
                             }
                             mir::AssertMessage::Math(ref err) => {
                                 ErrKind::Math(err.clone())
diff --git a/src/test/compile-fail/array_const_index-0.rs b/src/test/compile-fail/array_const_index-0.rs
index 1134dbfd1c4..e65230389f9 100644
--- a/src/test/compile-fail/array_const_index-0.rs
+++ b/src/test/compile-fail/array_const_index-0.rs
@@ -10,7 +10,7 @@
 
 const A: &'static [i32] = &[];
 const B: i32 = (&A)[1];
-//~^ ERROR: array index out of bounds
+//~^ ERROR index out of bounds: the len is 0 but the index is 1
 
 fn main() {
     let _ = B;
diff --git a/src/test/compile-fail/array_const_index-1.rs b/src/test/compile-fail/array_const_index-1.rs
index e59895cda44..69d84e24c49 100644
--- a/src/test/compile-fail/array_const_index-1.rs
+++ b/src/test/compile-fail/array_const_index-1.rs
@@ -9,7 +9,8 @@
 // except according to those terms.
 
 const A: [i32; 0] = [];
-const B: i32 = A[1]; //~ ERROR: array index out of bounds
+const B: i32 = A[1];
+//~^ ERROR index out of bounds: the len is 0 but the index is 1
 
 fn main() {
     let _ = B;
diff --git a/src/test/compile-fail/const-array-oob.rs b/src/test/compile-fail/const-array-oob.rs
index 15426febbcd..faabed4fd5e 100644
--- a/src/test/compile-fail/const-array-oob.rs
+++ b/src/test/compile-fail/const-array-oob.rs
@@ -8,13 +8,15 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// ignore-tidy-linelength
+
 #![feature(const_indexing)]
 
 const FOO: [u32; 3] = [1, 2, 3];
 const BAR: u32 = FOO[5]; // no error, because the error below occurs before regular const eval
 
 const BLUB: [u32; FOO[4]] = [5, 6];
-//~^ ERROR array length constant evaluation error: array index out of bounds [E0250]
+//~^ ERROR array length constant evaluation error: index out of bounds: the len is 3 but the index is 4 [E0250]
 
 fn main() {
     let _ = BAR;
diff --git a/src/test/compile-fail/const-err-early.rs b/src/test/compile-fail/const-err-early.rs
index 7567791c240..f666140970b 100644
--- a/src/test/compile-fail/const-err-early.rs
+++ b/src/test/compile-fail/const-err-early.rs
@@ -15,8 +15,10 @@ pub const A: i8 = -std::i8::MIN; //~ ERROR attempted to negate with overflow
 pub const B: u8 = 200u8 + 200u8; //~ ERROR attempted to add with overflow
 pub const C: u8 = 200u8 * 4; //~ ERROR attempted to multiply with overflow
 pub const D: u8 = 42u8 - (42u8 + 1); //~ ERROR attempted to subtract with overflow
-pub const E: u8 = [5u8][1]; //~ ERROR index out of bounds
+pub const E: u8 = [5u8][1];
+//~^ ERROR index out of bounds: the len is 1 but the index is 1
 
 fn main() {
-    let _e = [6u8][1]; //~ ERROR: array index out of bounds
+    let _e = [6u8][1];
+    //~^ ERROR index out of bounds: the len is 1 but the index is 1
 }
diff --git a/src/test/compile-fail/const-err.rs b/src/test/compile-fail/const-err.rs
index 85d67f52bfe..ac2ef6662a4 100644
--- a/src/test/compile-fail/const-err.rs
+++ b/src/test/compile-fail/const-err.rs
@@ -20,8 +20,8 @@ fn black_box<T>(_: T) {
 
 // Make sure that the two uses get two errors.
 const FOO: u8 = [5u8][1];
-//~^ ERROR array index out of bounds
-//~^^ ERROR array index out of bounds
+//~^ ERROR index out of bounds: the len is 1 but the index is 1
+//~^^ ERROR index out of bounds: the len is 1 but the index is 1
 
 fn main() {
     let a = -std::i8::MIN;
@@ -34,7 +34,7 @@ fn main() {
     let d = 42u8 - (42u8 + 1);
     //~^ WARN attempted to subtract with overflow
     let _e = [5u8][1];
-    //~^ WARN array index out of bounds
+    //~^ WARN index out of bounds: the len is 1 but the index is 1
     black_box(a);
     black_box(b);
     black_box(c);
diff --git a/src/test/compile-fail/const-slice-oob.rs b/src/test/compile-fail/const-slice-oob.rs
index b50468c33fd..d63b0097e5a 100644
--- a/src/test/compile-fail/const-slice-oob.rs
+++ b/src/test/compile-fail/const-slice-oob.rs
@@ -9,7 +9,8 @@
 // except according to those terms.
 
 const FOO: &'static[u32] = &[1, 2, 3];
-const BAR: u32 = FOO[5]; //~ ERROR array index out of bounds
+const BAR: u32 = FOO[5];
+//~^ ERROR index out of bounds: the len is 3 but the index is 5
 
 fn main() {
     let _ = BAR;