use rustc::hir::def::CtorKind;
use rustc::hir::*;
use rustc::lint::{in_external_macro, LateContext, LateLintPass, LintArray, LintContext, LintPass};
-use rustc::ty::{self, Ty, TyKind};
-use rustc::{declare_tool_lint, lint_array};
+use rustc::ty::{self, Ty};
+use rustc::{declare_lint_pass, declare_tool_lint};
use rustc_errors::Applicability;
use std::cmp::Ordering;
use std::collections::Bound;
/// **Known problems:** None.
///
/// **Example:**
- /// ```ignore
+ /// ```rust
+ /// # fn bar(stool: &str) {}
+ /// # let x = Some("abc");
/// match x {
/// Some(ref foo) => bar(foo),
/// _ => (),
/// ```
pub SINGLE_MATCH,
style,
- "a match statement with a single nontrivial arm (i.e. where the other arm is `_ => {}`) instead of `if let`"
+ "a match statement with a single nontrivial arm (i.e., where the other arm is `_ => {}`) instead of `if let`"
}
declare_clippy_lint! {
///
/// Using `if let` with `else`:
///
- /// ```ignore
+ /// ```rust
/// if let Some(ref foo) = x {
/// bar(foo);
/// } else {
/// **Known problems:** None.
///
/// **Example:**
- /// ```ignore
+ /// ```rust,ignore
/// match x {
/// &A(ref y) => foo(y),
/// &B => bar(),
/// **Known problems:** None.
///
/// **Example:**
- /// ```ignore
+ /// ```rust
+ /// # fn foo() {}
+ /// # fn bar() {}
/// let condition: bool = true;
/// match condition {
/// true => foo(),
/// }
/// ```
/// Use if/else instead:
- /// ```ignore
+ /// ```rust
+ /// # fn foo() {}
+ /// # fn bar() {}
/// let condition: bool = true;
/// if condition {
/// foo();
"a wildcard enum match arm using `_`"
}
-#[allow(missing_copy_implementations)]
-pub struct MatchPass;
-
-impl LintPass for MatchPass {
- fn get_lints(&self) -> LintArray {
- lint_array!(
- SINGLE_MATCH,
- MATCH_REF_PATS,
- MATCH_BOOL,
- SINGLE_MATCH_ELSE,
- MATCH_OVERLAPPING_ARM,
- MATCH_WILD_ERR_ARM,
- MATCH_AS_REF,
- WILDCARD_ENUM_MATCH_ARM
- )
- }
-
- fn name(&self) -> &'static str {
- "Matches"
- }
-}
-
-impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MatchPass {
+declare_lint_pass!(Matches => [
+ SINGLE_MATCH,
+ MATCH_REF_PATS,
+ MATCH_BOOL,
+ SINGLE_MATCH_ELSE,
+ MATCH_OVERLAPPING_ARM,
+ MATCH_WILD_ERR_ARM,
+ MATCH_AS_REF,
+ WILDCARD_ENUM_MATCH_ARM
+]);
+
+impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Matches {
fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr) {
if in_external_macro(cx.sess(), expr.span) {
return;
ty: Ty<'_>,
els: Option<&Expr>,
) {
- // list of candidate Enums we know will never get any more members
+ // list of candidate `Enum`s we know will never get any more members
let candidates = &[
(&paths::COW, "Borrowed"),
(&paths::COW, "Cow::Borrowed"),
let path = match arms[1].pats[0].node {
PatKind::TupleStruct(ref path, ref inner, _) => {
- // contains any non wildcard patterns? e.g. Err(err)
+ // Contains any non wildcard patterns (e.g., `Err(err)`)?
if !inner.iter().all(is_wild) {
return;
}
}
fn check_match_bool(cx: &LateContext<'_, '_>, ex: &Expr, arms: &[Arm], expr: &Expr) {
- // type of expression == bool
+ // Type of expression is `bool`.
if cx.tables.expr_ty(ex).sty == ty::Bool {
span_lint_and_then(
cx,
// already covered.
let mut missing_variants = vec![];
- if let TyKind::Adt(def, _) = ty.sty {
+ if let ty::Adt(def, _) = ty.sty {
for variant in &def.variants {
missing_variants.push(variant);
}
for pat in &arm.pats {
if let PatKind::Path(ref path) = pat.deref().node {
if let QPath::Resolved(_, p) = path {
- missing_variants.retain(|e| e.did != p.def.def_id());
+ missing_variants.retain(|e| e.ctor_def_id != Some(p.def.def_id()));
}
} else if let PatKind::TupleStruct(ref path, ..) = pat.deref().node {
if let QPath::Resolved(_, p) = path {
- missing_variants.retain(|e| e.did != p.def.def_id());
+ missing_variants.retain(|e| e.ctor_def_id != Some(p.def.def_id()));
}
}
}
String::new()
};
// This path assumes that the enum type is imported into scope.
- format!("{}{}{}", ident_str, cx.tcx.item_path_str(v.did), suffix)
+ format!("{}{}{}", ident_str, cx.tcx.def_path_str(v.def_id), suffix)
})
.collect();
}
}
-/// Get all arms that are unbounded `PatRange`s.
+/// Gets all arms that are unbounded `PatRange`s.
fn all_ranges<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, arms: &'tcx [Arm]) -> Vec<SpannedRange<Constant>> {
arms.iter()
.flat_map(|arm| {
type TypedRanges = Vec<SpannedRange<u128>>;
-/// Get all `Int` ranges or all `Uint` ranges. Mixed types are an error anyway
+/// Gets all `Int` ranges or all `Uint` ranges. Mixed types are an error anyway
/// and other types than
/// `Uint` and `Int` probably don't make sense.
fn type_ranges(ranges: &[SpannedRange<Constant>]) -> TypedRanges {