]> git.lizzy.rs Git - rust.git/blob - src/array_indexing.rs
Remove * dep
[rust.git] / src / array_indexing.rs
1 use rustc::lint::*;
2 use rustc::middle::const_eval::EvalHint::ExprTypeChecked;
3 use rustc::middle::const_eval::{eval_const_expr_partial, ConstVal};
4 use rustc::middle::ty::TyArray;
5 use rustc_front::hir::*;
6 use utils::span_lint;
7
8 /// **What it does:** Check for out of bounds array indexing with a constant index.
9 ///
10 /// **Why is this bad?** This will always panic at runtime.
11 ///
12 /// **Known problems:** Hopefully none.
13 ///
14 /// **Example:**
15 ///
16 /// ```
17 /// let x = [1,2,3,4];
18 /// ...
19 /// x[9];
20 /// ```
21 declare_lint! {
22     pub OUT_OF_BOUNDS_INDEXING,
23     Deny,
24     "out of bound constant indexing"
25 }
26
27 #[derive(Copy,Clone)]
28 pub struct ArrayIndexing;
29
30 impl LintPass for ArrayIndexing {
31     fn get_lints(&self) -> LintArray {
32         lint_array!(OUT_OF_BOUNDS_INDEXING)
33     }
34 }
35
36 impl LateLintPass for ArrayIndexing {
37     fn check_expr(&mut self, cx: &LateContext, e: &Expr) {
38         if let ExprIndex(ref array, ref index) = e.node {
39             let ty = cx.tcx.expr_ty(array);
40
41             if let TyArray(_, size) = ty.sty {
42                 let index = eval_const_expr_partial(cx.tcx, &index, ExprTypeChecked, None);
43                 if let Ok(ConstVal::Uint(index)) = index {
44                     if size as u64 <= index {
45                         span_lint(cx, OUT_OF_BOUNDS_INDEXING, e.span,
46                                   "const index-expr is out of bounds");
47                     }
48                 }
49             }
50         }
51     }
52 }