use std::iter;
declare_clippy_lint! {
- /// **What it does:** Checks for patterns that aren't exact representations of the types
+ /// ### What it does
+ /// Checks for patterns that aren't exact representations of the types
/// they are applied to.
///
/// To satisfy this lint, you will have to adjust either the expression that is matched
/// this lint can still be used to highlight areas of interest and ensure a good understanding
/// of ownership semantics.
///
- /// **Why is this bad?** It isn't bad in general. But in some contexts it can be desirable
+ /// ### Why is this bad?
+ /// It isn't bad in general. But in some contexts it can be desirable
/// because it increases ownership hints in the code, and will guard against some changes
/// in ownership.
///
- /// **Known problems:** None.
- ///
- /// **Example:**
- ///
+ /// ### Example
/// This example shows the basic adjustments necessary to satisfy the lint. Note how
/// the matched expression is explicitly dereferenced with `*` and the `inner` variable
/// is bound to a shared borrow via `ref inner`.
impl<'tcx> LateLintPass<'tcx> for PatternTypeMismatch {
fn check_stmt(&mut self, cx: &LateContext<'tcx>, stmt: &'tcx Stmt<'_>) {
- if let StmtKind::Local(ref local) = stmt.kind {
+ if let StmtKind::Local(local) = stmt.kind {
if let Some(init) = &local.init {
if let Some(init_ty) = cx.typeck_results().node_type_opt(init.hir_id) {
let pat = &local.pat;
}
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
- if let ExprKind::Match(ref expr, arms, source) = expr.kind {
- match source {
- MatchSource::Normal | MatchSource::IfLetDesugar { .. } | MatchSource::WhileLetDesugar => {
- if let Some(expr_ty) = cx.typeck_results().node_type_opt(expr.hir_id) {
- 'pattern_checks: for arm in arms {
- let pat = &arm.pat;
- if in_external_macro(cx.sess(), pat.span) {
- continue 'pattern_checks;
- }
- if apply_lint(cx, pat, expr_ty, DerefPossible::Possible) {
- break 'pattern_checks;
- }
- }
+ if let ExprKind::Match(scrutinee, arms, MatchSource::Normal) = expr.kind {
+ if let Some(expr_ty) = cx.typeck_results().node_type_opt(scrutinee.hir_id) {
+ 'pattern_checks: for arm in arms {
+ let pat = &arm.pat;
+ if in_external_macro(cx.sess(), pat.span) {
+ continue 'pattern_checks;
}
- },
- _ => (),
+ if apply_lint(cx, pat, expr_ty, DerefPossible::Possible) {
+ break 'pattern_checks;
+ }
+ }
+ }
+ }
+ if let ExprKind::Let(let_pat, let_expr, _) = expr.kind {
+ if let Some(expr_ty) = cx.typeck_results().node_type_opt(let_expr.hir_id) {
+ if in_external_macro(cx.sess(), let_pat.span) {
+ return;
+ }
+ apply_lint(cx, let_pat, expr_ty, DerefPossible::Possible);
}
}
}
) {
if let Some(fn_sig) = cx.typeck_results().liberated_fn_sigs().get(hir_id) {
for (param, ty) in iter::zip(body.params, fn_sig.inputs()) {
- apply_lint(cx, ¶m.pat, ty, DerefPossible::Impossible);
+ apply_lint(cx, param.pat, ty, DerefPossible::Impossible);
}
}
}
ty: Ty<'tcx>,
level: Level,
) -> Option<(Span, Mutability, Level)> {
- if let PatKind::Ref(ref sub_pat, _) = pat.kind {
+ if let PatKind::Ref(sub_pat, _) = pat.kind {
if let TyKind::Ref(_, sub_ty, _) = ty.kind() {
return find_first_mismatch(cx, sub_pat, sub_ty, Level::Lower);
}
}
}
- if let PatKind::Struct(ref qpath, ref field_pats, _) = pat.kind {
- if let TyKind::Adt(ref adt_def, ref substs_ref) = ty.kind() {
+ if let PatKind::Struct(ref qpath, field_pats, _) = pat.kind {
+ if let TyKind::Adt(adt_def, substs_ref) = ty.kind() {
if let Some(variant) = get_variant(adt_def, qpath) {
let field_defs = &variant.fields;
return find_first_mismatch_in_struct(cx, field_pats, field_defs, substs_ref);
}
}
- if let PatKind::TupleStruct(ref qpath, ref pats, _) = pat.kind {
- if let TyKind::Adt(ref adt_def, ref substs_ref) = ty.kind() {
+ if let PatKind::TupleStruct(ref qpath, pats, _) = pat.kind {
+ if let TyKind::Adt(adt_def, substs_ref) = ty.kind() {
if let Some(variant) = get_variant(adt_def, qpath) {
let field_defs = &variant.fields;
let ty_iter = field_defs.iter().map(|field_def| field_def.ty(cx.tcx, substs_ref));
}
}
- if let PatKind::Tuple(ref pats, _) = pat.kind {
+ if let PatKind::Tuple(pats, _) = pat.kind {
if let TyKind::Tuple(..) = ty.kind() {
return find_first_mismatch_in_tuple(cx, pats, ty.tuple_fields());
}
fn find_first_mismatch_in_tuple<'tcx, I>(
cx: &LateContext<'tcx>,
- pats: &[&Pat<'_>],
+ pats: &[Pat<'_>],
ty_iter_src: I,
) -> Option<(Span, Mutability, Level)>
where