]> git.lizzy.rs Git - rust.git/blobdiff - clippy_lints/src/vec.rs
Merge branch 'macro-use' into HEAD
[rust.git] / clippy_lints / src / vec.rs
index 8a4731c3eb003a202e14d18aaefbc0c3745cf6d3..a58d73f86daa067d5d14e2a84d0f493844a4060f 100644 (file)
@@ -1,9 +1,11 @@
 use rustc::hir::*;
 use rustc::lint::*;
+use rustc::{declare_lint, lint_array};
+use if_chain::if_chain;
 use rustc::ty::{self, Ty};
-use rustc_const_eval::ConstContext;
 use syntax::codemap::Span;
-use utils::{higher, is_copy, snippet, span_lint_and_sugg};
+use crate::utils::{higher, is_copy, snippet, span_lint_and_sugg};
+use crate::consts::constant;
 
 /// **What it does:** Checks for usage of `&vec![..]` when using `&[..]` would
 /// be possible.
@@ -16,9 +18,9 @@
 /// ```rust,ignore
 /// foo(&vec![1, 2])
 /// ```
-declare_lint! {
+declare_clippy_lint! {
     pub USELESS_VEC,
-    Warn,
+    perf,
     "useless `vec!`"
 }
 
@@ -34,58 +36,61 @@ fn get_lints(&self) -> LintArray {
 impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
     fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr) {
         // search for `&vec![_]` expressions where the adjusted type is `&[_]`
-        if_let_chain!{[
-            let ty::TyRef(_, ref ty) = cx.tables.expr_ty_adjusted(expr).sty,
-            let ty::TySlice(..) = ty.ty.sty,
-            let ExprAddrOf(_, ref addressee) = expr.node,
-            let Some(vec_args) = higher::vec_macro(cx, addressee),
-        ], {
-            check_vec_macro(cx, &vec_args, expr.span);
-        }}
+        if_chain! {
+            if let ty::TyRef(_, ty, _) = cx.tables.expr_ty_adjusted(expr).sty;
+            if let ty::TySlice(..) = ty.sty;
+            if let ExprKind::AddrOf(_, ref addressee) = expr.node;
+            if let Some(vec_args) = higher::vec_macro(cx, addressee);
+            then {
+                check_vec_macro(cx, &vec_args, expr.span);
+            }
+        }
 
         // search for `for _ in vec![…]`
-        if_let_chain!{[
-            let Some((_, arg, _)) = higher::for_loop(expr),
-            let Some(vec_args) = higher::vec_macro(cx, arg),
-            is_copy(cx, vec_type(cx.tables.expr_ty_adjusted(arg))),
-        ], {
-            // report the error around the `vec!` not inside `<std macros>:`
-            let span = arg.span.ctxt.outer().expn_info().map(|info| info.call_site).expect("unable to get call_site");
-            check_vec_macro(cx, &vec_args, span);
-        }}
+        if_chain! {
+            if let Some((_, arg, _)) = higher::for_loop(expr);
+            if let Some(vec_args) = higher::vec_macro(cx, arg);
+            if is_copy(cx, vec_type(cx.tables.expr_ty_adjusted(arg)));
+            then {
+                // report the error around the `vec!` not inside `<std macros>:`
+                let span = arg.span
+                    .ctxt()
+                    .outer()
+                    .expn_info()
+                    .map(|info| info.call_site)
+                    .expect("unable to get call_site");
+                check_vec_macro(cx, &vec_args, span);
+            }
+        }
     }
 }
 
-fn check_vec_macro(cx: &LateContext, vec_args: &higher::VecArgs, span: Span) {
+fn check_vec_macro<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, vec_args: &higher::VecArgs<'tcx>, span: Span) {
     let snippet = match *vec_args {
         higher::VecArgs::Repeat(elem, len) => {
-            if ConstContext::with_tables(cx.tcx, cx.tables).eval(len).is_ok() {
-                format!("&[{}; {}]", snippet(cx, elem.span, "elem"), snippet(cx, len.span, "len")).into()
+            if constant(cx, cx.tables, len).is_some() {
+                format!("&[{}; {}]", snippet(cx, elem.span, "elem"), snippet(cx, len.span, "len"))
             } else {
                 return;
             }
         },
-        higher::VecArgs::Vec(args) => {
-            if let Some(last) = args.iter().last() {
-                let span = Span {
-                    lo: args[0].span.lo,
-                    hi: last.span.hi,
-                    ctxt: args[0].span.ctxt,
-                };
+        higher::VecArgs::Vec(args) => if let Some(last) = args.iter().last() {
+            let span = args[0].span.to(last.span);
 
-                format!("&[{}]", snippet(cx, span, "..")).into()
-            } else {
-                "&[]".into()
-            }
+            format!("&[{}]", snippet(cx, span, ".."))
+        } else {
+            "&[]".into()
         },
     };
 
-    span_lint_and_sugg(cx,
-                       USELESS_VEC,
-                       span,
-                       "useless use of `vec!`",
-                       "you can use a slice directly",
-                       snippet);
+    span_lint_and_sugg(
+        cx,
+        USELESS_VEC,
+        span,
+        "useless use of `vec!`",
+        "you can use a slice directly",
+        snippet,
+    );
 }
 
 /// Return the item type of the vector (ie. the `T` in `Vec<T>`).