Check for constant expression in useless_vec lint

This commit is contained in:
James Lucas 2016-07-03 12:12:43 -07:00
parent 4e9ca25584
commit 10b545e30b
2 changed files with 25 additions and 1 deletions

View 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 @@ impl LateLintPass for Pass {
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() {

View 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