]> git.lizzy.rs Git - rust.git/commitdiff
Check for constant expression in useless_vec lint
authorJames Lucas <LucasJ94@hotmail.co.uk>
Sun, 3 Jul 2016 19:12:43 +0000 (12:12 -0700)
committerJames Lucas <LucasJ94@hotmail.co.uk>
Sun, 3 Jul 2016 19:12:43 +0000 (12:12 -0700)
clippy_lints/src/vec.rs
tests/compile-fail/vec.rs

index 73f2fb7caa819b27d58b634cff85037e9b128ae9..a6289837d4e93c3786b2661f05cbe6733ccad054 100644 (file)
@@ -1,6 +1,8 @@
 use rustc::lint::*;
 use rustc::ty::TypeVariants;
 use rustc::hir::*;
+use rustc_const_eval::EvalHint::ExprTypeChecked;
+use rustc_const_eval::eval_const_expr_partial;
 use syntax::codemap::Span;
 use syntax::ptr::P;
 use utils::{is_expn_of, match_path, paths, recover_for_loop, snippet, span_lint_and_then};
@@ -52,9 +54,15 @@ fn check_expr(&mut self, cx: &LateContext, expr: &Expr) {
 
 fn check_vec_macro(cx: &LateContext, vec: &Expr, span: Span) {
     if let Some(vec_args) = unexpand(cx, vec) {
+
         let snippet = match vec_args {
             Args::Repeat(elem, len) => {
-                format!("&[{}; {}]", snippet(cx, elem.span, "elem"), snippet(cx, len.span, "len")).into()
+                // Check that the length is a constant expression
+                if eval_const_expr_partial(cx.tcx, len, ExprTypeChecked, None).is_ok() {
+                    format!("&[{}; {}]", snippet(cx, elem.span, "elem"), snippet(cx, len.span, "len")).into()
+                } else {
+                    return;
+                }
             }
             Args::Vec(args) => {
                 if let Some(last) = args.iter().last() {
index eda75a2fe8a4f6bfc2edcb86a016f210269d5c9c..92c99c20e36ea8ce3f8656e865fb374bed3a9acc 100644 (file)
@@ -7,6 +7,16 @@ fn on_slice(_: &[u8]) {}
 #[allow(ptr_arg)]
 fn on_vec(_: &Vec<u8>) {}
 
+struct Line {
+    length: usize,
+}
+
+impl Line {
+    fn length(&self) -> usize {
+        self.length
+    }
+}
+
 fn main() {
     on_slice(&vec![]);
     //~^ ERROR useless use of `vec!`
@@ -42,6 +52,12 @@ fn main() {
     on_vec(&vec![1, 2]);
     on_vec(&vec![1; 2]);
 
+    // Now with non-constant expressions
+    let line = Line { length: 2 };
+
+    on_slice(&vec![2; line.length]);
+    on_slice(&vec![2; line.length()]);
+
     for a in vec![1, 2, 3] {
         //~^ ERROR useless use of `vec!`
         //~| HELP you can use