Skip to content

Commit a0f8ed6

Browse files
committed
Use utils::sugg in match related lints
Also don't build suggestion when unnecessary.
1 parent facad76 commit a0f8ed6

File tree

3 files changed

+67
-64
lines changed

3 files changed

+67
-64
lines changed

clippy_lints/src/matches.rs

Lines changed: 56 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -235,57 +235,54 @@ fn check_single_match_opt_like(cx: &LateContext, ex: &Expr, arms: &[Arm], expr:
235235
fn check_match_bool(cx: &LateContext, ex: &Expr, arms: &[Arm], expr: &Expr) {
236236
// type of expression == bool
237237
if cx.tcx.expr_ty(ex).sty == ty::TyBool {
238-
let sugg = if arms.len() == 2 && arms[0].pats.len() == 1 {
239-
// no guards
240-
let exprs = if let PatKind::Lit(ref arm_bool) = arms[0].pats[0].node {
241-
if let ExprLit(ref lit) = arm_bool.node {
242-
match lit.node {
243-
LitKind::Bool(true) => Some((&*arms[0].body, &*arms[1].body)),
244-
LitKind::Bool(false) => Some((&*arms[1].body, &*arms[0].body)),
245-
_ => None,
238+
span_lint_and_then(cx,
239+
MATCH_BOOL,
240+
expr.span,
241+
"you seem to be trying to match on a boolean expression",
242+
move |db| {
243+
if arms.len() == 2 && arms[0].pats.len() == 1 {
244+
// no guards
245+
let exprs = if let PatKind::Lit(ref arm_bool) = arms[0].pats[0].node {
246+
if let ExprLit(ref lit) = arm_bool.node {
247+
match lit.node {
248+
LitKind::Bool(true) => Some((&*arms[0].body, &*arms[1].body)),
249+
LitKind::Bool(false) => Some((&*arms[1].body, &*arms[0].body)),
250+
_ => None,
251+
}
252+
} else {
253+
None
246254
}
247255
} else {
248256
None
249-
}
250-
} else {
251-
None
252-
};
253-
254-
if let Some((ref true_expr, ref false_expr)) = exprs {
255-
match (is_unit_expr(true_expr), is_unit_expr(false_expr)) {
256-
(false, false) => {
257-
Some(format!("if {} {} else {}",
258-
snippet(cx, ex.span, "b"),
259-
expr_block(cx, true_expr, None, ".."),
260-
expr_block(cx, false_expr, None, "..")))
257+
};
258+
259+
if let Some((ref true_expr, ref false_expr)) = exprs {
260+
let sugg = match (is_unit_expr(true_expr), is_unit_expr(false_expr)) {
261+
(false, false) => {
262+
Some(format!("if {} {} else {}",
263+
snippet(cx, ex.span, "b"),
264+
expr_block(cx, true_expr, None, ".."),
265+
expr_block(cx, false_expr, None, "..")))
266+
}
267+
(false, true) => {
268+
Some(format!("if {} {}", snippet(cx, ex.span, "b"), expr_block(cx, true_expr, None, "..")))
269+
}
270+
(true, false) => {
271+
let test = Sugg::hir(cx, ex, "..");
272+
Some(format!("if {} {}",
273+
!test,
274+
expr_block(cx, false_expr, None, "..")))
275+
}
276+
(true, true) => None,
277+
};
278+
279+
if let Some(sugg) = sugg {
280+
db.span_suggestion(expr.span, "consider using an if/else expression", sugg);
261281
}
262-
(false, true) => {
263-
Some(format!("if {} {}", snippet(cx, ex.span, "b"), expr_block(cx, true_expr, None, "..")))
264-
}
265-
(true, false) => {
266-
let test = Sugg::hir(cx, ex, "..");
267-
Some(format!("if {} {}",
268-
!test,
269-
expr_block(cx, false_expr, None, "..")))
270-
}
271-
(true, true) => None,
272282
}
273-
} else {
274-
None
275283
}
276-
} else {
277-
None
278-
};
279284

280-
span_lint_and_then(cx,
281-
MATCH_BOOL,
282-
expr.span,
283-
"you seem to be trying to match on a boolean expression. Consider using an if..else block:",
284-
move |db| {
285-
if let Some(sugg) = sugg {
286-
db.span_suggestion(expr.span, "try this", sugg);
287-
}
288-
});
285+
});
289286
}
290287
}
291288

@@ -309,26 +306,28 @@ fn check_overlapping_arms(cx: &LateContext, ex: &Expr, arms: &[Arm]) {
309306
fn check_match_ref_pats(cx: &LateContext, ex: &Expr, arms: &[Arm], source: MatchSource, expr: &Expr) {
310307
if has_only_ref_pats(arms) {
311308
if let ExprAddrOf(Mutability::MutImmutable, ref inner) = ex.node {
312-
let template = match_template(cx, expr.span, source, "", inner);
313309
span_lint_and_then(cx,
314310
MATCH_REF_PATS,
315311
expr.span,
316312
"you don't need to add `&` to both the expression and the patterns",
317313
|db| {
318-
db.span_suggestion(expr.span, "try", template);
319-
});
314+
let inner = Sugg::hir(cx, inner, "..");
315+
let template = match_template(cx, expr.span, source, inner);
316+
db.span_suggestion(expr.span, "try", template);
317+
});
320318
} else {
321-
let template = match_template(cx, expr.span, source, "*", ex);
322319
span_lint_and_then(cx,
323320
MATCH_REF_PATS,
324321
expr.span,
325322
"you don't need to add `&` to all patterns",
326323
|db| {
327-
db.span_suggestion(expr.span,
328-
"instead of prefixing all patterns with `&`, you can \
329-
dereference the expression",
330-
template);
331-
});
324+
let ex = Sugg::hir(cx, ex, "..");
325+
let template = match_template(cx, expr.span, source, ex.deref());
326+
db.span_suggestion(expr.span,
327+
"instead of prefixing all patterns with `&`, you can \
328+
dereference the expression",
329+
template);
330+
});
332331
}
333332
}
334333
}
@@ -411,12 +410,11 @@ fn has_only_ref_pats(arms: &[Arm]) -> bool {
411410
mapped.map_or(false, |v| v.iter().any(|el| *el))
412411
}
413412

414-
fn match_template(cx: &LateContext, span: Span, source: MatchSource, op: &str, expr: &Expr) -> String {
415-
let expr_snippet = snippet(cx, expr.span, "..");
413+
fn match_template(cx: &LateContext, span: Span, source: MatchSource, expr: Sugg) -> String {
416414
match source {
417-
MatchSource::Normal => format!("match {}{} {{ .. }}", op, expr_snippet),
418-
MatchSource::IfLetDesugar { .. } => format!("if let .. = {}{} {{ .. }}", op, expr_snippet),
419-
MatchSource::WhileLetDesugar => format!("while let .. = {}{} {{ .. }}", op, expr_snippet),
415+
MatchSource::Normal => format!("match {} {{ .. }}", expr),
416+
MatchSource::IfLetDesugar { .. } => format!("if let .. = {} {{ .. }}", expr),
417+
MatchSource::WhileLetDesugar => format!("while let .. = {} {{ .. }}", expr),
420418
MatchSource::ForLoopDesugar => span_bug!(span, "for loop desugared to match with &-patterns!"),
421419
MatchSource::TryDesugar => span_bug!(span, "`?` operator desugared to match with &-patterns!"),
422420
}

clippy_lints/src/utils/sugg.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,11 @@ impl<'a> Sugg<'a> {
134134
make_unop("&mut ", self)
135135
}
136136

137+
/// Convenience method to create the `*<expr>` suggestion.
138+
pub fn deref(self) -> Sugg<'static> {
139+
make_unop("*", self)
140+
}
141+
137142
/// Convenience method to create the `<lhs>..<rhs>` or `<lhs>...<rhs>` suggestion.
138143
pub fn range(self, end: Self, limit: ast::RangeLimits) -> Sugg<'static> {
139144
match limit {

tests/compile-fail/matches.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ fn match_bool() {
112112

113113
match test {
114114
//~^ ERROR you seem to be trying to match on a boolean expression
115-
//~| HELP try
115+
//~| HELP consider
116116
//~| SUGGESTION if test { 0 } else { 42 };
117117
true => 0,
118118
false => 42,
@@ -121,31 +121,31 @@ fn match_bool() {
121121
let option = 1;
122122
match option == 1 {
123123
//~^ ERROR you seem to be trying to match on a boolean expression
124-
//~| HELP try
124+
//~| HELP consider
125125
//~| SUGGESTION if option == 1 { 1 } else { 0 };
126126
true => 1,
127127
false => 0,
128128
};
129129

130130
match test {
131131
//~^ ERROR you seem to be trying to match on a boolean expression
132-
//~| HELP try
132+
//~| HELP consider
133133
//~| SUGGESTION if !test { println!("Noooo!"); };
134134
true => (),
135135
false => { println!("Noooo!"); }
136136
};
137137

138138
match test {
139139
//~^ ERROR you seem to be trying to match on a boolean expression
140-
//~| HELP try
140+
//~| HELP consider
141141
//~| SUGGESTION if !test { println!("Noooo!"); };
142142
false => { println!("Noooo!"); }
143143
_ => (),
144144
};
145145

146146
match test && test {
147147
//~^ ERROR you seem to be trying to match on a boolean expression
148-
//~| HELP try
148+
//~| HELP consider
149149
//~| SUGGESTION if !(test && test) { println!("Noooo!"); };
150150
//~| ERROR equal expressions as operands
151151
false => { println!("Noooo!"); }
@@ -154,7 +154,7 @@ fn match_bool() {
154154

155155
match test {
156156
//~^ ERROR you seem to be trying to match on a boolean expression
157-
//~| HELP try
157+
//~| HELP consider
158158
//~| SUGGESTION if test { println!("Yes!"); } else { println!("Noooo!"); };
159159
false => { println!("Noooo!"); }
160160
true => { println!("Yes!"); }

0 commit comments

Comments
 (0)