/// ```rust
/// # fn bar(stool: &str) {}
/// # let x = Some("abc");
+ ///
+ /// // Bad
/// match x {
/// Some(ref foo) => bar(foo),
/// _ => (),
/// }
+ ///
+ /// // Good
+ /// if let Some(ref foo) = x {
+ /// bar(foo);
+ /// }
/// ```
pub SINGLE_MATCH,
style,
///
/// **Example:**
/// ```rust,ignore
+ /// // Bad
/// match x {
/// &A(ref y) => foo(y),
/// &B => bar(),
/// _ => frob(&x),
/// }
+ ///
+ /// // Good
+ /// match *x {
+ /// A(ref y) => foo(y),
+ /// B => bar(),
+ /// _ => frob(x),
+ /// }
/// ```
pub MATCH_REF_PATS,
style,
/// **What it does:** Checks for arm which matches all errors with `Err(_)`
/// and take drastic actions like `panic!`.
///
- /// **Why is this bad?** It is generally a bad practice, just like
+ /// **Why is this bad?** It is generally a bad practice, similar to
/// catching all exceptions in java with `catch(Exception)`
///
/// **Known problems:** None.
/// }
/// ```
pub MATCH_WILD_ERR_ARM,
- style,
+ pedantic,
"a `match` with `Err(_)` arm and take drastic actions"
}
/// **Example:**
/// ```rust
/// let x: Option<()> = None;
+ ///
+ /// // Bad
/// let r: Option<&()> = match x {
/// None => None,
/// Some(ref v) => Some(v),
/// };
+ ///
+ /// // Good
+ /// let r: Option<&()> = x.as_ref();
/// ```
pub MATCH_AS_REF,
complexity,
/// ```rust
/// # enum Foo { A(usize), B(usize) }
/// # let x = Foo::B(1);
+ ///
+ /// // Bad
/// match x {
- /// A => {},
+ /// Foo::A(_) => {},
/// _ => {},
/// }
+ ///
+ /// // Good
+ /// match x {
+ /// Foo::A(_) => {},
+ /// Foo::B(_) => {},
+ /// }
/// ```
pub WILDCARD_ENUM_MATCH_ARM,
restriction,
/// ```rust
/// # enum Foo { A, B, C }
/// # let x = Foo::B;
+ /// // Bad
/// match x {
/// Foo::A => {},
/// Foo::B => {},
/// _ => {},
/// }
- /// ```
- /// Use instead:
- /// ```rust
- /// # enum Foo { A, B, C }
- /// # let x = Foo::B;
+ ///
+ /// // Good
/// match x {
/// Foo::A => {},
/// Foo::B => {},
///
/// **Example:**
/// ```rust
+ /// // Bad
/// match "foo" {
/// "a" => {},
/// "bar" | _ => {},
/// }
+ ///
+ /// // Good
+ /// match "foo" {
+ /// "a" => {},
+ /// _ => {},
+ /// }
/// ```
pub WILDCARD_IN_OR_PATTERNS,
complexity,
arm.pat.span,
&format!("`Err({})` matches all errors", &ident_bind_name),
None,
- "match each error separately or use the error output",
+ "match each error separately or use the error output, or use `.except(msg)` if the error case is unreachable",
);
}
}
if let QPath::Resolved(_, p) = path {
missing_variants.retain(|e| e.ctor_def_id != Some(p.res.def_id()));
}
- } else if let PatKind::TupleStruct(ref path, ..) = arm.pat.kind {
+ } else if let PatKind::TupleStruct(ref path, ref patterns, ..) = arm.pat.kind {
if let QPath::Resolved(_, p) = path {
- missing_variants.retain(|e| e.ctor_def_id != Some(p.res.def_id()));
+ // Some simple checks for exhaustive patterns.
+ // There is a room for improvements to detect more cases,
+ // but it can be more expensive to do so.
+ let is_pattern_exhaustive = |pat: &&Pat<'_>| {
+ if let PatKind::Wild | PatKind::Binding(.., None) = pat.kind {
+ true
+ } else {
+ false
+ }
+ };
+ if patterns.iter().all(is_pattern_exhaustive) {
+ missing_variants.retain(|e| e.ctor_def_id != Some(p.res.def_id()));
+ }
}
}
}
span_lint_and_then(cx, MATCH_REF_PATS, expr.span, title, |diag| {
if !expr.span.from_expansion() {
- multispan_sugg(diag, msg.to_owned(), suggs);
+ multispan_sugg(diag, msg, suggs);
}
});
}