rustfmt
This commit is contained in:
parent
e256055dc4
commit
bd45cfd273
@ -92,8 +92,7 @@ fn check_expr(&mut self, cx: &LateContext, expr: &Expr) {
|
||||
snippet_block(cx, then.span, "..")));
|
||||
}
|
||||
} else {
|
||||
let span = block.expr.as_ref().map_or_else(|| block.stmts[0].span,
|
||||
|e| e.span);
|
||||
let span = block.expr.as_ref().map_or_else(|| block.stmts[0].span, |e| e.span);
|
||||
if in_macro(cx, span) || differing_macro_contexts(expr.span, span) {
|
||||
return;
|
||||
}
|
||||
|
@ -71,15 +71,13 @@ fn check_if(cx: &LateContext, e: &Expr) {
|
||||
});
|
||||
}}
|
||||
} else if let Some(&Expr{ node: ExprIf(ref check_inner, ref content, None), span: sp, ..}) =
|
||||
single_stmt_of_block(then) {
|
||||
single_stmt_of_block(then) {
|
||||
if e.span.expn_id != sp.expn_id {
|
||||
return;
|
||||
}
|
||||
span_lint_and_then(cx,
|
||||
COLLAPSIBLE_IF,
|
||||
e.span,
|
||||
"this if statement can be collapsed", |db| {
|
||||
db.span_suggestion(e.span, "try",
|
||||
span_lint_and_then(cx, COLLAPSIBLE_IF, e.span, "this if statement can be collapsed", |db| {
|
||||
db.span_suggestion(e.span,
|
||||
"try",
|
||||
format!("if {} && {} {}",
|
||||
check_to_string(cx, check),
|
||||
check_to_string(cx, check_inner),
|
||||
|
@ -91,9 +91,7 @@ fn lint_same_then_else(cx: &LateContext, blocks: &[&Block]) {
|
||||
h.finish()
|
||||
};
|
||||
|
||||
let eq: &Fn(&&Block, &&Block) -> bool = &|&lhs, &rhs| -> bool {
|
||||
SpanlessEq::new(cx).eq_block(lhs, rhs)
|
||||
};
|
||||
let eq: &Fn(&&Block, &&Block) -> bool = &|&lhs, &rhs| -> bool { SpanlessEq::new(cx).eq_block(lhs, rhs) };
|
||||
|
||||
if let Some((i, j)) = search_same(blocks, hash, eq) {
|
||||
span_note_and_lint(cx,
|
||||
|
@ -87,13 +87,7 @@ fn check_item(&mut self, cx: &LateContext, item: &Item) {
|
||||
}
|
||||
|
||||
/// Implementation of the `DERIVE_HASH_XOR_EQ` lint.
|
||||
fn check_hash_peq(
|
||||
cx: &LateContext,
|
||||
span: Span,
|
||||
trait_ref: &TraitRef,
|
||||
ty: ty::Ty,
|
||||
hash_is_automatically_derived: bool
|
||||
) {
|
||||
fn check_hash_peq(cx: &LateContext, span: Span, trait_ref: &TraitRef, ty: ty::Ty, hash_is_automatically_derived: bool) {
|
||||
if_let_chain! {[
|
||||
match_path(&trait_ref.path, &HASH_PATH),
|
||||
let Some(peq_trait_def_id) = cx.tcx.lang_items.eq_trait()
|
||||
@ -143,9 +137,7 @@ fn check_hash_peq(
|
||||
}
|
||||
|
||||
/// 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) {
|
||||
let parameter_environment = ty::ParameterEnvironment::for_item(cx.tcx, item.id);
|
||||
let subst_ty = ty.subst(cx.tcx, ¶meter_environment.free_substs);
|
||||
|
@ -48,7 +48,7 @@ fn check_expr(&mut self, cx: &LateContext, expr: &Expr) {
|
||||
// in case of `if !m.contains_key(&k) { m.insert(k, v); }`
|
||||
// we can give a better error message
|
||||
let sole_expr = else_block.is_none() &&
|
||||
if then_block.expr.is_some() { 1 } else { 0 } + then_block.stmts.len() == 1;
|
||||
((then_block.expr.is_some() as usize) + then_block.stmts.len() == 1);
|
||||
|
||||
let mut visitor = InsertVisitor {
|
||||
cx: cx,
|
||||
|
@ -31,17 +31,16 @@ fn var2str(var: &Variant) -> InternedString {
|
||||
var.node.name.name.as_str()
|
||||
}
|
||||
|
||||
/*
|
||||
FIXME: waiting for https://github.com/rust-lang/rust/pull/31700
|
||||
fn partial_match(pre: &str, name: &str) -> usize {
|
||||
// skip(1) to ensure that the prefix never takes the whole variant name
|
||||
pre.chars().zip(name.chars().rev().skip(1).rev()).take_while(|&(l, r)| l == r).count()
|
||||
}
|
||||
|
||||
fn partial_rmatch(post: &str, name: &str) -> usize {
|
||||
// skip(1) to ensure that the postfix never takes the whole variant name
|
||||
post.chars().rev().zip(name.chars().skip(1).rev()).take_while(|&(l, r)| l == r).count()
|
||||
}*/
|
||||
// FIXME: waiting for https://github.com/rust-lang/rust/pull/31700
|
||||
// fn partial_match(pre: &str, name: &str) -> usize {
|
||||
// // skip(1) to ensure that the prefix never takes the whole variant name
|
||||
// pre.chars().zip(name.chars().rev().skip(1).rev()).take_while(|&(l, r)| l == r).count()
|
||||
// }
|
||||
//
|
||||
// fn partial_rmatch(post: &str, name: &str) -> usize {
|
||||
// // skip(1) to ensure that the postfix never takes the whole variant name
|
||||
// post.chars().rev().zip(name.chars().skip(1).rev()).take_while(|&(l, r)| l == r).count()
|
||||
// }
|
||||
|
||||
fn partial_match(pre: &str, name: &str) -> usize {
|
||||
let mut name_iter = name.chars();
|
||||
@ -99,7 +98,8 @@ fn check_item(&mut self, cx: &EarlyContext, item: &Item) {
|
||||
item.span,
|
||||
&format!("All variants have the same {}fix: `{}`", what, value),
|
||||
&format!("remove the {}fixes and use full paths to \
|
||||
the variants instead of glob imports", what));
|
||||
the variants instead of glob imports",
|
||||
what));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -96,9 +96,11 @@ fn check_assign(cx: &EarlyContext, expr: &ast::Expr) {
|
||||
span_note_and_lint(cx,
|
||||
SUSPICIOUS_ASSIGNMENT_FORMATTING,
|
||||
eqop_span,
|
||||
&format!("this looks like you are trying to use `.. {op}= ..`, but you really are doing `.. = ({op} ..)`", op=op),
|
||||
&format!("this looks like you are trying to use `.. {op}= ..`, but you \
|
||||
really are doing `.. = ({op} ..)`",
|
||||
op = op),
|
||||
eqop_span,
|
||||
&format!("to remove this lint, use either `{op}=` or `= {op}`", op=op));
|
||||
&format!("to remove this lint, use either `{op}=` or `= {op}`", op = op));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -109,9 +111,7 @@ fn check_assign(cx: &EarlyContext, expr: &ast::Expr) {
|
||||
/// Implementation of the SUSPICIOUS_ELSE_FORMATTING lint for weird `else if`.
|
||||
fn check_else_if(cx: &EarlyContext, expr: &ast::Expr) {
|
||||
if let Some((then, &Some(ref else_))) = unsugar_if(expr) {
|
||||
if unsugar_if(else_).is_some() &&
|
||||
!differing_macro_contexts(then.span, else_.span) &&
|
||||
!in_macro(cx, then.span) {
|
||||
if unsugar_if(else_).is_some() && !differing_macro_contexts(then.span, else_.span) && !in_macro(cx, then.span) {
|
||||
// this will be a span from the closing ‘}’ of the “then” block (excluding) to the
|
||||
// “if” of the “else if” block (excluding)
|
||||
let else_span = mk_sp(then.span.hi, else_.span.lo);
|
||||
@ -127,7 +127,8 @@ fn check_else_if(cx: &EarlyContext, expr: &ast::Expr) {
|
||||
else_span,
|
||||
"this is an `else if` but the formatting might hide it",
|
||||
else_span,
|
||||
"to remove this lint, remove the `else` or remove the new line between `else` and `if`");
|
||||
"to remove this lint, remove the `else` or remove the new line between `else` \
|
||||
and `if`");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -136,10 +137,8 @@ fn check_else_if(cx: &EarlyContext, expr: &ast::Expr) {
|
||||
|
||||
/// Implementation of the `SUSPICIOUS_ELSE_FORMATTING` lint for consecutive ifs.
|
||||
fn check_consecutive_ifs(cx: &EarlyContext, first: &ast::Expr, second: &ast::Expr) {
|
||||
if !differing_macro_contexts(first.span, second.span) &&
|
||||
!in_macro(cx, first.span) &&
|
||||
unsugar_if(first).is_some() &&
|
||||
unsugar_if(second).is_some() {
|
||||
if !differing_macro_contexts(first.span, second.span) && !in_macro(cx, first.span) &&
|
||||
unsugar_if(first).is_some() && unsugar_if(second).is_some() {
|
||||
// where the else would be
|
||||
let else_span = mk_sp(first.span.hi, second.span.lo);
|
||||
|
||||
@ -150,14 +149,15 @@ fn check_consecutive_ifs(cx: &EarlyContext, first: &ast::Expr, second: &ast::Exp
|
||||
else_span,
|
||||
"this looks like an `else if` but the `else` is missing",
|
||||
else_span,
|
||||
"to remove this lint, add the missing `else` or add a new line before the second `if`");
|
||||
"to remove this lint, add the missing `else` or add a new line before the second \
|
||||
`if`");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Match `if` or `else if` expressions and return the `then` and `else` block.
|
||||
fn unsugar_if(expr: &ast::Expr) -> Option<(&P<ast::Block>, &Option<P<ast::Expr>>)>{
|
||||
fn unsugar_if(expr: &ast::Expr) -> Option<(&P<ast::Block>, &Option<P<ast::Expr>>)> {
|
||||
match expr.node {
|
||||
ast::ExprKind::If(_, ref then, ref else_) |
|
||||
ast::ExprKind::IfLet(_, _, ref then, ref else_) => Some((then, else_)),
|
||||
|
@ -155,17 +155,11 @@ fn check_cmp(cx: &LateContext, span: Span, left: &Expr, right: &Expr, op: &str)
|
||||
fn check_len_zero(cx: &LateContext, span: Span, name: &Name, args: &[P<Expr>], lit: &Lit, op: &str) {
|
||||
if let Spanned{node: LitKind::Int(0, _), ..} = *lit {
|
||||
if name.as_str() == "len" && args.len() == 1 && has_is_empty(cx, &args[0]) {
|
||||
span_lint_and_then(cx,
|
||||
LEN_ZERO,
|
||||
span,
|
||||
"length comparison to zero",
|
||||
|db| {
|
||||
db.span_suggestion(span,
|
||||
"consider using `is_empty`",
|
||||
format!("{}{}.is_empty()",
|
||||
op,
|
||||
snippet(cx, args[0].span, "_")));
|
||||
});
|
||||
span_lint_and_then(cx, LEN_ZERO, span, "length comparison to zero", |db| {
|
||||
db.span_suggestion(span,
|
||||
"consider using `is_empty`",
|
||||
format!("{}{}.is_empty()", op, snippet(cx, args[0].span, "_")));
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
27
src/loops.rs
27
src/loops.rs
@ -370,14 +370,14 @@ fn check_for_loop_range(cx: &LateContext, pat: &Pat, arg: &Expr, body: &Expr, ex
|
||||
span_lint(cx,
|
||||
NEEDLESS_RANGE_LOOP,
|
||||
expr.span,
|
||||
&format!("the loop variable `{}` is used to index `{}`. \
|
||||
Consider using `for ({}, item) in {}.iter().enumerate(){}{}` or similar iterators",
|
||||
ident.node.name,
|
||||
indexed,
|
||||
ident.node.name,
|
||||
indexed,
|
||||
take,
|
||||
skip));
|
||||
&format!("the loop variable `{}` is used to index `{}`. Consider using `for ({}, \
|
||||
item) in {}.iter().enumerate(){}{}` or similar iterators",
|
||||
ident.node.name,
|
||||
indexed,
|
||||
ident.node.name,
|
||||
indexed,
|
||||
take,
|
||||
skip));
|
||||
} else {
|
||||
let repl = if starts_at_zero && take.is_empty() {
|
||||
format!("&{}", indexed)
|
||||
@ -390,9 +390,9 @@ fn check_for_loop_range(cx: &LateContext, pat: &Pat, arg: &Expr, body: &Expr, ex
|
||||
expr.span,
|
||||
&format!("the loop variable `{}` is only used to index `{}`. \
|
||||
Consider using `for item in {}` or similar iterators",
|
||||
ident.node.name,
|
||||
indexed,
|
||||
repl));
|
||||
ident.node.name,
|
||||
indexed,
|
||||
repl));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -447,9 +447,7 @@ fn check_for_loop_reverse_range(cx: &LateContext, arg: &Expr, expr: &Expr) {
|
||||
"consider using the following if \
|
||||
you are attempting to iterate \
|
||||
over this range in reverse",
|
||||
format!("({}..{}).rev()` ",
|
||||
stop_snippet,
|
||||
start_snippet));
|
||||
format!("({}..{}).rev()` ", stop_snippet, start_snippet));
|
||||
});
|
||||
} else if eq {
|
||||
// if they are equal, it's also problematic - this loop
|
||||
@ -744,6 +742,7 @@ fn visit_expr(&mut self, expr: &'v Expr) {
|
||||
|
||||
/// Return true if the type of expr is one that provides IntoIterator impls
|
||||
/// for &T and &mut T, such as Vec.
|
||||
#[cfg_attr(rustfmt, rustfmt_skip)]
|
||||
fn is_ref_iterable_type(cx: &LateContext, e: &Expr) -> bool {
|
||||
// no walk_ptrs_ty: calling iter() on a reference can make sense because it
|
||||
// will allow further borrows afterwards
|
||||
|
@ -1,10 +1,8 @@
|
||||
use rustc::lint::*;
|
||||
use rustc_front::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, snippet, span_help_and_lint, walk_ptrs_ty,
|
||||
walk_ptrs_ty_depth};
|
||||
|
||||
/// **What it does:** This lint checks for mapping clone() over an iterator.
|
||||
///
|
||||
|
@ -134,10 +134,11 @@ fn check_expr(&mut self, cx: &LateContext, expr: &Expr) {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg_attr(rustfmt, rustfmt_skip)]
|
||||
fn check_single_match(cx: &LateContext, ex: &Expr, arms: &[Arm], expr: &Expr) {
|
||||
if arms.len() == 2 &&
|
||||
arms[0].pats.len() == 1 && arms[0].guard.is_none() &&
|
||||
arms[1].pats.len() == 1 && arms[1].guard.is_none() {
|
||||
arms[0].pats.len() == 1 && arms[0].guard.is_none() &&
|
||||
arms[1].pats.len() == 1 && arms[1].guard.is_none() {
|
||||
let els = if is_unit_expr(&arms[1].body) {
|
||||
None
|
||||
} else if let ExprBlock(_) = arms[1].body.node {
|
||||
@ -167,28 +168,28 @@ fn check_single_match_single_pattern(cx: &LateContext, ex: &Expr, arms: &[Arm],
|
||||
lint,
|
||||
expr.span,
|
||||
"you seem to be trying to use match for destructuring a single pattern. \
|
||||
Consider using `if let`", |db| {
|
||||
db.span_suggestion(expr.span, "try this",
|
||||
format!("if let {} = {} {}{}",
|
||||
snippet(cx, arms[0].pats[0].span, ".."),
|
||||
snippet(cx, ex.span, ".."),
|
||||
expr_block(cx, &arms[0].body, None, ".."),
|
||||
els_str));
|
||||
});
|
||||
Consider using `if let`",
|
||||
|db| {
|
||||
db.span_suggestion(expr.span,
|
||||
"try this",
|
||||
format!("if let {} = {} {}{}",
|
||||
snippet(cx, arms[0].pats[0].span, ".."),
|
||||
snippet(cx, ex.span, ".."),
|
||||
expr_block(cx, &arms[0].body, None, ".."),
|
||||
els_str));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
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 = &[(&COW_PATH, "Borrowed"),
|
||||
(&COW_PATH, "Cow::Borrowed"),
|
||||
(&COW_PATH, "Cow::Owned"),
|
||||
(&COW_PATH, "Owned"),
|
||||
(&OPTION_PATH, "None"),
|
||||
(&RESULT_PATH, "Err"),
|
||||
(&RESULT_PATH, "Ok")];
|
||||
|
||||
let path = match arms[1].pats[0].node {
|
||||
PatKind::TupleStruct(ref path, Some(ref inner)) => {
|
||||
|
@ -565,7 +565,9 @@ fn lint_clone_double_ref(cx: &LateContext, expr: &Expr, arg: &Expr) {
|
||||
let ty = cx.tcx.expr_ty(arg);
|
||||
if let ty::TyRef(_, ty::TypeAndMut { ty: ref inner, .. }) = ty.sty {
|
||||
if let ty::TyRef(..) = inner.sty {
|
||||
let mut db = span_lint(cx, CLONE_DOUBLE_REF, expr.span,
|
||||
let mut db = span_lint(cx,
|
||||
CLONE_DOUBLE_REF,
|
||||
expr.span,
|
||||
"using `clone` on a double-reference; \
|
||||
this will copy the reference instead of cloning \
|
||||
the inner type");
|
||||
@ -583,10 +585,7 @@ fn lint_extend(cx: &LateContext, expr: &Expr, args: &MethodArgs) {
|
||||
}
|
||||
let arg_ty = cx.tcx.expr_ty(&args[1]);
|
||||
if let Some((span, r)) = derefs_to_slice(cx, &args[1], &arg_ty) {
|
||||
span_lint(cx,
|
||||
EXTEND_FROM_SLICE,
|
||||
expr.span,
|
||||
"use of `extend` to extend a Vec by a slice")
|
||||
span_lint(cx, EXTEND_FROM_SLICE, expr.span, "use of `extend` to extend a Vec by a slice")
|
||||
.span_suggestion(expr.span,
|
||||
"try this",
|
||||
format!("{}.extend_from_slice({}{})",
|
||||
|
11
src/print.rs
11
src/print.rs
@ -60,9 +60,8 @@ fn check_expr(&mut self, cx: &LateContext, expr: &Expr) {
|
||||
// `::std::fmt::ArgumentV1::new(__arg0, ::std::fmt::Debug::fmt)`
|
||||
else if args.len() == 2 && match_path(path, &FMT_ARGUMENTV1_NEW_PATH) {
|
||||
if let ExprPath(None, ref path) = args[1].node {
|
||||
if match_path(path, &DEBUG_FMT_METHOD_PATH) &&
|
||||
!is_in_debug_impl(cx, expr) &&
|
||||
is_expn_of(cx, expr.span, "panic").is_none() {
|
||||
if match_path(path, &DEBUG_FMT_METHOD_PATH) && !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");
|
||||
}
|
||||
}
|
||||
@ -75,8 +74,10 @@ fn check_expr(&mut self, cx: &LateContext, expr: &Expr) {
|
||||
fn is_in_debug_impl(cx: &LateContext, expr: &Expr) -> bool {
|
||||
let map = &cx.tcx.map;
|
||||
|
||||
if let Some(NodeImplItem(item)) = map.find(map.get_parent(expr.id)) { // `fmt` method
|
||||
if let Some(NodeItem(item)) = map.find(map.get_parent(item.id)) { // `Debug` impl
|
||||
// `fmt` method
|
||||
if let Some(NodeImplItem(item)) = map.find(map.get_parent(expr.id)) {
|
||||
// `Debug` impl
|
||||
if let Some(NodeItem(item)) = map.find(map.get_parent(item.id)) {
|
||||
if let ItemImpl(_, _, _, Some(ref tr), _, _) = item.node {
|
||||
return match_path(&tr.path, &["Debug"]);
|
||||
}
|
||||
|
@ -147,7 +147,11 @@ fn str_span(base: Span, s: &str, c: usize) -> Span {
|
||||
Some((b, _)) => base.lo + BytePos(b as u32),
|
||||
_ => base.hi,
|
||||
};
|
||||
Span{ lo: lo, hi: lo, ..base }
|
||||
Span {
|
||||
lo: lo,
|
||||
hi: lo,
|
||||
..base
|
||||
}
|
||||
}
|
||||
|
||||
fn const_str(cx: &LateContext, e: &Expr) -> Option<InternedString> {
|
||||
|
@ -144,7 +144,7 @@ fn check_expr(&mut self, cx: &LateContext, e: &Expr) {
|
||||
let msg = format!("calling `as_bytes()` on a string literal. \
|
||||
Consider using a byte string literal instead: \
|
||||
`b{}`",
|
||||
snippet(cx, args[0].span, r#""foo""#));
|
||||
snippet(cx, args[0].span, r#""foo""#));
|
||||
span_lint(cx, STRING_LIT_AS_BYTES, e.span, &msg);
|
||||
}
|
||||
}
|
||||
|
10
src/types.rs
10
src/types.rs
@ -390,7 +390,8 @@ fn check_expr(&mut self, cx: &LateContext, expr: &Expr) {
|
||||
check_truncation_and_wrapping(cx, expr, cast_from, cast_to);
|
||||
}
|
||||
(false, false) => {
|
||||
if let (&ty::TyFloat(FloatTy::F64), &ty::TyFloat(FloatTy::F32)) = (&cast_from.sty, &cast_to.sty) {
|
||||
if let (&ty::TyFloat(FloatTy::F64), &ty::TyFloat(FloatTy::F32)) = (&cast_from.sty,
|
||||
&cast_to.sty) {
|
||||
span_lint(cx,
|
||||
CAST_POSSIBLE_TRUNCATION,
|
||||
expr.span,
|
||||
@ -570,7 +571,7 @@ fn check_expr(&mut self, cx: &LateContext, expr: &Expr) {
|
||||
truncates them";
|
||||
let help = format!("Consider using a byte literal \
|
||||
instead:\nb{}",
|
||||
snippet(cx, e.span, "'x'"));
|
||||
snippet(cx, e.span, "'x'"));
|
||||
span_help_and_lint(cx, CHAR_LIT_AS_U8, expr.span, msg, &help);
|
||||
}
|
||||
}
|
||||
@ -623,7 +624,10 @@ fn detect_absurd_comparison<'a>(cx: &LateContext, op: BinOp_, lhs: &'a Expr, rhs
|
||||
type Extr<'a> = ExtremeExpr<'a>;
|
||||
|
||||
// Put the expression in the form lhs < rhs or lhs <= rhs.
|
||||
enum Rel { Lt, Le };
|
||||
enum Rel {
|
||||
Lt,
|
||||
Le,
|
||||
};
|
||||
let (rel, lhs2, rhs2) = match op {
|
||||
BiLt => (Rel::Lt, lhs, rhs),
|
||||
BiLe => (Rel::Le, lhs, rhs),
|
||||
|
123
src/utils/hir.rs
123
src/utils/hir.rs
@ -38,10 +38,8 @@ pub fn eq_stmt(&self, left: &Stmt, right: &Stmt) -> bool {
|
||||
(&StmtDecl(ref l, _), &StmtDecl(ref r, _)) => {
|
||||
if let (&DeclLocal(ref l), &DeclLocal(ref r)) = (&l.node, &r.node) {
|
||||
// TODO: tys
|
||||
l.ty.is_none() && r.ty.is_none() &&
|
||||
both(&l.init, &r.init, |l, r| self.eq_expr(l, r))
|
||||
}
|
||||
else {
|
||||
l.ty.is_none() && r.ty.is_none() && both(&l.init, &r.init, |l, r| self.eq_expr(l, r))
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
@ -71,15 +69,9 @@ pub fn eq_expr(&self, left: &Expr, right: &Expr) -> bool {
|
||||
}
|
||||
|
||||
match (&left.node, &right.node) {
|
||||
(&ExprAddrOf(lmut, ref le), &ExprAddrOf(rmut, ref re)) => {
|
||||
lmut == rmut && self.eq_expr(le, re)
|
||||
}
|
||||
(&ExprAgain(li), &ExprAgain(ri)) => {
|
||||
both(&li, &ri, |l, r| l.node.name.as_str() == r.node.name.as_str())
|
||||
}
|
||||
(&ExprAssign(ref ll, ref lr), &ExprAssign(ref rl, ref rr)) => {
|
||||
self.eq_expr(ll, rl) && self.eq_expr(lr, rr)
|
||||
}
|
||||
(&ExprAddrOf(lmut, ref le), &ExprAddrOf(rmut, ref re)) => lmut == rmut && self.eq_expr(le, re),
|
||||
(&ExprAgain(li), &ExprAgain(ri)) => both(&li, &ri, |l, r| l.node.name.as_str() == r.node.name.as_str()),
|
||||
(&ExprAssign(ref ll, ref lr), &ExprAssign(ref rl, ref rr)) => self.eq_expr(ll, rl) && self.eq_expr(lr, rr),
|
||||
(&ExprAssignOp(ref lo, ref ll, ref lr), &ExprAssignOp(ref ro, ref rl, ref rr)) => {
|
||||
lo.node == ro.node && self.eq_expr(ll, rl) && self.eq_expr(lr, rr)
|
||||
}
|
||||
@ -87,79 +79,50 @@ pub fn eq_expr(&self, left: &Expr, right: &Expr) -> bool {
|
||||
(&ExprBinary(lop, ref ll, ref lr), &ExprBinary(rop, ref rl, ref rr)) => {
|
||||
lop.node == rop.node && self.eq_expr(ll, rl) && self.eq_expr(lr, rr)
|
||||
}
|
||||
(&ExprBreak(li), &ExprBreak(ri)) => {
|
||||
both(&li, &ri, |l, r| l.node.name.as_str() == r.node.name.as_str())
|
||||
}
|
||||
(&ExprBox(ref l), &ExprBox(ref r)) => {
|
||||
self.eq_expr(l, r)
|
||||
}
|
||||
(&ExprBreak(li), &ExprBreak(ri)) => both(&li, &ri, |l, r| l.node.name.as_str() == r.node.name.as_str()),
|
||||
(&ExprBox(ref l), &ExprBox(ref r)) => self.eq_expr(l, r),
|
||||
(&ExprCall(ref lfun, ref largs), &ExprCall(ref rfun, ref rargs)) => {
|
||||
!self.ignore_fn &&
|
||||
self.eq_expr(lfun, rfun) &&
|
||||
self.eq_exprs(largs, rargs)
|
||||
}
|
||||
(&ExprCast(ref lx, ref lt), &ExprCast(ref rx, ref rt)) => {
|
||||
self.eq_expr(lx, rx) && self.eq_ty(lt, rt)
|
||||
!self.ignore_fn && self.eq_expr(lfun, rfun) && self.eq_exprs(largs, rargs)
|
||||
}
|
||||
(&ExprCast(ref lx, ref lt), &ExprCast(ref rx, ref rt)) => self.eq_expr(lx, rx) && self.eq_ty(lt, rt),
|
||||
(&ExprField(ref lfexp, ref lfident), &ExprField(ref rfexp, ref rfident)) => {
|
||||
lfident.node == rfident.node && self.eq_expr(lfexp, rfexp)
|
||||
}
|
||||
(&ExprIndex(ref la, ref li), &ExprIndex(ref ra, ref ri)) => {
|
||||
self.eq_expr(la, ra) && self.eq_expr(li, ri)
|
||||
}
|
||||
(&ExprIndex(ref la, ref li), &ExprIndex(ref ra, ref ri)) => self.eq_expr(la, ra) && self.eq_expr(li, ri),
|
||||
(&ExprIf(ref lc, ref lt, ref le), &ExprIf(ref rc, ref rt, ref re)) => {
|
||||
self.eq_expr(lc, rc) &&
|
||||
self.eq_block(lt, rt) &&
|
||||
both(le, re, |l, r| self.eq_expr(l, r))
|
||||
self.eq_expr(lc, rc) && self.eq_block(lt, rt) && both(le, re, |l, r| self.eq_expr(l, r))
|
||||
}
|
||||
(&ExprLit(ref l), &ExprLit(ref r)) => l.node == r.node,
|
||||
(&ExprLoop(ref lb, ref ll), &ExprLoop(ref rb, ref rl)) => {
|
||||
self.eq_block(lb, rb) &&
|
||||
both(ll, rl, |l, r| l.name.as_str() == r.name.as_str())
|
||||
|
||||
self.eq_block(lb, rb) && both(ll, rl, |l, r| l.name.as_str() == r.name.as_str())
|
||||
}
|
||||
(&ExprMatch(ref le, ref la, ref ls), &ExprMatch(ref re, ref ra, ref rs)) => {
|
||||
ls == rs &&
|
||||
self.eq_expr(le, re) &&
|
||||
over(la, ra, |l, r| {
|
||||
self.eq_expr(&l.body, &r.body) &&
|
||||
both(&l.guard, &r.guard, |l, r| self.eq_expr(l, r)) &&
|
||||
over(&l.pats, &r.pats, |l, r| self.eq_pat(l, r))
|
||||
})
|
||||
ls == rs && self.eq_expr(le, re) &&
|
||||
over(la, ra, |l, r| {
|
||||
self.eq_expr(&l.body, &r.body) && both(&l.guard, &r.guard, |l, r| self.eq_expr(l, r)) &&
|
||||
over(&l.pats, &r.pats, |l, r| self.eq_pat(l, r))
|
||||
})
|
||||
}
|
||||
(&ExprMethodCall(ref lname, ref ltys, ref largs), &ExprMethodCall(ref rname, ref rtys, ref rargs)) => {
|
||||
(&ExprMethodCall(ref lname, ref ltys, ref largs),
|
||||
&ExprMethodCall(ref rname, ref rtys, ref rargs)) => {
|
||||
// TODO: tys
|
||||
!self.ignore_fn &&
|
||||
lname.node == rname.node &&
|
||||
ltys.is_empty() &&
|
||||
rtys.is_empty() &&
|
||||
self.eq_exprs(largs, rargs)
|
||||
!self.ignore_fn && lname.node == rname.node && ltys.is_empty() && rtys.is_empty() &&
|
||||
self.eq_exprs(largs, rargs)
|
||||
}
|
||||
(&ExprRange(ref lb, ref le), &ExprRange(ref rb, ref re)) => {
|
||||
both(lb, rb, |l, r| self.eq_expr(l, r)) &&
|
||||
both(le, re, |l, r| self.eq_expr(l, r))
|
||||
}
|
||||
(&ExprRepeat(ref le, ref ll), &ExprRepeat(ref re, ref rl)) => {
|
||||
self.eq_expr(le, re) && self.eq_expr(ll, rl)
|
||||
}
|
||||
(&ExprRet(ref l), &ExprRet(ref r)) => {
|
||||
both(l, r, |l, r| self.eq_expr(l, r))
|
||||
both(lb, rb, |l, r| self.eq_expr(l, r)) && both(le, re, |l, r| self.eq_expr(l, r))
|
||||
}
|
||||
(&ExprRepeat(ref le, ref ll), &ExprRepeat(ref re, ref rl)) => self.eq_expr(le, re) && self.eq_expr(ll, rl),
|
||||
(&ExprRet(ref l), &ExprRet(ref r)) => both(l, r, |l, r| self.eq_expr(l, r)),
|
||||
(&ExprPath(ref lqself, ref lsubpath), &ExprPath(ref rqself, ref rsubpath)) => {
|
||||
both(lqself, rqself, |l, r| self.eq_qself(l, r)) && self.eq_path(lsubpath, rsubpath)
|
||||
}
|
||||
(&ExprTup(ref ltup), &ExprTup(ref rtup)) => self.eq_exprs(ltup, rtup),
|
||||
(&ExprTupField(ref le, li), &ExprTupField(ref re, ri)) => {
|
||||
li.node == ri.node && self.eq_expr(le, re)
|
||||
}
|
||||
(&ExprUnary(lop, ref le), &ExprUnary(rop, ref re)) => {
|
||||
lop == rop && self.eq_expr(le, re)
|
||||
}
|
||||
(&ExprTupField(ref le, li), &ExprTupField(ref re, ri)) => li.node == ri.node && self.eq_expr(le, re),
|
||||
(&ExprUnary(lop, ref le), &ExprUnary(rop, ref re)) => lop == rop && self.eq_expr(le, re),
|
||||
(&ExprVec(ref l), &ExprVec(ref r)) => self.eq_exprs(l, r),
|
||||
(&ExprWhile(ref lc, ref lb, ref ll), &ExprWhile(ref rc, ref rb, ref rl)) => {
|
||||
self.eq_expr(lc, rc) &&
|
||||
self.eq_block(lb, rb) &&
|
||||
both(ll, rl, |l, r| l.name.as_str() == r.name.as_str())
|
||||
self.eq_expr(lc, rc) && self.eq_block(lb, rb) && both(ll, rl, |l, r| l.name.as_str() == r.name.as_str())
|
||||
}
|
||||
_ => false,
|
||||
}
|
||||
@ -172,39 +135,25 @@ fn eq_exprs(&self, left: &[P<Expr>], right: &[P<Expr>]) -> bool {
|
||||
/// Check whether two patterns are the same.
|
||||
pub fn eq_pat(&self, left: &Pat, right: &Pat) -> bool {
|
||||
match (&left.node, &right.node) {
|
||||
(&PatKind::Box(ref l), &PatKind::Box(ref r)) => {
|
||||
self.eq_pat(l, r)
|
||||
}
|
||||
(&PatKind::Box(ref l), &PatKind::Box(ref r)) => self.eq_pat(l, r),
|
||||
(&PatKind::TupleStruct(ref lp, ref la), &PatKind::TupleStruct(ref rp, ref ra)) => {
|
||||
self.eq_path(lp, rp) &&
|
||||
both(la, ra, |l, r| {
|
||||
over(l, r, |l, r| self.eq_pat(l, r))
|
||||
})
|
||||
self.eq_path(lp, rp) && both(la, ra, |l, r| over(l, r, |l, r| self.eq_pat(l, r)))
|
||||
}
|
||||
(&PatKind::Ident(ref lb, ref li, ref lp), &PatKind::Ident(ref rb, ref ri, ref rp)) => {
|
||||
lb == rb && li.node.name.as_str() == ri.node.name.as_str() &&
|
||||
both(lp, rp, |l, r| self.eq_pat(l, r))
|
||||
}
|
||||
(&PatKind::Lit(ref l), &PatKind::Lit(ref r)) => {
|
||||
self.eq_expr(l, r)
|
||||
lb == rb && li.node.name.as_str() == ri.node.name.as_str() && both(lp, rp, |l, r| self.eq_pat(l, r))
|
||||
}
|
||||
(&PatKind::Lit(ref l), &PatKind::Lit(ref r)) => self.eq_expr(l, r),
|
||||
(&PatKind::QPath(ref ls, ref lp), &PatKind::QPath(ref rs, ref rp)) => {
|
||||
self.eq_qself(ls, rs) && self.eq_path(lp, rp)
|
||||
}
|
||||
(&PatKind::Tup(ref l), &PatKind::Tup(ref r)) => {
|
||||
over(l, r, |l, r| self.eq_pat(l, r))
|
||||
}
|
||||
(&PatKind::Tup(ref l), &PatKind::Tup(ref r)) => over(l, r, |l, r| self.eq_pat(l, r)),
|
||||
(&PatKind::Range(ref ls, ref le), &PatKind::Range(ref rs, ref re)) => {
|
||||
self.eq_expr(ls, rs) &&
|
||||
self.eq_expr(le, re)
|
||||
}
|
||||
(&PatKind::Ref(ref le, ref lm), &PatKind::Ref(ref re, ref rm)) => {
|
||||
lm == rm && self.eq_pat(le, re)
|
||||
self.eq_expr(ls, rs) && self.eq_expr(le, re)
|
||||
}
|
||||
(&PatKind::Ref(ref le, ref lm), &PatKind::Ref(ref re, ref rm)) => lm == rm && self.eq_pat(le, re),
|
||||
(&PatKind::Vec(ref ls, ref li, ref le), &PatKind::Vec(ref rs, ref ri, ref re)) => {
|
||||
over(ls, rs, |l, r| self.eq_pat(l, r)) &&
|
||||
over(le, re, |l, r| self.eq_pat(l, r)) &&
|
||||
both(li, ri, |l, r| self.eq_pat(l, r))
|
||||
over(ls, rs, |l, r| self.eq_pat(l, r)) && over(le, re, |l, r| self.eq_pat(l, r)) &&
|
||||
both(li, ri, |l, r| self.eq_pat(l, r))
|
||||
}
|
||||
(&PatKind::Wild, &PatKind::Wild) => true,
|
||||
_ => false,
|
||||
|
@ -137,8 +137,7 @@ pub fn match_def_path(cx: &LateContext, def_id: DefId, path: &[&str]) -> bool {
|
||||
|
||||
iter.inspect(|_| len += 1)
|
||||
.zip(path)
|
||||
.all(|(nm, p)| nm.name().as_str() == *p)
|
||||
&& len == path.len()
|
||||
.all(|(nm, p)| nm.name().as_str() == *p) && len == path.len()
|
||||
})
|
||||
}
|
||||
|
||||
@ -600,11 +599,10 @@ fn parse_attrs<F: FnMut(u64)>(sess: &Session, attrs: &[ast::Attribute], name: &'
|
||||
/// Return the pre-expansion span if is this comes from an expansion of the macro `name`.
|
||||
pub fn is_expn_of(cx: &LateContext, mut span: Span, name: &str) -> Option<Span> {
|
||||
loop {
|
||||
let span_name_span = cx.tcx.sess.codemap().with_expn_info(span.expn_id, |expn| {
|
||||
expn.map(|ei| {
|
||||
(ei.callee.name(), ei.call_site)
|
||||
})
|
||||
});
|
||||
let span_name_span = cx.tcx
|
||||
.sess
|
||||
.codemap()
|
||||
.with_expn_info(span.expn_id, |expn| expn.map(|ei| (ei.callee.name(), ei.call_site)));
|
||||
|
||||
match span_name_span {
|
||||
Some((mac_name, new_span)) if mac_name.as_str() == name => return Some(new_span),
|
||||
|
Loading…
Reference in New Issue
Block a user