Skip to content

Commit f9682ca

Browse files
authored
Merge pull request #2154 from durka/ifchain
replace if_let_chain with if_chain
2 parents 2771378 + 24a2c14 commit f9682ca

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+1929
-1883
lines changed

clippy_lints/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ toml = "0.4"
2828
unicode-normalization = "0.1"
2929
pulldown-cmark = "0.0.15"
3030
url = "1.5.0"
31+
if_chain = "0.1"
3132

3233
[features]
3334
debugging = []

clippy_lints/src/assign_ops.rs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -140,12 +140,13 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for AssignOps {
140140
let parent_fn = cx.tcx.hir.get_parent(e.id);
141141
let parent_impl = cx.tcx.hir.get_parent(parent_fn);
142142
// the crate node is the only one that is not in the map
143-
if_let_chain!{[
144-
parent_impl != ast::CRATE_NODE_ID,
145-
let hir::map::Node::NodeItem(item) = cx.tcx.hir.get(parent_impl),
146-
let hir::Item_::ItemImpl(_, _, _, _, Some(ref trait_ref), _, _) = item.node,
147-
trait_ref.path.def.def_id() == trait_id
148-
], { return; }}
143+
if_chain! {
144+
if parent_impl != ast::CRATE_NODE_ID;
145+
if let hir::map::Node::NodeItem(item) = cx.tcx.hir.get(parent_impl);
146+
if let hir::Item_::ItemImpl(_, _, _, _, Some(ref trait_ref), _, _) = item.node;
147+
if trait_ref.path.def.def_id() == trait_id;
148+
then { return; }
149+
}
149150
implements_trait($cx, $ty, trait_id, &[$rty])
150151
},)*
151152
_ => false,

clippy_lints/src/attrs.rs

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -94,13 +94,14 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for AttrPass {
9494
return;
9595
}
9696
for item in items {
97-
if_let_chain! {[
98-
let NestedMetaItemKind::MetaItem(ref mi) = item.node,
99-
let MetaItemKind::NameValue(ref lit) = mi.node,
100-
mi.name() == "since",
101-
], {
102-
check_semver(cx, item.span, lit);
103-
}}
97+
if_chain! {
98+
if let NestedMetaItemKind::MetaItem(ref mi) = item.node;
99+
if let MetaItemKind::NameValue(ref lit) = mi.node;
100+
if mi.name() == "since";
101+
then {
102+
check_semver(cx, item.span, lit);
103+
}
104+
}
104105
}
105106
}
106107
}

clippy_lints/src/bit_mask.rs

Lines changed: 22 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -119,27 +119,28 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for BitMask {
119119
}
120120
}
121121
}
122-
if_let_chain!{[
123-
let Expr_::ExprBinary(ref op, ref left, ref right) = e.node,
124-
BinOp_::BiEq == op.node,
125-
let Expr_::ExprBinary(ref op1, ref left1, ref right1) = left.node,
126-
BinOp_::BiBitAnd == op1.node,
127-
let Expr_::ExprLit(ref lit) = right1.node,
128-
let LitKind::Int(n, _) = lit.node,
129-
let Expr_::ExprLit(ref lit1) = right.node,
130-
let LitKind::Int(0, _) = lit1.node,
131-
n.leading_zeros() == n.count_zeros(),
132-
n > u128::from(self.verbose_bit_mask_threshold),
133-
], {
134-
span_lint_and_then(cx,
135-
VERBOSE_BIT_MASK,
136-
e.span,
137-
"bit mask could be simplified with a call to `trailing_zeros`",
138-
|db| {
139-
let sugg = Sugg::hir(cx, left1, "...").maybe_par();
140-
db.span_suggestion(e.span, "try", format!("{}.trailing_zeros() >= {}", sugg, n.count_ones()));
141-
});
142-
}}
122+
if_chain! {
123+
if let Expr_::ExprBinary(ref op, ref left, ref right) = e.node;
124+
if BinOp_::BiEq == op.node;
125+
if let Expr_::ExprBinary(ref op1, ref left1, ref right1) = left.node;
126+
if BinOp_::BiBitAnd == op1.node;
127+
if let Expr_::ExprLit(ref lit) = right1.node;
128+
if let LitKind::Int(n, _) = lit.node;
129+
if let Expr_::ExprLit(ref lit1) = right.node;
130+
if let LitKind::Int(0, _) = lit1.node;
131+
if n.leading_zeros() == n.count_zeros();
132+
if n > u128::from(self.verbose_bit_mask_threshold);
133+
then {
134+
span_lint_and_then(cx,
135+
VERBOSE_BIT_MASK,
136+
e.span,
137+
"bit mask could be simplified with a call to `trailing_zeros`",
138+
|db| {
139+
let sugg = Sugg::hir(cx, left1, "...").maybe_par();
140+
db.span_suggestion(e.span, "try", format!("{}.trailing_zeros() >= {}", sugg, n.count_ones()));
141+
});
142+
}
143+
}
143144
}
144145
}
145146

clippy_lints/src/bytecount.rs

Lines changed: 50 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -37,56 +37,58 @@ impl LintPass for ByteCount {
3737

3838
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ByteCount {
3939
fn check_expr(&mut self, cx: &LateContext, expr: &Expr) {
40-
if_let_chain!([
41-
let ExprMethodCall(ref count, _, ref count_args) = expr.node,
42-
count.name == "count",
43-
count_args.len() == 1,
44-
let ExprMethodCall(ref filter, _, ref filter_args) = count_args[0].node,
45-
filter.name == "filter",
46-
filter_args.len() == 2,
47-
let ExprClosure(_, _, body_id, _, _) = filter_args[1].node,
48-
], {
49-
let body = cx.tcx.hir.body(body_id);
50-
if_let_chain!([
51-
body.arguments.len() == 1,
52-
let Some(argname) = get_pat_name(&body.arguments[0].pat),
53-
let ExprBinary(ref op, ref l, ref r) = body.value.node,
54-
op.node == BiEq,
55-
match_type(cx,
56-
walk_ptrs_ty(cx.tables.expr_ty(&filter_args[0])),
57-
&paths::SLICE_ITER),
58-
], {
59-
let needle = match get_path_name(l) {
60-
Some(name) if check_arg(name, argname, r) => r,
61-
_ => match get_path_name(r) {
62-
Some(name) if check_arg(name, argname, l) => l,
63-
_ => { return; }
40+
if_chain! {
41+
if let ExprMethodCall(ref count, _, ref count_args) = expr.node;
42+
if count.name == "count";
43+
if count_args.len() == 1;
44+
if let ExprMethodCall(ref filter, _, ref filter_args) = count_args[0].node;
45+
if filter.name == "filter";
46+
if filter_args.len() == 2;
47+
if let ExprClosure(_, _, body_id, _, _) = filter_args[1].node;
48+
then {
49+
let body = cx.tcx.hir.body(body_id);
50+
if_chain! {
51+
if body.arguments.len() == 1;
52+
if let Some(argname) = get_pat_name(&body.arguments[0].pat);
53+
if let ExprBinary(ref op, ref l, ref r) = body.value.node;
54+
if op.node == BiEq;
55+
if match_type(cx,
56+
walk_ptrs_ty(cx.tables.expr_ty(&filter_args[0])),
57+
&paths::SLICE_ITER);
58+
then {
59+
let needle = match get_path_name(l) {
60+
Some(name) if check_arg(name, argname, r) => r,
61+
_ => match get_path_name(r) {
62+
Some(name) if check_arg(name, argname, l) => l,
63+
_ => { return; }
64+
}
65+
};
66+
if ty::TyUint(UintTy::U8) != walk_ptrs_ty(cx.tables.expr_ty(needle)).sty {
67+
return;
68+
}
69+
let haystack = if let ExprMethodCall(ref path, _, ref args) =
70+
filter_args[0].node {
71+
let p = path.name;
72+
if (p == "iter" || p == "iter_mut") && args.len() == 1 {
73+
&args[0]
74+
} else {
75+
&filter_args[0]
76+
}
77+
} else {
78+
&filter_args[0]
79+
};
80+
span_lint_and_sugg(cx,
81+
NAIVE_BYTECOUNT,
82+
expr.span,
83+
"You appear to be counting bytes the naive way",
84+
"Consider using the bytecount crate",
85+
format!("bytecount::count({}, {})",
86+
snippet(cx, haystack.span, ".."),
87+
snippet(cx, needle.span, "..")));
6488
}
6589
};
66-
if ty::TyUint(UintTy::U8) != walk_ptrs_ty(cx.tables.expr_ty(needle)).sty {
67-
return;
68-
}
69-
let haystack = if let ExprMethodCall(ref path, _, ref args) =
70-
filter_args[0].node {
71-
let p = path.name;
72-
if (p == "iter" || p == "iter_mut") && args.len() == 1 {
73-
&args[0]
74-
} else {
75-
&filter_args[0]
76-
}
77-
} else {
78-
&filter_args[0]
79-
};
80-
span_lint_and_sugg(cx,
81-
NAIVE_BYTECOUNT,
82-
expr.span,
83-
"You appear to be counting bytes the naive way",
84-
"Consider using the bytecount crate",
85-
format!("bytecount::count({}, {})",
86-
snippet(cx, haystack.span, ".."),
87-
snippet(cx, needle.span, "..")));
88-
});
89-
});
90+
}
91+
};
9092
}
9193
}
9294

clippy_lints/src/collapsible_if.rs

Lines changed: 33 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -100,43 +100,45 @@ fn check_if(cx: &EarlyContext, expr: &ast::Expr) {
100100
}
101101

102102
fn check_collapsible_maybe_if_let(cx: &EarlyContext, else_: &ast::Expr) {
103-
if_let_chain! {[
104-
let ast::ExprKind::Block(ref block) = else_.node,
105-
let Some(else_) = expr_block(block),
106-
!in_macro(else_.span),
107-
], {
108-
match else_.node {
109-
ast::ExprKind::If(..) | ast::ExprKind::IfLet(..) => {
110-
span_lint_and_sugg(cx,
111-
COLLAPSIBLE_IF,
112-
block.span,
113-
"this `else { if .. }` block can be collapsed",
114-
"try",
115-
snippet_block(cx, else_.span, "..").into_owned());
103+
if_chain! {
104+
if let ast::ExprKind::Block(ref block) = else_.node;
105+
if let Some(else_) = expr_block(block);
106+
if !in_macro(else_.span);
107+
then {
108+
match else_.node {
109+
ast::ExprKind::If(..) | ast::ExprKind::IfLet(..) => {
110+
span_lint_and_sugg(cx,
111+
COLLAPSIBLE_IF,
112+
block.span,
113+
"this `else { if .. }` block can be collapsed",
114+
"try",
115+
snippet_block(cx, else_.span, "..").into_owned());
116+
}
117+
_ => (),
116118
}
117-
_ => (),
118119
}
119-
}}
120+
}
120121
}
121122

122123
fn check_collapsible_no_if_let(cx: &EarlyContext, expr: &ast::Expr, check: &ast::Expr, then: &ast::Block) {
123-
if_let_chain! {[
124-
let Some(inner) = expr_block(then),
125-
let ast::ExprKind::If(ref check_inner, ref content, None) = inner.node,
126-
], {
127-
if expr.span.ctxt() != inner.span.ctxt() {
128-
return;
124+
if_chain! {
125+
if let Some(inner) = expr_block(then);
126+
if let ast::ExprKind::If(ref check_inner, ref content, None) = inner.node;
127+
then {
128+
if expr.span.ctxt() != inner.span.ctxt() {
129+
return;
130+
}
131+
span_lint_and_then(cx, COLLAPSIBLE_IF, expr.span, "this if statement can be collapsed", |db| {
132+
let lhs = Sugg::ast(cx, check, "..");
133+
let rhs = Sugg::ast(cx, check_inner, "..");
134+
db.span_suggestion(expr.span,
135+
"try",
136+
format!("if {} {}",
137+
lhs.and(rhs),
138+
snippet_block(cx, content.span, "..")));
139+
});
129140
}
130-
span_lint_and_then(cx, COLLAPSIBLE_IF, expr.span, "this if statement can be collapsed", |db| {
131-
let lhs = Sugg::ast(cx, check, "..");
132-
let rhs = Sugg::ast(cx, check_inner, "..");
133-
db.span_suggestion(expr.span,
134-
"try",
135-
format!("if {} {}",
136-
lhs.and(rhs),
137-
snippet_block(cx, content.span, "..")));
138-
});
139-
}}
141+
}
140142
}
141143

142144
/// If the block contains only one expression, return it.

clippy_lints/src/derive.rs

Lines changed: 38 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -91,43 +91,44 @@ fn check_hash_peq<'a, 'tcx>(
9191
ty: Ty<'tcx>,
9292
hash_is_automatically_derived: bool,
9393
) {
94-
if_let_chain! {[
95-
match_path(&trait_ref.path, &paths::HASH),
96-
let Some(peq_trait_def_id) = cx.tcx.lang_items().eq_trait()
97-
], {
98-
// Look for the PartialEq implementations for `ty`
99-
cx.tcx.for_each_relevant_impl(peq_trait_def_id, ty, |impl_id| {
100-
let peq_is_automatically_derived = is_automatically_derived(&cx.tcx.get_attrs(impl_id));
101-
102-
if peq_is_automatically_derived == hash_is_automatically_derived {
103-
return;
104-
}
105-
106-
let trait_ref = cx.tcx.impl_trait_ref(impl_id).expect("must be a trait implementation");
107-
108-
// Only care about `impl PartialEq<Foo> for Foo`
109-
// For `impl PartialEq<B> for A, input_types is [A, B]
110-
if trait_ref.substs.type_at(1) == ty {
111-
let mess = if peq_is_automatically_derived {
112-
"you are implementing `Hash` explicitly but have derived `PartialEq`"
113-
} else {
114-
"you are deriving `Hash` but have implemented `PartialEq` explicitly"
115-
};
116-
117-
span_lint_and_then(
118-
cx, DERIVE_HASH_XOR_EQ, span,
119-
mess,
120-
|db| {
121-
if let Some(node_id) = cx.tcx.hir.as_local_node_id(impl_id) {
122-
db.span_note(
123-
cx.tcx.hir.span(node_id),
124-
"`PartialEq` implemented here"
125-
);
126-
}
127-
});
128-
}
129-
});
130-
}}
94+
if_chain! {
95+
if match_path(&trait_ref.path, &paths::HASH);
96+
if let Some(peq_trait_def_id) = cx.tcx.lang_items().eq_trait();
97+
then {
98+
// Look for the PartialEq implementations for `ty`
99+
cx.tcx.for_each_relevant_impl(peq_trait_def_id, ty, |impl_id| {
100+
let peq_is_automatically_derived = is_automatically_derived(&cx.tcx.get_attrs(impl_id));
101+
102+
if peq_is_automatically_derived == hash_is_automatically_derived {
103+
return;
104+
}
105+
106+
let trait_ref = cx.tcx.impl_trait_ref(impl_id).expect("must be a trait implementation");
107+
108+
// Only care about `impl PartialEq<Foo> for Foo`
109+
// For `impl PartialEq<B> for A, input_types is [A, B]
110+
if trait_ref.substs.type_at(1) == ty {
111+
let mess = if peq_is_automatically_derived {
112+
"you are implementing `Hash` explicitly but have derived `PartialEq`"
113+
} else {
114+
"you are deriving `Hash` but have implemented `PartialEq` explicitly"
115+
};
116+
117+
span_lint_and_then(
118+
cx, DERIVE_HASH_XOR_EQ, span,
119+
mess,
120+
|db| {
121+
if let Some(node_id) = cx.tcx.hir.as_local_node_id(impl_id) {
122+
db.span_note(
123+
cx.tcx.hir.span(node_id),
124+
"`PartialEq` implemented here"
125+
);
126+
}
127+
});
128+
}
129+
});
130+
}
131+
}
131132
}
132133

133134
/// Implementation of the `EXPL_IMPL_CLONE_ON_COPY` lint.

0 commit comments

Comments
 (0)