From: James Lucas Date: Sun, 3 Jul 2016 19:12:43 +0000 (-0700) Subject: Check for constant expression in useless_vec lint X-Git-Url: https://git.lizzy.rs/?a=commitdiff_plain;h=10b545e30b18216d536fd4799da65589e499b588;p=rust.git Check for constant expression in useless_vec lint --- diff --git a/clippy_lints/src/vec.rs b/clippy_lints/src/vec.rs index 73f2fb7caa8..a6289837d4e 100644 --- a/clippy_lints/src/vec.rs +++ b/clippy_lints/src/vec.rs @@ -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() { diff --git a/tests/compile-fail/vec.rs b/tests/compile-fail/vec.rs index eda75a2fe8a..92c99c20e36 100644 --- a/tests/compile-fail/vec.rs +++ b/tests/compile-fail/vec.rs @@ -7,6 +7,16 @@ fn on_slice(_: &[u8]) {} #[allow(ptr_arg)] fn on_vec(_: &Vec) {} +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