Check for constant expression in useless_vec lint
This commit is contained in:
parent
4e9ca25584
commit
10b545e30b
|
@ -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() {
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue