diff --git a/src/attrs.rs b/src/attrs.rs index 17b8a60bcb95..a41cd141a128 100644 --- a/src/attrs.rs +++ b/src/attrs.rs @@ -7,7 +7,8 @@ use semver::Version; use syntax::ast::{Attribute, Lit, LitKind, MetaItemKind}; use syntax::attr::*; use syntax::codemap::Span; -use utils::{in_macro, match_path, span_lint, BEGIN_UNWIND}; +use utils::{in_macro, match_path, span_lint}; +use utils::paths; /// **What it does:** This lint checks for items annotated with `#[inline(always)]`, unless the annotated function is empty or simply panics. /// @@ -129,7 +130,7 @@ fn is_relevant_expr(expr: &Expr) -> bool { ExprRet(None) | ExprBreak(_) => false, ExprCall(ref path_expr, _) => { if let ExprPath(_, ref path) = path_expr.node { - !match_path(path, &BEGIN_UNWIND) + !match_path(path, &paths::BEGIN_UNWIND) } else { true } diff --git a/src/derive.rs b/src/derive.rs index 4b8446e6201d..c9ac8f0a948b 100644 --- a/src/derive.rs +++ b/src/derive.rs @@ -5,7 +5,7 @@ use rustc::ty; use rustc::hir::*; use syntax::ast::{Attribute, MetaItemKind}; use syntax::codemap::Span; -use utils::{CLONE_TRAIT_PATH, HASH_PATH}; +use utils::paths; use utils::{match_path, span_lint_and_then}; /// **What it does:** This lint warns about deriving `Hash` but implementing `PartialEq` @@ -88,7 +88,7 @@ impl LateLintPass for Derive { /// Implementation of the `DERIVE_HASH_XOR_EQ` lint. fn check_hash_peq<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, span: Span, trait_ref: &TraitRef, ty: ty::Ty<'tcx>, hash_is_automatically_derived: bool) { if_let_chain! {[ - match_path(&trait_ref.path, &HASH_PATH), + match_path(&trait_ref.path, &paths::HASH), let Some(peq_trait_def_id) = cx.tcx.lang_items.eq_trait() ], { let peq_trait_def = cx.tcx.lookup_trait_def(peq_trait_def_id); @@ -129,7 +129,7 @@ fn check_hash_peq<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, span: Span, trait_ref: & /// Implementation of the `EXPL_IMPL_CLONE_ON_COPY` lint. fn check_copy_clone<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, item: &Item, trait_ref: &TraitRef, ty: ty::Ty<'tcx>) { - if match_path(&trait_ref.path, &CLONE_TRAIT_PATH) { + if match_path(&trait_ref.path, &paths::CLONE_TRAIT) { let parameter_environment = ty::ParameterEnvironment::for_item(cx.tcx, item.id); let subst_ty = ty.subst(cx.tcx, ¶meter_environment.free_substs); diff --git a/src/drop_ref.rs b/src/drop_ref.rs index 3448e05dbac1..69156f15f317 100644 --- a/src/drop_ref.rs +++ b/src/drop_ref.rs @@ -2,8 +2,7 @@ use rustc::lint::*; use rustc::ty; use rustc::hir::*; use syntax::codemap::Span; -use utils::DROP_PATH; -use utils::{match_def_path, span_note_and_lint}; +use utils::{match_def_path, paths, span_note_and_lint}; /// **What it does:** This lint checks for calls to `std::mem::drop` with a reference instead of an owned value. /// @@ -37,7 +36,7 @@ impl LateLintPass for DropRefPass { if let ExprCall(ref path, ref args) = expr.node { if let ExprPath(None, _) = path.node { let def_id = cx.tcx.def_map.borrow()[&path.id].def_id(); - if match_def_path(cx, def_id, &DROP_PATH) { + if match_def_path(cx, def_id, &paths::DROP) { if args.len() != 1 { return; } diff --git a/src/entry.rs b/src/entry.rs index 934400bc1228..24810e242ad1 100644 --- a/src/entry.rs +++ b/src/entry.rs @@ -1,10 +1,9 @@ -use rustc::lint::*; use rustc::hir::*; use rustc::hir::intravisit::{Visitor, walk_expr, walk_block}; +use rustc::lint::*; use syntax::codemap::Span; use utils::SpanlessEq; -use utils::{BTREEMAP_PATH, HASHMAP_PATH}; -use utils::{get_item_name, match_type, snippet, span_lint_and_then, walk_ptrs_ty}; +use utils::{get_item_name, match_type, paths, snippet, span_lint_and_then, walk_ptrs_ty}; /// **What it does:** This lint checks for uses of `contains_key` + `insert` on `HashMap` or /// `BTreeMap`. @@ -89,10 +88,10 @@ fn check_cond<'a, 'tcx, 'b>(cx: &'a LateContext<'a, 'tcx>, check: &'b Expr) -> O let map = ¶ms[0]; let obj_ty = walk_ptrs_ty(cx.tcx.expr_ty(map)); - return if match_type(cx, obj_ty, &BTREEMAP_PATH) { + return if match_type(cx, obj_ty, &paths::BTREEMAP) { Some(("BTreeMap", map, key)) } - else if match_type(cx, obj_ty, &HASHMAP_PATH) { + else if match_type(cx, obj_ty, &paths::HASHMAP) { Some(("HashMap", map, key)) } else { diff --git a/src/format.rs b/src/format.rs index 0a349c98e076..0726fcaeab71 100644 --- a/src/format.rs +++ b/src/format.rs @@ -1,9 +1,9 @@ +use rustc::hir::*; use rustc::hir::map::Node::NodeItem; use rustc::lint::*; use rustc::ty::TypeVariants; -use rustc::hir::*; use syntax::ast::LitKind; -use utils::{DISPLAY_FMT_METHOD_PATH, FMT_ARGUMENTS_NEWV1_PATH, STRING_PATH}; +use utils::paths; use utils::{is_expn_of, match_path, match_type, span_lint, walk_ptrs_ty}; /// **What it does:** This lints about use of `format!("string literal with no argument")` and @@ -40,7 +40,7 @@ impl LateLintPass for FormatMacLint { if_let_chain!{[ let ExprPath(_, ref path) = fun.node, args.len() == 2, - match_path(path, &FMT_ARGUMENTS_NEWV1_PATH), + match_path(path, &paths::FMT_ARGUMENTS_NEWV1), // ensure the format string is `"{..}"` with only one argument and no text check_static_str(cx, &args[0]), // ensure the format argument is `{}` ie. Display with no fancy option @@ -108,11 +108,11 @@ fn check_arg_is_display(cx: &LateContext, expr: &Expr) -> bool { let ExprCall(_, ref args) = exprs[0].node, args.len() == 2, let ExprPath(None, ref path) = args[1].node, - match_path(path, &DISPLAY_FMT_METHOD_PATH) + match_path(path, &paths::DISPLAY_FMT_METHOD) ], { let ty = walk_ptrs_ty(cx.tcx.pat_ty(&pat[0])); - return ty.sty == TypeVariants::TyStr || match_type(cx, ty, &STRING_PATH); + return ty.sty == TypeVariants::TyStr || match_type(cx, ty, &paths::STRING); }} false diff --git a/src/loops.rs b/src/loops.rs index 4e7e4bf117d8..4fb45e7c1986 100644 --- a/src/loops.rs +++ b/src/loops.rs @@ -16,7 +16,7 @@ use syntax::ast; use utils::{snippet, span_lint, get_parent_expr, match_trait_method, match_type, in_external_macro, span_help_and_lint, is_integer_literal, get_enclosing_block, span_lint_and_then, unsugar_range, walk_ptrs_ty, recover_for_loop}; -use utils::{BTREEMAP_PATH, HASHMAP_PATH, LL_PATH, OPTION_PATH, RESULT_PATH, VEC_PATH}; +use utils::paths; use utils::UnsugaredRange; /// **What it does:** This lint checks for looping over the range of `0..len` of some collection just to get the values by index. @@ -505,7 +505,7 @@ fn check_for_loop_arg(cx: &LateContext, pat: &Pat, arg: &Expr, expr: &Expr) { /// Check for `for` loops over `Option`s and `Results` fn check_arg_type(cx: &LateContext, pat: &Pat, arg: &Expr) { let ty = cx.tcx.expr_ty(arg); - if match_type(cx, ty, &OPTION_PATH) { + if match_type(cx, ty, &paths::OPTION) { span_help_and_lint(cx, FOR_LOOP_OVER_OPTION, arg.span, @@ -515,7 +515,7 @@ fn check_arg_type(cx: &LateContext, pat: &Pat, arg: &Expr) { &format!("consider replacing `for {0} in {1}` with `if let Some({0}) = {1}`", snippet(cx, pat.span, "_"), snippet(cx, arg.span, "_"))); - } else if match_type(cx, ty, &RESULT_PATH) { + } else if match_type(cx, ty, &paths::RESULT) { span_help_and_lint(cx, FOR_LOOP_OVER_RESULT, arg.span, @@ -589,7 +589,7 @@ fn check_for_loop_over_map_kv(cx: &LateContext, pat: &Pat, arg: &Expr, body: &Ex }; let ty = walk_ptrs_ty(cx.tcx.expr_ty(arg)); - if match_type(cx, ty, &HASHMAP_PATH) || match_type(cx, ty, &BTREEMAP_PATH) { + if match_type(cx, ty, &paths::HASHMAP) || match_type(cx, ty, &paths::BTREEMAP) { span_lint_and_then(cx, FOR_KV_MAP, expr.span, @@ -735,13 +735,13 @@ fn is_ref_iterable_type(cx: &LateContext, e: &Expr) -> bool { // will allow further borrows afterwards let ty = cx.tcx.expr_ty(e); is_iterable_array(ty) || - match_type(cx, ty, &VEC_PATH) || - match_type(cx, ty, &LL_PATH) || - match_type(cx, ty, &HASHMAP_PATH) || + match_type(cx, ty, &paths::VEC) || + match_type(cx, ty, &paths::LL) || + match_type(cx, ty, &paths::HASHMAP) || match_type(cx, ty, &["std", "collections", "hash", "set", "HashSet"]) || match_type(cx, ty, &["collections", "vec_deque", "VecDeque"]) || match_type(cx, ty, &["collections", "binary_heap", "BinaryHeap"]) || - match_type(cx, ty, &BTREEMAP_PATH) || + match_type(cx, ty, &paths::BTREEMAP) || match_type(cx, ty, &["collections", "btree", "set", "BTreeSet"]) } diff --git a/src/map_clone.rs b/src/map_clone.rs index eeb3aab4655c..caefb64eb5f1 100644 --- a/src/map_clone.rs +++ b/src/map_clone.rs @@ -1,8 +1,7 @@ use rustc::lint::*; use rustc::hir::*; -use utils::{CLONE_PATH, OPTION_PATH}; -use utils::{is_adjusted, match_path, match_trait_method, match_type, snippet, span_help_and_lint, walk_ptrs_ty, - walk_ptrs_ty_depth}; +use utils::{is_adjusted, match_path, match_trait_method, match_type, paths, snippet, + span_help_and_lint, walk_ptrs_ty, walk_ptrs_ty_depth}; /// **What it does:** This lint checks for mapping clone() over an iterator. /// @@ -65,7 +64,7 @@ impl LateLintPass for MapClonePass { } } ExprPath(_, ref path) => { - if match_path(path, &CLONE_PATH) { + if match_path(path, &paths::CLONE) { let type_name = get_type_name(cx, expr, &args[0]).unwrap_or("_"); span_help_and_lint(cx, MAP_CLONE, @@ -99,7 +98,7 @@ fn expr_eq_ident(expr: &Expr, id: Ident) -> bool { fn get_type_name(cx: &LateContext, expr: &Expr, arg: &Expr) -> Option<&'static str> { if match_trait_method(cx, expr, &["core", "iter", "Iterator"]) { Some("iterator") - } else if match_type(cx, walk_ptrs_ty(cx.tcx.expr_ty(arg)), &OPTION_PATH) { + } else if match_type(cx, walk_ptrs_ty(cx.tcx.expr_ty(arg)), &paths::OPTION) { Some("Option") } else { None diff --git a/src/matches.rs b/src/matches.rs index d82dad5b0653..c1692ee47d29 100644 --- a/src/matches.rs +++ b/src/matches.rs @@ -8,7 +8,7 @@ use rustc_const_math::ConstInt; use std::cmp::Ordering; use syntax::ast::LitKind; use syntax::codemap::Span; -use utils::{COW_PATH, OPTION_PATH, RESULT_PATH}; +use utils::paths; use utils::{match_type, snippet, span_note_and_lint, span_lint_and_then, in_external_macro, expr_block}; /// **What it does:** This lint checks for matches with a single arm where an `if let` will usually suffice. @@ -184,13 +184,13 @@ fn check_single_match_single_pattern(cx: &LateContext, ex: &Expr, arms: &[Arm], fn check_single_match_opt_like(cx: &LateContext, ex: &Expr, arms: &[Arm], expr: &Expr, ty: ty::Ty, els: Option<&Expr>) { // list of candidate Enums we know will never get any more members - let candidates = &[(&COW_PATH, "Borrowed"), - (&COW_PATH, "Cow::Borrowed"), - (&COW_PATH, "Cow::Owned"), - (&COW_PATH, "Owned"), - (&OPTION_PATH, "None"), - (&RESULT_PATH, "Err"), - (&RESULT_PATH, "Ok")]; + let candidates = &[(&paths::COW, "Borrowed"), + (&paths::COW, "Cow::Borrowed"), + (&paths::COW, "Cow::Owned"), + (&paths::COW, "Owned"), + (&paths::OPTION, "None"), + (&paths::RESULT, "Err"), + (&paths::RESULT, "Ok")]; let path = match arms[1].pats[0].node { PatKind::TupleStruct(ref path, Some(ref inner)) => { diff --git a/src/methods.rs b/src/methods.rs index 8a51b576b3df..d2a91b615ae5 100644 --- a/src/methods.rs +++ b/src/methods.rs @@ -13,9 +13,8 @@ use syntax::ptr::P; use utils::{get_trait_def_id, implements_trait, in_external_macro, in_macro, match_path, match_trait_method, match_type, method_chain_args, return_ty, same_tys, snippet, snippet_opt, span_lint, span_lint_and_then, span_note_and_lint, walk_ptrs_ty, walk_ptrs_ty_depth}; -use utils::{CSTRING_NEW_PATH, BTREEMAP_ENTRY_PATH, DEFAULT_TRAIT_PATH, HASHMAP_ENTRY_PATH, - OPTION_PATH, RESULT_PATH, VEC_PATH}; use utils::MethodArgs; +use utils::paths; #[derive(Clone)] pub struct MethodsPass; @@ -470,7 +469,7 @@ fn lint_or_fun_call(cx: &LateContext, expr: &Expr, name: &str, args: &[P]) if ["default", "new"].contains(&path) { let arg_ty = cx.tcx.expr_ty(arg); - let default_trait_id = if let Some(default_trait_id) = get_trait_def_id(cx, &DEFAULT_TRAIT_PATH) { + let default_trait_id = if let Some(default_trait_id) = get_trait_def_id(cx, &paths::DEFAULT_TRAIT) { default_trait_id } else { return false; @@ -497,13 +496,13 @@ fn lint_or_fun_call(cx: &LateContext, expr: &Expr, name: &str, args: &[P]) fn check_general_case(cx: &LateContext, name: &str, fun: &Expr, self_expr: &Expr, arg: &Expr, or_has_args: bool, span: Span) { // (path, fn_has_argument, methods) - let know_types: &[(&[_], _, &[_], _)] = &[(&BTREEMAP_ENTRY_PATH, false, &["or_insert"], "with"), - (&HASHMAP_ENTRY_PATH, false, &["or_insert"], "with"), - (&OPTION_PATH, + let know_types: &[(&[_], _, &[_], _)] = &[(&paths::BTREEMAP_ENTRY, false, &["or_insert"], "with"), + (&paths::HASHMAP_ENTRY, false, &["or_insert"], "with"), + (&paths::OPTION, false, &["map_or", "ok_or", "or", "unwrap_or"], "else"), - (&RESULT_PATH, true, &["or", "unwrap_or"], "else")]; + (&paths::RESULT, true, &["or", "unwrap_or"], "else")]; let self_ty = cx.tcx.expr_ty(self_expr); @@ -571,7 +570,7 @@ fn lint_clone_double_ref(cx: &LateContext, expr: &Expr, arg: &Expr) { fn lint_extend(cx: &LateContext, expr: &Expr, args: &MethodArgs) { let (obj_ty, _) = walk_ptrs_ty_depth(cx.tcx.expr_ty(&args[0])); - if !match_type(cx, obj_ty, &VEC_PATH) { + if !match_type(cx, obj_ty, &paths::VEC) { return; } let arg_ty = cx.tcx.expr_ty(&args[1]); @@ -591,7 +590,7 @@ fn lint_cstring_as_ptr(cx: &LateContext, expr: &Expr, new: &Expr, unwrap: &Expr) let ExprCall(ref fun, ref args) = new.node, args.len() == 1, let ExprPath(None, ref path) = fun.node, - match_path(path, &CSTRING_NEW_PATH), + match_path(path, &paths::CSTRING_NEW), ], { span_lint_and_then(cx, TEMPORARY_CSTRING_AS_PTR, expr.span, "you are getting the inner pointer of a temporary `CString`", @@ -606,7 +605,7 @@ fn derefs_to_slice(cx: &LateContext, expr: &Expr, ty: &ty::Ty) -> Option<(Span, fn may_slice(cx: &LateContext, ty: &ty::Ty) -> bool { match ty.sty { ty::TySlice(_) => true, - ty::TyStruct(..) => match_type(cx, ty, &VEC_PATH), + ty::TyStruct(..) => match_type(cx, ty, &paths::VEC), ty::TyArray(_, size) => size < 32, ty::TyRef(_, ty::TypeAndMut { ty: ref inner, .. }) | ty::TyBox(ref inner) => may_slice(cx, inner), @@ -641,9 +640,9 @@ fn derefs_to_slice(cx: &LateContext, expr: &Expr, ty: &ty::Ty) -> Option<(Span, fn lint_unwrap(cx: &LateContext, expr: &Expr, unwrap_args: &MethodArgs) { let (obj_ty, _) = walk_ptrs_ty_depth(cx.tcx.expr_ty(&unwrap_args[0])); - let mess = if match_type(cx, obj_ty, &OPTION_PATH) { + let mess = if match_type(cx, obj_ty, &paths::OPTION) { Some((OPTION_UNWRAP_USED, "an Option", "None")) - } else if match_type(cx, obj_ty, &RESULT_PATH) { + } else if match_type(cx, obj_ty, &paths::RESULT) { Some((RESULT_UNWRAP_USED, "a Result", "Err")) } else { None @@ -666,7 +665,7 @@ fn lint_unwrap(cx: &LateContext, expr: &Expr, unwrap_args: &MethodArgs) { /// lint use of `ok().expect()` for `Result`s fn lint_ok_expect(cx: &LateContext, expr: &Expr, ok_args: &MethodArgs) { // lint if the caller of `ok()` is a `Result` - if match_type(cx, cx.tcx.expr_ty(&ok_args[0]), &RESULT_PATH) { + if match_type(cx, cx.tcx.expr_ty(&ok_args[0]), &paths::RESULT) { let result_type = cx.tcx.expr_ty(&ok_args[0]); if let Some(error_type) = get_error_type(cx, result_type) { if has_debug_impl(error_type, cx) { @@ -684,7 +683,7 @@ fn lint_ok_expect(cx: &LateContext, expr: &Expr, ok_args: &MethodArgs) { /// lint use of `map().unwrap_or()` for `Option`s fn lint_map_unwrap_or(cx: &LateContext, expr: &Expr, map_args: &MethodArgs, unwrap_args: &MethodArgs) { // lint if the caller of `map()` is an `Option` - if match_type(cx, cx.tcx.expr_ty(&map_args[0]), &OPTION_PATH) { + if match_type(cx, cx.tcx.expr_ty(&map_args[0]), &paths::OPTION) { // lint message let msg = "called `map(f).unwrap_or(a)` on an Option value. This can be done more directly by calling \ `map_or(a, f)` instead"; @@ -715,7 +714,7 @@ fn lint_map_unwrap_or(cx: &LateContext, expr: &Expr, map_args: &MethodArgs, unwr /// lint use of `map().unwrap_or_else()` for `Option`s fn lint_map_unwrap_or_else(cx: &LateContext, expr: &Expr, map_args: &MethodArgs, unwrap_args: &MethodArgs) { // lint if the caller of `map()` is an `Option` - if match_type(cx, cx.tcx.expr_ty(&map_args[0]), &OPTION_PATH) { + if match_type(cx, cx.tcx.expr_ty(&map_args[0]), &paths::OPTION) { // lint message let msg = "called `map(f).unwrap_or_else(g)` on an Option value. This can be done more directly by calling \ `map_or_else(g, f)` instead"; @@ -842,7 +841,7 @@ fn lint_single_char_pattern(cx: &LateContext, expr: &Expr, arg: &Expr) { /// Given a `Result` type, return its error type (`E`). fn get_error_type<'a>(cx: &LateContext, ty: ty::Ty<'a>) -> Option> { - if !match_type(cx, ty, &RESULT_PATH) { + if !match_type(cx, ty, &paths::RESULT) { return None; } if let ty::TyEnum(_, substs) = ty.sty { @@ -853,7 +852,7 @@ fn get_error_type<'a>(cx: &LateContext, ty: ty::Ty<'a>) -> Option> { None } -/// This checks whether a given type is known to implement `Debug`. +/// This checks whether a given type is known to implement Debug. fn has_debug_impl<'a, 'b>(ty: ty::Ty<'a>, cx: &LateContext<'b, 'a>) -> bool { match cx.tcx.lang_items.debug_trait() { Some(debug) => implements_trait(cx, ty, debug, Vec::new()), diff --git a/src/mutex_atomic.rs b/src/mutex_atomic.rs index bae1ae38168d..7d637adb8b8b 100644 --- a/src/mutex_atomic.rs +++ b/src/mutex_atomic.rs @@ -7,7 +7,7 @@ use rustc::ty::subst::ParamSpace; use rustc::ty; use rustc::hir::Expr; use syntax::ast; -use utils::{span_lint, MUTEX_PATH, match_type}; +use utils::{match_type, paths, span_lint}; /// **What it does:** This lint checks for usages of `Mutex` where an atomic will do. /// @@ -47,7 +47,7 @@ impl LateLintPass for MutexAtomic { fn check_expr(&mut self, cx: &LateContext, expr: &Expr) { let ty = cx.tcx.expr_ty(expr); if let ty::TyStruct(_, subst) = ty.sty { - if match_type(cx, ty, &MUTEX_PATH) { + if match_type(cx, ty, &paths::MUTEX) { let mutex_param = &subst.types.get(ParamSpace::TypeSpace, 0).sty; if let Some(atomic_name) = get_atomic_name(mutex_param) { let msg = format!("Consider using an {} instead of a Mutex here. If you just want the locking \ diff --git a/src/new_without_default.rs b/src/new_without_default.rs index 2bcc345fd601..f42b1d0d74a5 100644 --- a/src/new_without_default.rs +++ b/src/new_without_default.rs @@ -1,10 +1,10 @@ -use rustc::lint::*; -use rustc::hir; use rustc::hir::intravisit::FnKind; +use rustc::hir; +use rustc::lint::*; use syntax::ast; use syntax::codemap::Span; -use utils::{get_trait_def_id, implements_trait, in_external_macro, return_ty, same_tys, span_lint, - DEFAULT_TRAIT_PATH}; +use utils::paths; +use utils::{get_trait_def_id, implements_trait, in_external_macro, return_ty, same_tys, span_lint}; /// **What it does:** This lints about type with a `fn new() -> Self` method and no `Default` /// implementation. @@ -54,7 +54,7 @@ impl LateLintPass for NewWithoutDefault { self_ty.walk_shallow().next().is_none(), // implements_trait does not work with generics let Some(ret_ty) = return_ty(cx, id), same_tys(cx, self_ty, ret_ty, id), - let Some(default_trait_id) = get_trait_def_id(cx, &DEFAULT_TRAIT_PATH), + let Some(default_trait_id) = get_trait_def_id(cx, &paths::DEFAULT_TRAIT), !implements_trait(cx, self_ty, default_trait_id, Vec::new()) ], { span_lint(cx, NEW_WITHOUT_DEFAULT, span, diff --git a/src/open_options.rs b/src/open_options.rs index 3c1e69a40ea2..aaaebe5b2f8b 100644 --- a/src/open_options.rs +++ b/src/open_options.rs @@ -1,8 +1,8 @@ -use rustc::lint::*; use rustc::hir::{Expr, ExprMethodCall, ExprLit}; +use rustc::lint::*; use syntax::ast::LitKind; use syntax::codemap::{Span, Spanned}; -use utils::{walk_ptrs_ty_depth, match_type, span_lint, OPEN_OPTIONS_PATH}; +use utils::{match_type, paths, span_lint, walk_ptrs_ty_depth}; /// **What it does:** This lint checks for duplicate open options as well as combinations that make no sense. /// @@ -31,7 +31,7 @@ impl LateLintPass for NonSensicalOpenOptions { fn check_expr(&mut self, cx: &LateContext, e: &Expr) { if let ExprMethodCall(ref name, _, ref arguments) = e.node { let (obj_ty, _) = walk_ptrs_ty_depth(cx.tcx.expr_ty(&arguments[0])); - if name.node.as_str() == "open" && match_type(cx, obj_ty, &OPEN_OPTIONS_PATH) { + if name.node.as_str() == "open" && match_type(cx, obj_ty, &paths::OPEN_OPTIONS) { let mut options = Vec::new(); get_open_options(cx, &arguments[0], &mut options); check_open_options(cx, &options, e.span); @@ -61,7 +61,7 @@ fn get_open_options(cx: &LateContext, argument: &Expr, options: &mut Vec<(OpenOp let (obj_ty, _) = walk_ptrs_ty_depth(cx.tcx.expr_ty(&arguments[0])); // Only proceed if this is a call on some object of type std::fs::OpenOptions - if match_type(cx, obj_ty, &OPEN_OPTIONS_PATH) && arguments.len() >= 2 { + if match_type(cx, obj_ty, &paths::OPEN_OPTIONS) && arguments.len() >= 2 { let argument_option = match arguments[1].node { ExprLit(ref span) => { diff --git a/src/panic.rs b/src/panic.rs index ab03181c2dd3..78499fa1a1aa 100644 --- a/src/panic.rs +++ b/src/panic.rs @@ -1,7 +1,7 @@ -use rustc::lint::*; use rustc::hir::*; +use rustc::lint::*; use syntax::ast::LitKind; -use utils::{span_lint, is_direct_expn_of, match_path, BEGIN_UNWIND}; +use utils::{is_direct_expn_of, match_path, paths, span_lint}; /// **What it does:** This lint checks for missing parameters in `panic!`. /// @@ -33,7 +33,7 @@ impl LateLintPass for PanicPass { let ExprCall(ref fun, ref params) = ex.node, params.len() == 2, let ExprPath(None, ref path) = fun.node, - match_path(path, &BEGIN_UNWIND), + match_path(path, &paths::BEGIN_UNWIND), let ExprLit(ref lit) = params[0].node, is_direct_expn_of(cx, params[0].span, "panic").is_some(), let LitKind::Str(ref string, _) = lit.node, diff --git a/src/print.rs b/src/print.rs index a298d162c058..d426286dba48 100644 --- a/src/print.rs +++ b/src/print.rs @@ -1,7 +1,7 @@ +use rustc::hir::*; use rustc::hir::map::Node::{NodeItem, NodeImplItem}; use rustc::lint::*; -use rustc::hir::*; -use utils::{FMT_ARGUMENTV1_NEW_PATH, DEBUG_FMT_METHOD_PATH, IO_PRINT_PATH}; +use utils::paths; use utils::{is_expn_of, match_path, span_lint}; /// **What it does:** This lint warns whenever you print on *stdout*. The purpose of this lint is to catch debugging remnants. @@ -45,7 +45,7 @@ impl LateLintPass for PrintLint { if let ExprPath(_, ref path) = fun.node { // Search for `std::io::_print(..)` which is unique in a // `print!` expansion. - if match_path(path, &IO_PRINT_PATH) { + if match_path(path, &paths::IO_PRINT) { if let Some(span) = is_expn_of(cx, expr.span, "print") { // `println!` uses `print!`. let (span, name) = match is_expn_of(cx, span, "println") { @@ -58,9 +58,9 @@ impl LateLintPass for PrintLint { } // Search for something like // `::std::fmt::ArgumentV1::new(__arg0, ::std::fmt::Debug::fmt)` - else if args.len() == 2 && match_path(path, &FMT_ARGUMENTV1_NEW_PATH) { + else if args.len() == 2 && match_path(path, &paths::FMT_ARGUMENTV1_NEW) { if let ExprPath(None, ref path) = args[1].node { - if match_path(path, &DEBUG_FMT_METHOD_PATH) && !is_in_debug_impl(cx, expr) && + if match_path(path, &paths::DEBUG_FMT_METHOD) && !is_in_debug_impl(cx, expr) && is_expn_of(cx, expr.span, "panic").is_none() { span_lint(cx, USE_DEBUG, args[0].span, "use of `Debug`-based formatting"); } diff --git a/src/ptr_arg.rs b/src/ptr_arg.rs index 8720424da86f..addcfc9e84d1 100644 --- a/src/ptr_arg.rs +++ b/src/ptr_arg.rs @@ -1,12 +1,11 @@ //! Checks for usage of `&Vec[_]` and `&String`. +use rustc::hir::*; use rustc::hir::map::NodeItem; use rustc::lint::*; use rustc::ty; -use rustc::hir::*; use syntax::ast::NodeId; -use utils::{STRING_PATH, VEC_PATH}; -use utils::{span_lint, match_type}; +use utils::{match_type, paths, span_lint}; /// **What it does:** This lint checks for function arguments of type `&String` or `&Vec` unless the references are mutable. /// @@ -61,13 +60,13 @@ fn check_fn(cx: &LateContext, decl: &FnDecl, fn_id: NodeId) { for (arg, ty) in decl.inputs.iter().zip(&fn_ty.inputs) { if let ty::TyRef(_, ty::TypeAndMut { ty, mutbl: MutImmutable }) = ty.sty { - if match_type(cx, ty, &VEC_PATH) { + if match_type(cx, ty, &paths::VEC) { span_lint(cx, PTR_ARG, arg.ty.span, "writing `&Vec<_>` instead of `&[_]` involves one more reference and cannot be used \ with non-Vec-based slices. Consider changing the type to `&[...]`"); - } else if match_type(cx, ty, &STRING_PATH) { + } else if match_type(cx, ty, &paths::STRING) { span_lint(cx, PTR_ARG, arg.ty.span, diff --git a/src/regex.rs b/src/regex.rs index f24639312ed8..177f7a7b0458 100644 --- a/src/regex.rs +++ b/src/regex.rs @@ -9,7 +9,8 @@ use std::error::Error; use syntax::ast::{LitKind, NodeId}; use syntax::codemap::{Span, BytePos}; use syntax::parse::token::InternedString; -use utils::{is_expn_of, match_path, match_type, REGEX_NEW_PATH, span_lint, span_help_and_lint}; +use utils::paths; +use utils::{is_expn_of, match_path, match_type, span_lint, span_help_and_lint}; /// **What it does:** This lint checks `Regex::new(_)` invocations for correct regex syntax. /// @@ -97,7 +98,7 @@ impl LateLintPass for RegexPass { if_let_chain!{[ let ExprCall(ref fun, ref args) = expr.node, let ExprPath(_, ref path) = fun.node, - match_path(path, ®EX_NEW_PATH) && args.len() == 1 + match_path(path, &paths::REGEX_NEW) && args.len() == 1 ], { if let ExprLit(ref lit) = args[0].node { if let LitKind::Str(ref r, _) = lit.node { diff --git a/src/strings.rs b/src/strings.rs index da1456671fdf..a6808d2dd421 100644 --- a/src/strings.rs +++ b/src/strings.rs @@ -3,12 +3,11 @@ //! Note that since we have two lints where one subsumes the other, we try to //! disable the subsumed lint unless it has a higher level -use rustc::lint::*; use rustc::hir::*; +use rustc::lint::*; use syntax::codemap::Spanned; -use utils::STRING_PATH; use utils::SpanlessEq; -use utils::{match_type, span_lint, span_lint_and_then, walk_ptrs_ty, get_parent_expr}; +use utils::{match_type, paths, span_lint, span_lint_and_then, walk_ptrs_ty, get_parent_expr}; /// **What it does:** This lint matches code of the form `x = x + y` (without `let`!). /// @@ -108,7 +107,7 @@ impl LateLintPass for StringAdd { } fn is_string(cx: &LateContext, e: &Expr) -> bool { - match_type(cx, walk_ptrs_ty(cx.tcx.expr_ty(e)), &STRING_PATH) + match_type(cx, walk_ptrs_ty(cx.tcx.expr_ty(e)), &paths::STRING) } fn is_add(cx: &LateContext, src: &Expr, target: &Expr) -> bool { diff --git a/src/transmute.rs b/src/transmute.rs index 41b92ca61138..8b74b1989dbd 100644 --- a/src/transmute.rs +++ b/src/transmute.rs @@ -2,8 +2,7 @@ use rustc::lint::*; use rustc::ty::TypeVariants::{TyRawPtr, TyRef}; use rustc::ty; use rustc::hir::*; -use utils::TRANSMUTE_PATH; -use utils::{match_def_path, snippet_opt, span_lint, span_lint_and_then}; +use utils::{match_def_path, paths, snippet_opt, span_lint, span_lint_and_then}; /// **What it does:** This lint checks for transmutes to the original type of the object. /// @@ -67,7 +66,7 @@ impl LateLintPass for Transmute { if let ExprPath(None, _) = path_expr.node { let def_id = cx.tcx.def_map.borrow()[&path_expr.id].def_id(); - if match_def_path(cx, def_id, &TRANSMUTE_PATH) { + if match_def_path(cx, def_id, &paths::TRANSMUTE) { let from_ty = cx.tcx.expr_ty(&args[0]); let to_ty = cx.tcx.expr_ty(e); diff --git a/src/types.rs b/src/types.rs index 281af90736b2..00b36f1f5d4d 100644 --- a/src/types.rs +++ b/src/types.rs @@ -6,7 +6,9 @@ use rustc::ty; use std::cmp::Ordering; use syntax::ast::{IntTy, UintTy, FloatTy}; use syntax::codemap::Span; -use utils::*; +use utils::{comparisons, in_external_macro, in_macro, is_from_for_desugar, match_def_path, snippet, + span_help_and_lint, span_lint}; +use utils::paths; /// Handles all the linting of funky types #[allow(missing_copy_implementations)] @@ -63,7 +65,7 @@ impl LateLintPass for TypePass { let Some(ref vec) = ag.types.get(0), let Some(did) = cx.tcx.def_map.borrow().get(&vec.id), let def::Def::Struct(..) = did.full_def(), - match_def_path(cx, did.def_id(), &VEC_PATH), + match_def_path(cx, did.def_id(), &paths::VEC), ], { span_help_and_lint(cx, @@ -73,7 +75,7 @@ impl LateLintPass for TypePass { "`Vec` is already on the heap, `Box>` makes an extra allocation."); } } - } else if match_def_path(cx, did.def_id(), &LL_PATH) { + } else if match_def_path(cx, did.def_id(), &paths::LL) { span_help_and_lint(cx, LINKEDLIST, ast_ty.span, diff --git a/src/utils/mod.rs b/src/utils/mod.rs index 75637b67d9dc..d01b0698de80 100644 --- a/src/utils/mod.rs +++ b/src/utils/mod.rs @@ -22,45 +22,10 @@ use syntax::ptr::P; pub mod comparisons; pub mod conf; mod hir; +pub mod paths; pub use self::hir::{SpanlessEq, SpanlessHash}; -pub type MethodArgs = HirVec>; -// module DefPaths for certain structs/enums we check for -pub const BEGIN_UNWIND: [&'static str; 3] = ["std", "rt", "begin_unwind"]; -pub const BOX_NEW_PATH: [&'static str; 4] = ["std", "boxed", "Box", "new"]; -pub const BOX_PATH: [&'static str; 3] = ["std", "boxed", "Box"]; -pub const BTREEMAP_ENTRY_PATH: [&'static str; 4] = ["collections", "btree", "map", "Entry"]; -pub const BTREEMAP_PATH: [&'static str; 4] = ["collections", "btree", "map", "BTreeMap"]; -pub const CLONE_PATH: [&'static str; 3] = ["clone", "Clone", "clone"]; -pub const CLONE_TRAIT_PATH: [&'static str; 2] = ["clone", "Clone"]; -pub const COW_PATH: [&'static str; 3] = ["collections", "borrow", "Cow"]; -pub const CSTRING_NEW_PATH: [&'static str; 4] = ["std", "ffi", "CString", "new"]; -pub const DEBUG_FMT_METHOD_PATH: [&'static str; 4] = ["std", "fmt", "Debug", "fmt"]; -pub const DEFAULT_TRAIT_PATH: [&'static str; 3] = ["core", "default", "Default"]; -pub const DISPLAY_FMT_METHOD_PATH: [&'static str; 4] = ["std", "fmt", "Display", "fmt"]; -pub const DROP_PATH: [&'static str; 3] = ["core", "mem", "drop"]; -pub const FMT_ARGUMENTS_NEWV1_PATH: [&'static str; 4] = ["std", "fmt", "Arguments", "new_v1"]; -pub const FMT_ARGUMENTV1_NEW_PATH: [&'static str; 4] = ["std", "fmt", "ArgumentV1", "new"]; -pub const HASHMAP_ENTRY_PATH: [&'static str; 5] = ["std", "collections", "hash", "map", "Entry"]; -pub const HASHMAP_PATH: [&'static str; 5] = ["std", "collections", "hash", "map", "HashMap"]; -pub const HASH_PATH: [&'static str; 2] = ["hash", "Hash"]; -pub const IO_PRINT_PATH: [&'static str; 3] = ["std", "io", "_print"]; -pub const LL_PATH: [&'static str; 3] = ["collections", "linked_list", "LinkedList"]; -pub const MUTEX_PATH: [&'static str; 4] = ["std", "sync", "mutex", "Mutex"]; -pub const OPEN_OPTIONS_PATH: [&'static str; 3] = ["std", "fs", "OpenOptions"]; -pub const OPTION_PATH: [&'static str; 3] = ["core", "option", "Option"]; -pub const RANGE_FROM_PATH: [&'static str; 3] = ["std", "ops", "RangeFrom"]; -pub const RANGE_FULL_PATH: [&'static str; 3] = ["std", "ops", "RangeFull"]; -pub const RANGE_INCLUSIVE_NON_EMPTY_PATH: [&'static str; 4] = ["std", "ops", "RangeInclusive", "NonEmpty"]; -pub const RANGE_PATH: [&'static str; 3] = ["std", "ops", "Range"]; -pub const RANGE_TO_INCLUSIVE_PATH: [&'static str; 3] = ["std", "ops", "RangeToInclusive"]; -pub const RANGE_TO_PATH: [&'static str; 3] = ["std", "ops", "RangeTo"]; -pub const REGEX_NEW_PATH: [&'static str; 3] = ["regex", "Regex", "new"]; -pub const RESULT_PATH: [&'static str; 3] = ["core", "result", "Result"]; -pub const STRING_PATH: [&'static str; 3] = ["collections", "string", "String"]; -pub const TRANSMUTE_PATH: [&'static str; 4] = ["core", "intrinsics", "", "transmute"]; -pub const VEC_FROM_ELEM_PATH: [&'static str; 3] = ["std", "vec", "from_elem"]; -pub const VEC_PATH: [&'static str; 3] = ["collections", "vec", "Vec"]; +pub type MethodArgs = HirVec>; /// Produce a nested chain of if-lets and ifs from the patterns: /// @@ -764,22 +729,22 @@ pub fn unsugar_range(expr: &Expr) -> Option { match unwrap_unstable(&expr).node { ExprPath(None, ref path) => { - if match_path(path, &RANGE_FULL_PATH) { + if match_path(path, &paths::RANGE_FULL) { Some(UnsugaredRange { start: None, end: None, limits: RangeLimits::HalfOpen }) } else { None } } ExprStruct(ref path, ref fields, None) => { - if match_path(path, &RANGE_FROM_PATH) { + if match_path(path, &paths::RANGE_FROM) { Some(UnsugaredRange { start: get_field("start", fields), end: None, limits: RangeLimits::HalfOpen }) - } else if match_path(path, &RANGE_INCLUSIVE_NON_EMPTY_PATH) { + } else if match_path(path, &paths::RANGE_INCLUSIVE_NON_EMPTY) { Some(UnsugaredRange { start: get_field("start", fields), end: get_field("end", fields), limits: RangeLimits::Closed }) - } else if match_path(path, &RANGE_PATH) { + } else if match_path(path, &paths::RANGE) { Some(UnsugaredRange { start: get_field("start", fields), end: get_field("end", fields), limits: RangeLimits::HalfOpen }) - } else if match_path(path, &RANGE_TO_INCLUSIVE_PATH) { + } else if match_path(path, &paths::RANGE_TO_INCLUSIVE) { Some(UnsugaredRange { start: None, end: get_field("end", fields), limits: RangeLimits::Closed }) - } else if match_path(path, &RANGE_TO_PATH) { + } else if match_path(path, &paths::RANGE_TO) { Some(UnsugaredRange { start: None, end: get_field("end", fields), limits: RangeLimits::HalfOpen }) } else { None diff --git a/src/utils/paths.rs b/src/utils/paths.rs new file mode 100644 index 000000000000..94f1d17f27a9 --- /dev/null +++ b/src/utils/paths.rs @@ -0,0 +1,37 @@ +//! This module contains paths to types and functions Clippy needs to know about. + +pub const BEGIN_UNWIND: [&'static str; 3] = ["std", "rt", "begin_unwind"]; +pub const BOX_NEW: [&'static str; 4] = ["std", "boxed", "Box", "new"]; +pub const BOX: [&'static str; 3] = ["std", "boxed", "Box"]; +pub const BTREEMAP_ENTRY: [&'static str; 4] = ["collections", "btree", "map", "Entry"]; +pub const BTREEMAP: [&'static str; 4] = ["collections", "btree", "map", "BTreeMap"]; +pub const CLONE: [&'static str; 3] = ["clone", "Clone", "clone"]; +pub const CLONE_TRAIT: [&'static str; 2] = ["clone", "Clone"]; +pub const COW: [&'static str; 3] = ["collections", "borrow", "Cow"]; +pub const CSTRING_NEW: [&'static str; 4] = ["std", "ffi", "CString", "new"]; +pub const DEBUG_FMT_METHOD: [&'static str; 4] = ["std", "fmt", "Debug", "fmt"]; +pub const DEFAULT_TRAIT: [&'static str; 3] = ["core", "default", "Default"]; +pub const DISPLAY_FMT_METHOD: [&'static str; 4] = ["std", "fmt", "Display", "fmt"]; +pub const DROP: [&'static str; 3] = ["core", "mem", "drop"]; +pub const FMT_ARGUMENTS_NEWV1: [&'static str; 4] = ["std", "fmt", "Arguments", "new_v1"]; +pub const FMT_ARGUMENTV1_NEW: [&'static str; 4] = ["std", "fmt", "ArgumentV1", "new"]; +pub const HASHMAP_ENTRY: [&'static str; 5] = ["std", "collections", "hash", "map", "Entry"]; +pub const HASHMAP: [&'static str; 5] = ["std", "collections", "hash", "map", "HashMap"]; +pub const HASH: [&'static str; 2] = ["hash", "Hash"]; +pub const IO_PRINT: [&'static str; 3] = ["std", "io", "_print"]; +pub const LL: [&'static str; 3] = ["collections", "linked_list", "LinkedList"]; +pub const MUTEX: [&'static str; 4] = ["std", "sync", "mutex", "Mutex"]; +pub const OPEN_OPTIONS: [&'static str; 3] = ["std", "fs", "OpenOptions"]; +pub const OPTION: [&'static str; 3] = ["core", "option", "Option"]; +pub const RANGE_FROM: [&'static str; 3] = ["std", "ops", "RangeFrom"]; +pub const RANGE_FULL: [&'static str; 3] = ["std", "ops", "RangeFull"]; +pub const RANGE_INCLUSIVE_NON_EMPTY: [&'static str; 4] = ["std", "ops", "RangeInclusive", "NonEmpty"]; +pub const RANGE: [&'static str; 3] = ["std", "ops", "Range"]; +pub const RANGE_TO_INCLUSIVE: [&'static str; 3] = ["std", "ops", "RangeToInclusive"]; +pub const RANGE_TO: [&'static str; 3] = ["std", "ops", "RangeTo"]; +pub const REGEX_NEW: [&'static str; 3] = ["regex", "Regex", "new"]; +pub const RESULT: [&'static str; 3] = ["core", "result", "Result"]; +pub const STRING: [&'static str; 3] = ["collections", "string", "String"]; +pub const TRANSMUTE: [&'static str; 4] = ["core", "intrinsics", "", "transmute"]; +pub const VEC_FROM_ELEM: [&'static str; 3] = ["std", "vec", "from_elem"]; +pub const VEC: [&'static str; 3] = ["collections", "vec", "Vec"]; diff --git a/src/vec.rs b/src/vec.rs index d27a3320d96c..513efa1a2a4f 100644 --- a/src/vec.rs +++ b/src/vec.rs @@ -3,8 +3,7 @@ use rustc::ty::TypeVariants; use rustc::hir::*; use syntax::codemap::Span; use syntax::ptr::P; -use utils::VEC_FROM_ELEM_PATH; -use utils::{is_expn_of, match_path, recover_for_loop, snippet, span_lint_and_then}; +use utils::{is_expn_of, match_path, paths, recover_for_loop, snippet, span_lint_and_then}; /// **What it does:** This lint warns about using `&vec![..]` when using `&[..]` would be possible. /// @@ -92,7 +91,7 @@ pub fn unexpand_vec<'e>(cx: &LateContext, expr: &'e Expr) -> Option> let ExprPath(_, ref path) = fun.node, is_expn_of(cx, fun.span, "vec").is_some() ], { - return if match_path(path, &VEC_FROM_ELEM_PATH) && args.len() == 2 { + return if match_path(path, &paths::VEC_FROM_ELEM) && args.len() == 2 { // `vec![elem; size]` case Some(VecArgs::Repeat(&args[0], &args[1])) }