use rustc::lint::*;
-use rustc::middle::ty;
+use rustc::ty;
use rustc_front::hir::*;
use std::collections::HashMap;
use std::collections::hash_map::Entry;
/// **What it does:** This lint checks for `match` with identical arm bodies.
///
-/// **Why is this bad?** This is probably a copy & paste error.
+/// **Why is this bad?** This is probably a copy & paste error. If arm bodies are the same on
+/// purpose, you can factor them
+/// [using `|`](https://doc.rust-lang.org/book/patterns.html#multiple-patterns).
///
/// **Known problems:** Hopefully none.
///
/// match foo {
/// Bar => bar(),
/// Quz => quz(),
-/// Baz => bar(), // <= oups
+/// Baz => bar(), // <= oops
/// }
/// ```
declare_lint! {
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,
};
let eq = |lhs: &Arm, rhs: &Arm| -> bool {
- SpanlessEq::new(cx).eq_expr(&lhs.body, &rhs.body) &&
+ // Arms with a guard are ignored, those can’t always be merged together
+ lhs.guard.is_none() && rhs.guard.is_none() &&
+ SpanlessEq::new(cx).eq_expr(&lhs.body, &rhs.body) &&
// all patterns should have the same bindings
bindings(cx, &lhs.pats[0]) == bindings(cx, &rhs.pats[0])
};
if let ExprMatch(_, ref arms, MatchSource::Normal) = expr.node {
- if let Some((i, j)) = search_same(&**arms, hash, eq) {
+ if let Some((i, j)) = search_same(&arms, hash, eq) {
span_note_and_lint(cx,
MATCH_SAME_ARMS,
j.body.span,