mirror of
https://github.com/rust-lang/rust.git
synced 2025-05-14 02:49:40 +00:00
Move paths to their own module
This commit is contained in:
parent
d81481bd0d
commit
48a672b4ee
@ -7,7 +7,8 @@ use semver::Version;
|
|||||||
use syntax::ast::{Attribute, Lit, LitKind, MetaItemKind};
|
use syntax::ast::{Attribute, Lit, LitKind, MetaItemKind};
|
||||||
use syntax::attr::*;
|
use syntax::attr::*;
|
||||||
use syntax::codemap::Span;
|
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.
|
/// **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,
|
ExprRet(None) | ExprBreak(_) => false,
|
||||||
ExprCall(ref path_expr, _) => {
|
ExprCall(ref path_expr, _) => {
|
||||||
if let ExprPath(_, ref path) = path_expr.node {
|
if let ExprPath(_, ref path) = path_expr.node {
|
||||||
!match_path(path, &BEGIN_UNWIND)
|
!match_path(path, &paths::BEGIN_UNWIND)
|
||||||
} else {
|
} else {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@ use rustc::ty;
|
|||||||
use rustc::hir::*;
|
use rustc::hir::*;
|
||||||
use syntax::ast::{Attribute, MetaItemKind};
|
use syntax::ast::{Attribute, MetaItemKind};
|
||||||
use syntax::codemap::Span;
|
use syntax::codemap::Span;
|
||||||
use utils::{CLONE_TRAIT_PATH, HASH_PATH};
|
use utils::paths;
|
||||||
use utils::{match_path, span_lint_and_then};
|
use utils::{match_path, span_lint_and_then};
|
||||||
|
|
||||||
/// **What it does:** This lint warns about deriving `Hash` but implementing `PartialEq`
|
/// **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.
|
/// 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) {
|
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! {[
|
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 Some(peq_trait_def_id) = cx.tcx.lang_items.eq_trait()
|
||||||
], {
|
], {
|
||||||
let peq_trait_def = cx.tcx.lookup_trait_def(peq_trait_def_id);
|
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.
|
/// 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>) {
|
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 parameter_environment = ty::ParameterEnvironment::for_item(cx.tcx, item.id);
|
||||||
let subst_ty = ty.subst(cx.tcx, ¶meter_environment.free_substs);
|
let subst_ty = ty.subst(cx.tcx, ¶meter_environment.free_substs);
|
||||||
|
|
||||||
|
@ -2,8 +2,7 @@ use rustc::lint::*;
|
|||||||
use rustc::ty;
|
use rustc::ty;
|
||||||
use rustc::hir::*;
|
use rustc::hir::*;
|
||||||
use syntax::codemap::Span;
|
use syntax::codemap::Span;
|
||||||
use utils::DROP_PATH;
|
use utils::{match_def_path, paths, span_note_and_lint};
|
||||||
use utils::{match_def_path, span_note_and_lint};
|
|
||||||
|
|
||||||
/// **What it does:** This lint checks for calls to `std::mem::drop` with a reference instead of an owned value.
|
/// **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 ExprCall(ref path, ref args) = expr.node {
|
||||||
if let ExprPath(None, _) = path.node {
|
if let ExprPath(None, _) = path.node {
|
||||||
let def_id = cx.tcx.def_map.borrow()[&path.id].def_id();
|
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 {
|
if args.len() != 1 {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,9 @@
|
|||||||
use rustc::lint::*;
|
|
||||||
use rustc::hir::*;
|
use rustc::hir::*;
|
||||||
use rustc::hir::intravisit::{Visitor, walk_expr, walk_block};
|
use rustc::hir::intravisit::{Visitor, walk_expr, walk_block};
|
||||||
|
use rustc::lint::*;
|
||||||
use syntax::codemap::Span;
|
use syntax::codemap::Span;
|
||||||
use utils::SpanlessEq;
|
use utils::SpanlessEq;
|
||||||
use utils::{BTREEMAP_PATH, HASHMAP_PATH};
|
use utils::{get_item_name, match_type, paths, snippet, span_lint_and_then, walk_ptrs_ty};
|
||||||
use utils::{get_item_name, match_type, snippet, span_lint_and_then, walk_ptrs_ty};
|
|
||||||
|
|
||||||
/// **What it does:** This lint checks for uses of `contains_key` + `insert` on `HashMap` or
|
/// **What it does:** This lint checks for uses of `contains_key` + `insert` on `HashMap` or
|
||||||
/// `BTreeMap`.
|
/// `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 map = ¶ms[0];
|
||||||
let obj_ty = walk_ptrs_ty(cx.tcx.expr_ty(map));
|
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))
|
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))
|
Some(("HashMap", map, key))
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
|
use rustc::hir::*;
|
||||||
use rustc::hir::map::Node::NodeItem;
|
use rustc::hir::map::Node::NodeItem;
|
||||||
use rustc::lint::*;
|
use rustc::lint::*;
|
||||||
use rustc::ty::TypeVariants;
|
use rustc::ty::TypeVariants;
|
||||||
use rustc::hir::*;
|
|
||||||
use syntax::ast::LitKind;
|
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};
|
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
|
/// **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!{[
|
if_let_chain!{[
|
||||||
let ExprPath(_, ref path) = fun.node,
|
let ExprPath(_, ref path) = fun.node,
|
||||||
args.len() == 2,
|
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
|
// ensure the format string is `"{..}"` with only one argument and no text
|
||||||
check_static_str(cx, &args[0]),
|
check_static_str(cx, &args[0]),
|
||||||
// ensure the format argument is `{}` ie. Display with no fancy option
|
// 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,
|
let ExprCall(_, ref args) = exprs[0].node,
|
||||||
args.len() == 2,
|
args.len() == 2,
|
||||||
let ExprPath(None, ref path) = args[1].node,
|
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]));
|
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
|
false
|
||||||
|
16
src/loops.rs
16
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,
|
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,
|
span_help_and_lint, is_integer_literal, get_enclosing_block, span_lint_and_then,
|
||||||
unsugar_range, walk_ptrs_ty, recover_for_loop};
|
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;
|
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.
|
/// **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`
|
/// Check for `for` loops over `Option`s and `Results`
|
||||||
fn check_arg_type(cx: &LateContext, pat: &Pat, arg: &Expr) {
|
fn check_arg_type(cx: &LateContext, pat: &Pat, arg: &Expr) {
|
||||||
let ty = cx.tcx.expr_ty(arg);
|
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,
|
span_help_and_lint(cx,
|
||||||
FOR_LOOP_OVER_OPTION,
|
FOR_LOOP_OVER_OPTION,
|
||||||
arg.span,
|
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}`",
|
&format!("consider replacing `for {0} in {1}` with `if let Some({0}) = {1}`",
|
||||||
snippet(cx, pat.span, "_"),
|
snippet(cx, pat.span, "_"),
|
||||||
snippet(cx, arg.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,
|
span_help_and_lint(cx,
|
||||||
FOR_LOOP_OVER_RESULT,
|
FOR_LOOP_OVER_RESULT,
|
||||||
arg.span,
|
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));
|
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,
|
span_lint_and_then(cx,
|
||||||
FOR_KV_MAP,
|
FOR_KV_MAP,
|
||||||
expr.span,
|
expr.span,
|
||||||
@ -735,13 +735,13 @@ fn is_ref_iterable_type(cx: &LateContext, e: &Expr) -> bool {
|
|||||||
// will allow further borrows afterwards
|
// will allow further borrows afterwards
|
||||||
let ty = cx.tcx.expr_ty(e);
|
let ty = cx.tcx.expr_ty(e);
|
||||||
is_iterable_array(ty) ||
|
is_iterable_array(ty) ||
|
||||||
match_type(cx, ty, &VEC_PATH) ||
|
match_type(cx, ty, &paths::VEC) ||
|
||||||
match_type(cx, ty, &LL_PATH) ||
|
match_type(cx, ty, &paths::LL) ||
|
||||||
match_type(cx, ty, &HASHMAP_PATH) ||
|
match_type(cx, ty, &paths::HASHMAP) ||
|
||||||
match_type(cx, ty, &["std", "collections", "hash", "set", "HashSet"]) ||
|
match_type(cx, ty, &["std", "collections", "hash", "set", "HashSet"]) ||
|
||||||
match_type(cx, ty, &["collections", "vec_deque", "VecDeque"]) ||
|
match_type(cx, ty, &["collections", "vec_deque", "VecDeque"]) ||
|
||||||
match_type(cx, ty, &["collections", "binary_heap", "BinaryHeap"]) ||
|
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"])
|
match_type(cx, ty, &["collections", "btree", "set", "BTreeSet"])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
use rustc::lint::*;
|
use rustc::lint::*;
|
||||||
use rustc::hir::*;
|
use rustc::hir::*;
|
||||||
use utils::{CLONE_PATH, OPTION_PATH};
|
use utils::{is_adjusted, match_path, match_trait_method, match_type, paths, snippet,
|
||||||
use utils::{is_adjusted, match_path, match_trait_method, match_type, snippet, span_help_and_lint, walk_ptrs_ty,
|
span_help_and_lint, walk_ptrs_ty, walk_ptrs_ty_depth};
|
||||||
walk_ptrs_ty_depth};
|
|
||||||
|
|
||||||
/// **What it does:** This lint checks for mapping clone() over an iterator.
|
/// **What it does:** This lint checks for mapping clone() over an iterator.
|
||||||
///
|
///
|
||||||
@ -65,7 +64,7 @@ impl LateLintPass for MapClonePass {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
ExprPath(_, ref path) => {
|
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("_");
|
let type_name = get_type_name(cx, expr, &args[0]).unwrap_or("_");
|
||||||
span_help_and_lint(cx,
|
span_help_and_lint(cx,
|
||||||
MAP_CLONE,
|
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> {
|
fn get_type_name(cx: &LateContext, expr: &Expr, arg: &Expr) -> Option<&'static str> {
|
||||||
if match_trait_method(cx, expr, &["core", "iter", "Iterator"]) {
|
if match_trait_method(cx, expr, &["core", "iter", "Iterator"]) {
|
||||||
Some("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")
|
Some("Option")
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
@ -8,7 +8,7 @@ use rustc_const_math::ConstInt;
|
|||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
use syntax::ast::LitKind;
|
use syntax::ast::LitKind;
|
||||||
use syntax::codemap::Span;
|
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};
|
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.
|
/// **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>) {
|
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
|
// list of candidate Enums we know will never get any more members
|
||||||
let candidates = &[(&COW_PATH, "Borrowed"),
|
let candidates = &[(&paths::COW, "Borrowed"),
|
||||||
(&COW_PATH, "Cow::Borrowed"),
|
(&paths::COW, "Cow::Borrowed"),
|
||||||
(&COW_PATH, "Cow::Owned"),
|
(&paths::COW, "Cow::Owned"),
|
||||||
(&COW_PATH, "Owned"),
|
(&paths::COW, "Owned"),
|
||||||
(&OPTION_PATH, "None"),
|
(&paths::OPTION, "None"),
|
||||||
(&RESULT_PATH, "Err"),
|
(&paths::RESULT, "Err"),
|
||||||
(&RESULT_PATH, "Ok")];
|
(&paths::RESULT, "Ok")];
|
||||||
|
|
||||||
let path = match arms[1].pats[0].node {
|
let path = match arms[1].pats[0].node {
|
||||||
PatKind::TupleStruct(ref path, Some(ref inner)) => {
|
PatKind::TupleStruct(ref path, Some(ref inner)) => {
|
||||||
|
@ -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,
|
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,
|
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};
|
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::MethodArgs;
|
||||||
|
use utils::paths;
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct MethodsPass;
|
pub struct MethodsPass;
|
||||||
@ -470,7 +469,7 @@ fn lint_or_fun_call(cx: &LateContext, expr: &Expr, name: &str, args: &[P<Expr>])
|
|||||||
|
|
||||||
if ["default", "new"].contains(&path) {
|
if ["default", "new"].contains(&path) {
|
||||||
let arg_ty = cx.tcx.expr_ty(arg);
|
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
|
default_trait_id
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
@ -497,13 +496,13 @@ fn lint_or_fun_call(cx: &LateContext, expr: &Expr, name: &str, args: &[P<Expr>])
|
|||||||
fn check_general_case(cx: &LateContext, name: &str, fun: &Expr, self_expr: &Expr, arg: &Expr, or_has_args: bool,
|
fn check_general_case(cx: &LateContext, name: &str, fun: &Expr, self_expr: &Expr, arg: &Expr, or_has_args: bool,
|
||||||
span: Span) {
|
span: Span) {
|
||||||
// (path, fn_has_argument, methods)
|
// (path, fn_has_argument, methods)
|
||||||
let know_types: &[(&[_], _, &[_], _)] = &[(&BTREEMAP_ENTRY_PATH, false, &["or_insert"], "with"),
|
let know_types: &[(&[_], _, &[_], _)] = &[(&paths::BTREEMAP_ENTRY, false, &["or_insert"], "with"),
|
||||||
(&HASHMAP_ENTRY_PATH, false, &["or_insert"], "with"),
|
(&paths::HASHMAP_ENTRY, false, &["or_insert"], "with"),
|
||||||
(&OPTION_PATH,
|
(&paths::OPTION,
|
||||||
false,
|
false,
|
||||||
&["map_or", "ok_or", "or", "unwrap_or"],
|
&["map_or", "ok_or", "or", "unwrap_or"],
|
||||||
"else"),
|
"else"),
|
||||||
(&RESULT_PATH, true, &["or", "unwrap_or"], "else")];
|
(&paths::RESULT, true, &["or", "unwrap_or"], "else")];
|
||||||
|
|
||||||
let self_ty = cx.tcx.expr_ty(self_expr);
|
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) {
|
fn lint_extend(cx: &LateContext, expr: &Expr, args: &MethodArgs) {
|
||||||
let (obj_ty, _) = walk_ptrs_ty_depth(cx.tcx.expr_ty(&args[0]));
|
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;
|
return;
|
||||||
}
|
}
|
||||||
let arg_ty = cx.tcx.expr_ty(&args[1]);
|
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,
|
let ExprCall(ref fun, ref args) = new.node,
|
||||||
args.len() == 1,
|
args.len() == 1,
|
||||||
let ExprPath(None, ref path) = fun.node,
|
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,
|
span_lint_and_then(cx, TEMPORARY_CSTRING_AS_PTR, expr.span,
|
||||||
"you are getting the inner pointer of a temporary `CString`",
|
"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 {
|
fn may_slice(cx: &LateContext, ty: &ty::Ty) -> bool {
|
||||||
match ty.sty {
|
match ty.sty {
|
||||||
ty::TySlice(_) => true,
|
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::TyArray(_, size) => size < 32,
|
||||||
ty::TyRef(_, ty::TypeAndMut { ty: ref inner, .. }) |
|
ty::TyRef(_, ty::TypeAndMut { ty: ref inner, .. }) |
|
||||||
ty::TyBox(ref inner) => may_slice(cx, 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) {
|
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 (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"))
|
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"))
|
Some((RESULT_UNWRAP_USED, "a Result", "Err"))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
@ -666,7 +665,7 @@ fn lint_unwrap(cx: &LateContext, expr: &Expr, unwrap_args: &MethodArgs) {
|
|||||||
/// lint use of `ok().expect()` for `Result`s
|
/// lint use of `ok().expect()` for `Result`s
|
||||||
fn lint_ok_expect(cx: &LateContext, expr: &Expr, ok_args: &MethodArgs) {
|
fn lint_ok_expect(cx: &LateContext, expr: &Expr, ok_args: &MethodArgs) {
|
||||||
// lint if the caller of `ok()` is a `Result`
|
// 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]);
|
let result_type = cx.tcx.expr_ty(&ok_args[0]);
|
||||||
if let Some(error_type) = get_error_type(cx, result_type) {
|
if let Some(error_type) = get_error_type(cx, result_type) {
|
||||||
if has_debug_impl(error_type, cx) {
|
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
|
/// lint use of `map().unwrap_or()` for `Option`s
|
||||||
fn lint_map_unwrap_or(cx: &LateContext, expr: &Expr, map_args: &MethodArgs, unwrap_args: &MethodArgs) {
|
fn lint_map_unwrap_or(cx: &LateContext, expr: &Expr, map_args: &MethodArgs, unwrap_args: &MethodArgs) {
|
||||||
// lint if the caller of `map()` is an `Option`
|
// 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
|
// lint message
|
||||||
let msg = "called `map(f).unwrap_or(a)` on an Option value. This can be done more directly by calling \
|
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";
|
`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
|
/// 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) {
|
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`
|
// 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
|
// lint message
|
||||||
let msg = "called `map(f).unwrap_or_else(g)` on an Option value. This can be done more directly by calling \
|
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";
|
`map_or_else(g, f)` instead";
|
||||||
@ -842,7 +841,7 @@ fn lint_single_char_pattern(cx: &LateContext, expr: &Expr, arg: &Expr) {
|
|||||||
|
|
||||||
/// Given a `Result<T, E>` type, return its error type (`E`).
|
/// Given a `Result<T, E>` type, return its error type (`E`).
|
||||||
fn get_error_type<'a>(cx: &LateContext, ty: ty::Ty<'a>) -> Option<ty::Ty<'a>> {
|
fn get_error_type<'a>(cx: &LateContext, ty: ty::Ty<'a>) -> Option<ty::Ty<'a>> {
|
||||||
if !match_type(cx, ty, &RESULT_PATH) {
|
if !match_type(cx, ty, &paths::RESULT) {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
if let ty::TyEnum(_, substs) = ty.sty {
|
if let ty::TyEnum(_, substs) = ty.sty {
|
||||||
@ -853,7 +852,7 @@ fn get_error_type<'a>(cx: &LateContext, ty: ty::Ty<'a>) -> Option<ty::Ty<'a>> {
|
|||||||
None
|
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 {
|
fn has_debug_impl<'a, 'b>(ty: ty::Ty<'a>, cx: &LateContext<'b, 'a>) -> bool {
|
||||||
match cx.tcx.lang_items.debug_trait() {
|
match cx.tcx.lang_items.debug_trait() {
|
||||||
Some(debug) => implements_trait(cx, ty, debug, Vec::new()),
|
Some(debug) => implements_trait(cx, ty, debug, Vec::new()),
|
||||||
|
@ -7,7 +7,7 @@ use rustc::ty::subst::ParamSpace;
|
|||||||
use rustc::ty;
|
use rustc::ty;
|
||||||
use rustc::hir::Expr;
|
use rustc::hir::Expr;
|
||||||
use syntax::ast;
|
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<X>` where an atomic will do.
|
/// **What it does:** This lint checks for usages of `Mutex<X>` where an atomic will do.
|
||||||
///
|
///
|
||||||
@ -47,7 +47,7 @@ impl LateLintPass for MutexAtomic {
|
|||||||
fn check_expr(&mut self, cx: &LateContext, expr: &Expr) {
|
fn check_expr(&mut self, cx: &LateContext, expr: &Expr) {
|
||||||
let ty = cx.tcx.expr_ty(expr);
|
let ty = cx.tcx.expr_ty(expr);
|
||||||
if let ty::TyStruct(_, subst) = ty.sty {
|
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;
|
let mutex_param = &subst.types.get(ParamSpace::TypeSpace, 0).sty;
|
||||||
if let Some(atomic_name) = get_atomic_name(mutex_param) {
|
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 \
|
let msg = format!("Consider using an {} instead of a Mutex here. If you just want the locking \
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
use rustc::lint::*;
|
|
||||||
use rustc::hir;
|
|
||||||
use rustc::hir::intravisit::FnKind;
|
use rustc::hir::intravisit::FnKind;
|
||||||
|
use rustc::hir;
|
||||||
|
use rustc::lint::*;
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
use syntax::codemap::Span;
|
use syntax::codemap::Span;
|
||||||
use utils::{get_trait_def_id, implements_trait, in_external_macro, return_ty, same_tys, span_lint,
|
use utils::paths;
|
||||||
DEFAULT_TRAIT_PATH};
|
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`
|
/// **What it does:** This lints about type with a `fn new() -> Self` method and no `Default`
|
||||||
/// implementation.
|
/// implementation.
|
||||||
@ -54,7 +54,7 @@ impl LateLintPass for NewWithoutDefault {
|
|||||||
self_ty.walk_shallow().next().is_none(), // implements_trait does not work with generics
|
self_ty.walk_shallow().next().is_none(), // implements_trait does not work with generics
|
||||||
let Some(ret_ty) = return_ty(cx, id),
|
let Some(ret_ty) = return_ty(cx, id),
|
||||||
same_tys(cx, self_ty, ret_ty, 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())
|
!implements_trait(cx, self_ty, default_trait_id, Vec::new())
|
||||||
], {
|
], {
|
||||||
span_lint(cx, NEW_WITHOUT_DEFAULT, span,
|
span_lint(cx, NEW_WITHOUT_DEFAULT, span,
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
use rustc::lint::*;
|
|
||||||
use rustc::hir::{Expr, ExprMethodCall, ExprLit};
|
use rustc::hir::{Expr, ExprMethodCall, ExprLit};
|
||||||
|
use rustc::lint::*;
|
||||||
use syntax::ast::LitKind;
|
use syntax::ast::LitKind;
|
||||||
use syntax::codemap::{Span, Spanned};
|
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.
|
/// **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) {
|
fn check_expr(&mut self, cx: &LateContext, e: &Expr) {
|
||||||
if let ExprMethodCall(ref name, _, ref arguments) = e.node {
|
if let ExprMethodCall(ref name, _, ref arguments) = e.node {
|
||||||
let (obj_ty, _) = walk_ptrs_ty_depth(cx.tcx.expr_ty(&arguments[0]));
|
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();
|
let mut options = Vec::new();
|
||||||
get_open_options(cx, &arguments[0], &mut options);
|
get_open_options(cx, &arguments[0], &mut options);
|
||||||
check_open_options(cx, &options, e.span);
|
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]));
|
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
|
// 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 {
|
let argument_option = match arguments[1].node {
|
||||||
ExprLit(ref span) => {
|
ExprLit(ref span) => {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use rustc::lint::*;
|
|
||||||
use rustc::hir::*;
|
use rustc::hir::*;
|
||||||
|
use rustc::lint::*;
|
||||||
use syntax::ast::LitKind;
|
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!`.
|
/// **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,
|
let ExprCall(ref fun, ref params) = ex.node,
|
||||||
params.len() == 2,
|
params.len() == 2,
|
||||||
let ExprPath(None, ref path) = fun.node,
|
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,
|
let ExprLit(ref lit) = params[0].node,
|
||||||
is_direct_expn_of(cx, params[0].span, "panic").is_some(),
|
is_direct_expn_of(cx, params[0].span, "panic").is_some(),
|
||||||
let LitKind::Str(ref string, _) = lit.node,
|
let LitKind::Str(ref string, _) = lit.node,
|
||||||
|
10
src/print.rs
10
src/print.rs
@ -1,7 +1,7 @@
|
|||||||
|
use rustc::hir::*;
|
||||||
use rustc::hir::map::Node::{NodeItem, NodeImplItem};
|
use rustc::hir::map::Node::{NodeItem, NodeImplItem};
|
||||||
use rustc::lint::*;
|
use rustc::lint::*;
|
||||||
use rustc::hir::*;
|
use utils::paths;
|
||||||
use utils::{FMT_ARGUMENTV1_NEW_PATH, DEBUG_FMT_METHOD_PATH, IO_PRINT_PATH};
|
|
||||||
use utils::{is_expn_of, match_path, span_lint};
|
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.
|
/// **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 {
|
if let ExprPath(_, ref path) = fun.node {
|
||||||
// Search for `std::io::_print(..)` which is unique in a
|
// Search for `std::io::_print(..)` which is unique in a
|
||||||
// `print!` expansion.
|
// `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") {
|
if let Some(span) = is_expn_of(cx, expr.span, "print") {
|
||||||
// `println!` uses `print!`.
|
// `println!` uses `print!`.
|
||||||
let (span, name) = match is_expn_of(cx, span, "println") {
|
let (span, name) = match is_expn_of(cx, span, "println") {
|
||||||
@ -58,9 +58,9 @@ impl LateLintPass for PrintLint {
|
|||||||
}
|
}
|
||||||
// Search for something like
|
// Search for something like
|
||||||
// `::std::fmt::ArgumentV1::new(__arg0, ::std::fmt::Debug::fmt)`
|
// `::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 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() {
|
is_expn_of(cx, expr.span, "panic").is_none() {
|
||||||
span_lint(cx, USE_DEBUG, args[0].span, "use of `Debug`-based formatting");
|
span_lint(cx, USE_DEBUG, args[0].span, "use of `Debug`-based formatting");
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,11 @@
|
|||||||
//! Checks for usage of `&Vec[_]` and `&String`.
|
//! Checks for usage of `&Vec[_]` and `&String`.
|
||||||
|
|
||||||
|
use rustc::hir::*;
|
||||||
use rustc::hir::map::NodeItem;
|
use rustc::hir::map::NodeItem;
|
||||||
use rustc::lint::*;
|
use rustc::lint::*;
|
||||||
use rustc::ty;
|
use rustc::ty;
|
||||||
use rustc::hir::*;
|
|
||||||
use syntax::ast::NodeId;
|
use syntax::ast::NodeId;
|
||||||
use utils::{STRING_PATH, VEC_PATH};
|
use utils::{match_type, paths, span_lint};
|
||||||
use utils::{span_lint, match_type};
|
|
||||||
|
|
||||||
/// **What it does:** This lint checks for function arguments of type `&String` or `&Vec` unless the references are mutable.
|
/// **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) {
|
for (arg, ty) in decl.inputs.iter().zip(&fn_ty.inputs) {
|
||||||
if let ty::TyRef(_, ty::TypeAndMut { ty, mutbl: MutImmutable }) = ty.sty {
|
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,
|
span_lint(cx,
|
||||||
PTR_ARG,
|
PTR_ARG,
|
||||||
arg.ty.span,
|
arg.ty.span,
|
||||||
"writing `&Vec<_>` instead of `&[_]` involves one more reference and cannot be used \
|
"writing `&Vec<_>` instead of `&[_]` involves one more reference and cannot be used \
|
||||||
with non-Vec-based slices. Consider changing the type to `&[...]`");
|
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,
|
span_lint(cx,
|
||||||
PTR_ARG,
|
PTR_ARG,
|
||||||
arg.ty.span,
|
arg.ty.span,
|
||||||
|
@ -9,7 +9,8 @@ use std::error::Error;
|
|||||||
use syntax::ast::{LitKind, NodeId};
|
use syntax::ast::{LitKind, NodeId};
|
||||||
use syntax::codemap::{Span, BytePos};
|
use syntax::codemap::{Span, BytePos};
|
||||||
use syntax::parse::token::InternedString;
|
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.
|
/// **What it does:** This lint checks `Regex::new(_)` invocations for correct regex syntax.
|
||||||
///
|
///
|
||||||
@ -97,7 +98,7 @@ impl LateLintPass for RegexPass {
|
|||||||
if_let_chain!{[
|
if_let_chain!{[
|
||||||
let ExprCall(ref fun, ref args) = expr.node,
|
let ExprCall(ref fun, ref args) = expr.node,
|
||||||
let ExprPath(_, ref path) = fun.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 ExprLit(ref lit) = args[0].node {
|
||||||
if let LitKind::Str(ref r, _) = lit.node {
|
if let LitKind::Str(ref r, _) = lit.node {
|
||||||
|
@ -3,12 +3,11 @@
|
|||||||
//! Note that since we have two lints where one subsumes the other, we try to
|
//! 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
|
//! disable the subsumed lint unless it has a higher level
|
||||||
|
|
||||||
use rustc::lint::*;
|
|
||||||
use rustc::hir::*;
|
use rustc::hir::*;
|
||||||
|
use rustc::lint::*;
|
||||||
use syntax::codemap::Spanned;
|
use syntax::codemap::Spanned;
|
||||||
use utils::STRING_PATH;
|
|
||||||
use utils::SpanlessEq;
|
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`!).
|
/// **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 {
|
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 {
|
fn is_add(cx: &LateContext, src: &Expr, target: &Expr) -> bool {
|
||||||
|
@ -2,8 +2,7 @@ use rustc::lint::*;
|
|||||||
use rustc::ty::TypeVariants::{TyRawPtr, TyRef};
|
use rustc::ty::TypeVariants::{TyRawPtr, TyRef};
|
||||||
use rustc::ty;
|
use rustc::ty;
|
||||||
use rustc::hir::*;
|
use rustc::hir::*;
|
||||||
use utils::TRANSMUTE_PATH;
|
use utils::{match_def_path, paths, snippet_opt, span_lint, span_lint_and_then};
|
||||||
use utils::{match_def_path, snippet_opt, span_lint, span_lint_and_then};
|
|
||||||
|
|
||||||
/// **What it does:** This lint checks for transmutes to the original type of the object.
|
/// **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 {
|
if let ExprPath(None, _) = path_expr.node {
|
||||||
let def_id = cx.tcx.def_map.borrow()[&path_expr.id].def_id();
|
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 from_ty = cx.tcx.expr_ty(&args[0]);
|
||||||
let to_ty = cx.tcx.expr_ty(e);
|
let to_ty = cx.tcx.expr_ty(e);
|
||||||
|
|
||||||
|
@ -6,7 +6,9 @@ use rustc::ty;
|
|||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
use syntax::ast::{IntTy, UintTy, FloatTy};
|
use syntax::ast::{IntTy, UintTy, FloatTy};
|
||||||
use syntax::codemap::Span;
|
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
|
/// Handles all the linting of funky types
|
||||||
#[allow(missing_copy_implementations)]
|
#[allow(missing_copy_implementations)]
|
||||||
@ -63,7 +65,7 @@ impl LateLintPass for TypePass {
|
|||||||
let Some(ref vec) = ag.types.get(0),
|
let Some(ref vec) = ag.types.get(0),
|
||||||
let Some(did) = cx.tcx.def_map.borrow().get(&vec.id),
|
let Some(did) = cx.tcx.def_map.borrow().get(&vec.id),
|
||||||
let def::Def::Struct(..) = did.full_def(),
|
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,
|
span_help_and_lint(cx,
|
||||||
@ -73,7 +75,7 @@ impl LateLintPass for TypePass {
|
|||||||
"`Vec<T>` is already on the heap, `Box<Vec<T>>` makes an extra allocation.");
|
"`Vec<T>` is already on the heap, `Box<Vec<T>>` 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,
|
span_help_and_lint(cx,
|
||||||
LINKEDLIST,
|
LINKEDLIST,
|
||||||
ast_ty.span,
|
ast_ty.span,
|
||||||
|
@ -22,45 +22,10 @@ use syntax::ptr::P;
|
|||||||
pub mod comparisons;
|
pub mod comparisons;
|
||||||
pub mod conf;
|
pub mod conf;
|
||||||
mod hir;
|
mod hir;
|
||||||
|
pub mod paths;
|
||||||
pub use self::hir::{SpanlessEq, SpanlessHash};
|
pub use self::hir::{SpanlessEq, SpanlessHash};
|
||||||
pub type MethodArgs = HirVec<P<Expr>>;
|
|
||||||
|
|
||||||
// module DefPaths for certain structs/enums we check for
|
pub type MethodArgs = HirVec<P<Expr>>;
|
||||||
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"];
|
|
||||||
|
|
||||||
/// Produce a nested chain of if-lets and ifs from the patterns:
|
/// Produce a nested chain of if-lets and ifs from the patterns:
|
||||||
///
|
///
|
||||||
@ -764,22 +729,22 @@ pub fn unsugar_range(expr: &Expr) -> Option<UnsugaredRange> {
|
|||||||
|
|
||||||
match unwrap_unstable(&expr).node {
|
match unwrap_unstable(&expr).node {
|
||||||
ExprPath(None, ref path) => {
|
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 })
|
Some(UnsugaredRange { start: None, end: None, limits: RangeLimits::HalfOpen })
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ExprStruct(ref path, ref fields, 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 })
|
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 })
|
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 })
|
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 })
|
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 })
|
Some(UnsugaredRange { start: None, end: get_field("end", fields), limits: RangeLimits::HalfOpen })
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
37
src/utils/paths.rs
Normal file
37
src/utils/paths.rs
Normal file
@ -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"];
|
@ -3,8 +3,7 @@ use rustc::ty::TypeVariants;
|
|||||||
use rustc::hir::*;
|
use rustc::hir::*;
|
||||||
use syntax::codemap::Span;
|
use syntax::codemap::Span;
|
||||||
use syntax::ptr::P;
|
use syntax::ptr::P;
|
||||||
use utils::VEC_FROM_ELEM_PATH;
|
use utils::{is_expn_of, match_path, paths, recover_for_loop, snippet, span_lint_and_then};
|
||||||
use utils::{is_expn_of, match_path, recover_for_loop, snippet, span_lint_and_then};
|
|
||||||
|
|
||||||
/// **What it does:** This lint warns about using `&vec![..]` when using `&[..]` would be possible.
|
/// **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<VecArgs<'e>>
|
|||||||
let ExprPath(_, ref path) = fun.node,
|
let ExprPath(_, ref path) = fun.node,
|
||||||
is_expn_of(cx, fun.span, "vec").is_some()
|
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
|
// `vec![elem; size]` case
|
||||||
Some(VecArgs::Repeat(&args[0], &args[1]))
|
Some(VecArgs::Repeat(&args[0], &args[1]))
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user