Auto merge of #101241 - camsteffen:refactor-binding-annotations, r=cjgillot

`BindingAnnotation` refactor

* `ast::BindingMode` is deleted and replaced with `hir::BindingAnnotation` (which is moved to `ast`)
* `BindingAnnotation` is changed from an enum to a tuple struct e.g. `BindingAnnotation(ByRef::No, Mutability::Mut)`
* Associated constants added for convenience `BindingAnnotation::{NONE, REF, MUT, REF_MUT}`

One goal is to make it more clear that `BindingAnnotation` merely represents syntax `ref mut` and not the actual binding mode. This was especially confusing since we had `ast::BindingMode`->`hir::BindingAnnotation`->`thir::BindingMode`.

I wish there were more symmetry between `ByRef` and `Mutability` (variant) naming (maybe `Mutable::Yes`?), and I also don't love how long the name `BindingAnnotation` is, but this seems like the best compromise. Ideas welcome.
This commit is contained in:
bors 2022-09-06 03:16:29 +00:00
commit ce339b219a
35 changed files with 95 additions and 103 deletions

View file

@ -503,7 +503,7 @@ impl<'tcx> LateLintPass<'tcx> for Dereferencing {
} }
fn check_pat(&mut self, cx: &LateContext<'tcx>, pat: &'tcx Pat<'_>) { fn check_pat(&mut self, cx: &LateContext<'tcx>, pat: &'tcx Pat<'_>) {
if let PatKind::Binding(BindingAnnotation::Ref, id, name, _) = pat.kind { if let PatKind::Binding(BindingAnnotation::REF, id, name, _) = pat.kind {
if let Some(opt_prev_pat) = self.ref_locals.get_mut(&id) { if let Some(opt_prev_pat) = self.ref_locals.get_mut(&id) {
// This binding id has been seen before. Add this pattern to the list of changes. // This binding id has been seen before. Add this pattern to the list of changes.
if let Some(prev_pat) = opt_prev_pat { if let Some(prev_pat) = opt_prev_pat {

View file

@ -128,7 +128,7 @@ fn look_in_block<'tcx, 'hir>(cx: &LateContext<'tcx>, kind: &'tcx ExprKind<'hir>)
if let Some(Node::Pat(res_pat)) = cx.tcx.hir().find(expr_res); if let Some(Node::Pat(res_pat)) = cx.tcx.hir().find(expr_res);
// Find id of the local we found in the block // Find id of the local we found in the block
if let PatKind::Binding(BindingAnnotation::Unannotated, local_hir_id, _ident, None) = local.pat.kind; if let PatKind::Binding(BindingAnnotation::NONE, local_hir_id, _ident, None) = local.pat.kind;
// If those two are the same hir id // If those two are the same hir id
if res_pat.hir_id == local_hir_id; if res_pat.hir_id == local_hir_id;

View file

@ -95,12 +95,14 @@ fn find_slice_values(cx: &LateContext<'_>, pat: &hir::Pat<'_>) -> FxIndexMap<hir
let mut removed_pat: FxHashSet<hir::HirId> = FxHashSet::default(); let mut removed_pat: FxHashSet<hir::HirId> = FxHashSet::default();
let mut slices: FxIndexMap<hir::HirId, SliceLintInformation> = FxIndexMap::default(); let mut slices: FxIndexMap<hir::HirId, SliceLintInformation> = FxIndexMap::default();
pat.walk_always(|pat| { pat.walk_always(|pat| {
if let hir::PatKind::Binding(binding, value_hir_id, ident, sub_pat) = pat.kind { // We'll just ignore mut and ref mut for simplicity sake right now
// We'll just ignore mut and ref mut for simplicity sake right now if let hir::PatKind::Binding(
if let hir::BindingAnnotation::Mutable | hir::BindingAnnotation::RefMut = binding { hir::BindingAnnotation(by_ref, hir::Mutability::Not),
return; value_hir_id,
} ident,
sub_pat,
) = pat.kind
{
// This block catches bindings with sub patterns. It would be hard to build a correct suggestion // This block catches bindings with sub patterns. It would be hard to build a correct suggestion
// for them and it's likely that the user knows what they are doing in such a case. // for them and it's likely that the user knows what they are doing in such a case.
if removed_pat.contains(&value_hir_id) { if removed_pat.contains(&value_hir_id) {
@ -116,7 +118,7 @@ fn find_slice_values(cx: &LateContext<'_>, pat: &hir::Pat<'_>) -> FxIndexMap<hir
if let ty::Slice(inner_ty) | ty::Array(inner_ty, _) = bound_ty.peel_refs().kind() { if let ty::Slice(inner_ty) | ty::Array(inner_ty, _) = bound_ty.peel_refs().kind() {
// The values need to use the `ref` keyword if they can't be copied. // The values need to use the `ref` keyword if they can't be copied.
// This will need to be adjusted if the lint want to support mutable access in the future // This will need to be adjusted if the lint want to support mutable access in the future
let src_is_ref = bound_ty.is_ref() && binding != hir::BindingAnnotation::Ref; let src_is_ref = bound_ty.is_ref() && by_ref != hir::ByRef::Yes;
let needs_ref = !(src_is_ref || is_copy(cx, *inner_ty)); let needs_ref = !(src_is_ref || is_copy(cx, *inner_ty));
let slice_info = slices let slice_info = slices

View file

@ -4,7 +4,7 @@ use clippy_utils::{path_to_local_id, visitors::is_local_used};
use if_chain::if_chain; use if_chain::if_chain;
use rustc_errors::Applicability; use rustc_errors::Applicability;
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::BindingAnnotation; use rustc_hir::{BindingAnnotation, Mutability};
use rustc_lint::{LateContext, LateLintPass}; use rustc_lint::{LateContext, LateLintPass};
use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_session::{declare_lint_pass, declare_tool_lint};
@ -98,7 +98,7 @@ impl<'tcx> LateLintPass<'tcx> for LetIfSeq {
}; };
let mutability = match mode { let mutability = match mode {
BindingAnnotation::RefMut | BindingAnnotation::Mutable => "<mut> ", BindingAnnotation(_, Mutability::Mut) => "<mut> ",
_ => "", _ => "",
}; };

View file

@ -106,7 +106,7 @@ fn get_binding(pat: &Pat<'_>) -> Option<HirId> {
hir_id = None; hir_id = None;
return; return;
} }
if let BindingAnnotation::Unannotated = annotation { if let BindingAnnotation::NONE = annotation {
hir_id = Some(id); hir_id = Some(id);
} }
}); });

View file

@ -44,7 +44,7 @@ fn check_for_mutability(cx: &LateContext<'_>, bound: &Expr<'_>) -> Option<HirId>
if_chain! { if_chain! {
if let Some(hir_id) = path_to_local(bound); if let Some(hir_id) = path_to_local(bound);
if let Node::Pat(pat) = cx.tcx.hir().get(hir_id); if let Node::Pat(pat) = cx.tcx.hir().get(hir_id);
if let PatKind::Binding(BindingAnnotation::Mutable, ..) = pat.kind; if let PatKind::Binding(BindingAnnotation::MUT, ..) = pat.kind;
then { then {
return Some(hir_id); return Some(hir_id);
} }

View file

@ -7,7 +7,7 @@ use if_chain::if_chain;
use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::fx::FxHashSet;
use rustc_hir::def::{DefKind, Res}; use rustc_hir::def::{DefKind, Res};
use rustc_hir::intravisit::{walk_expr, Visitor}; use rustc_hir::intravisit::{walk_expr, Visitor};
use rustc_hir::{BindingAnnotation, Block, Expr, ExprKind, HirId, Node, Pat, PatKind, Stmt, StmtKind}; use rustc_hir::{BindingAnnotation, Block, Expr, ExprKind, HirId, Mutability, Node, Pat, PatKind, Stmt, StmtKind};
use rustc_lint::LateContext; use rustc_lint::LateContext;
use rustc_span::symbol::sym; use rustc_span::symbol::sym;
use std::iter::Iterator; use std::iter::Iterator;
@ -65,7 +65,7 @@ pub(super) fn check<'tcx>(
if_chain! { if_chain! {
if let Node::Pat(pat) = node; if let Node::Pat(pat) = node;
if let PatKind::Binding(bind_ann, ..) = pat.kind; if let PatKind::Binding(bind_ann, ..) = pat.kind;
if !matches!(bind_ann, BindingAnnotation::RefMut | BindingAnnotation::Mutable); if !matches!(bind_ann, BindingAnnotation(_, Mutability::Mut));
let parent_node = cx.tcx.hir().get_parent_node(hir_id); let parent_node = cx.tcx.hir().get_parent_node(hir_id);
if let Some(Node::Local(parent_let_expr)) = cx.tcx.hir().find(parent_node); if let Some(Node::Local(parent_let_expr)) = cx.tcx.hir().find(parent_node);
if let Some(init) = parent_let_expr.init; if let Some(init) = parent_let_expr.init;

View file

@ -165,7 +165,7 @@ fn check<'tcx>(
} }
// `ref` and `ref mut` annotations were handled earlier. // `ref` and `ref mut` annotations were handled earlier.
let annotation = if matches!(annotation, BindingAnnotation::Mutable) { let annotation = if matches!(annotation, BindingAnnotation::MUT) {
"mut " "mut "
} else { } else {
"" ""

View file

@ -2,7 +2,7 @@ use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::source::snippet_with_applicability; use clippy_utils::source::snippet_with_applicability;
use clippy_utils::{is_lang_ctor, peel_blocks}; use clippy_utils::{is_lang_ctor, peel_blocks};
use rustc_errors::Applicability; use rustc_errors::Applicability;
use rustc_hir::{Arm, BindingAnnotation, Expr, ExprKind, LangItem, PatKind, QPath}; use rustc_hir::{Arm, BindingAnnotation, ByRef, Expr, ExprKind, LangItem, Mutability, PatKind, QPath};
use rustc_lint::LateContext; use rustc_lint::LateContext;
use rustc_middle::ty; use rustc_middle::ty;
@ -10,18 +10,17 @@ use super::MATCH_AS_REF;
pub(crate) fn check(cx: &LateContext<'_>, ex: &Expr<'_>, arms: &[Arm<'_>], expr: &Expr<'_>) { pub(crate) fn check(cx: &LateContext<'_>, ex: &Expr<'_>, arms: &[Arm<'_>], expr: &Expr<'_>) {
if arms.len() == 2 && arms[0].guard.is_none() && arms[1].guard.is_none() { if arms.len() == 2 && arms[0].guard.is_none() && arms[1].guard.is_none() {
let arm_ref: Option<BindingAnnotation> = if is_none_arm(cx, &arms[0]) { let arm_ref_mut = if is_none_arm(cx, &arms[0]) {
is_ref_some_arm(cx, &arms[1]) is_ref_some_arm(cx, &arms[1])
} else if is_none_arm(cx, &arms[1]) { } else if is_none_arm(cx, &arms[1]) {
is_ref_some_arm(cx, &arms[0]) is_ref_some_arm(cx, &arms[0])
} else { } else {
None None
}; };
if let Some(rb) = arm_ref { if let Some(rb) = arm_ref_mut {
let suggestion = if rb == BindingAnnotation::Ref { let suggestion = match rb {
"as_ref" Mutability::Not => "as_ref",
} else { Mutability::Mut => "as_mut",
"as_mut"
}; };
let output_ty = cx.typeck_results().expr_ty(expr); let output_ty = cx.typeck_results().expr_ty(expr);
@ -66,19 +65,18 @@ fn is_none_arm(cx: &LateContext<'_>, arm: &Arm<'_>) -> bool {
} }
// Checks if arm has the form `Some(ref v) => Some(v)` (checks for `ref` and `ref mut`) // Checks if arm has the form `Some(ref v) => Some(v)` (checks for `ref` and `ref mut`)
fn is_ref_some_arm(cx: &LateContext<'_>, arm: &Arm<'_>) -> Option<BindingAnnotation> { fn is_ref_some_arm(cx: &LateContext<'_>, arm: &Arm<'_>) -> Option<Mutability> {
if_chain! { if_chain! {
if let PatKind::TupleStruct(ref qpath, [first_pat, ..], _) = arm.pat.kind; if let PatKind::TupleStruct(ref qpath, [first_pat, ..], _) = arm.pat.kind;
if is_lang_ctor(cx, qpath, LangItem::OptionSome); if is_lang_ctor(cx, qpath, LangItem::OptionSome);
if let PatKind::Binding(rb, .., ident, _) = first_pat.kind; if let PatKind::Binding(BindingAnnotation(ByRef::Yes, mutabl), .., ident, _) = first_pat.kind;
if rb == BindingAnnotation::Ref || rb == BindingAnnotation::RefMut;
if let ExprKind::Call(e, [arg]) = peel_blocks(arm.body).kind; if let ExprKind::Call(e, [arg]) = peel_blocks(arm.body).kind;
if let ExprKind::Path(ref some_path) = e.kind; if let ExprKind::Path(ref some_path) = e.kind;
if is_lang_ctor(cx, some_path, LangItem::OptionSome); if is_lang_ctor(cx, some_path, LangItem::OptionSome);
if let ExprKind::Path(QPath::Resolved(_, path2)) = arg.kind; if let ExprKind::Path(QPath::Resolved(_, path2)) = arg.kind;
if path2.segments.len() == 1 && ident.name == path2.segments[0].ident.name; if path2.segments.len() == 1 && ident.name == path2.segments[0].ident.name;
then { then {
return Some(rb) return Some(mutabl)
} }
} }
None None

View file

@ -8,7 +8,7 @@ use clippy_utils::{
}; };
use rustc_errors::Applicability; use rustc_errors::Applicability;
use rustc_hir::LangItem::OptionNone; use rustc_hir::LangItem::OptionNone;
use rustc_hir::{Arm, BindingAnnotation, Expr, ExprKind, FnRetTy, Guard, Node, Pat, PatKind, Path, QPath}; use rustc_hir::{Arm, BindingAnnotation, ByRef, Expr, ExprKind, FnRetTy, Guard, Node, Pat, PatKind, Path, QPath};
use rustc_lint::LateContext; use rustc_lint::LateContext;
use rustc_span::sym; use rustc_span::sym;
use rustc_typeck::hir_ty_to_ty; use rustc_typeck::hir_ty_to_ty;
@ -189,8 +189,7 @@ fn pat_same_as_expr(pat: &Pat<'_>, expr: &Expr<'_>) -> bool {
}, },
)), )),
) => { ) => {
return !matches!(annot, BindingAnnotation::Ref | BindingAnnotation::RefMut) return !matches!(annot, BindingAnnotation(ByRef::Yes, _)) && pat_ident.name == first_seg.ident.name;
&& pat_ident.name == first_seg.ident.name;
}, },
// Example: `Custom::TypeA => Custom::TypeB`, or `None => None` // Example: `Custom::TypeA => Custom::TypeB`, or `None => None`
(PatKind::Path(QPath::Resolved(_, p_path)), ExprKind::Path(QPath::Resolved(_, e_path))) => { (PatKind::Path(QPath::Resolved(_, p_path)), ExprKind::Path(QPath::Resolved(_, e_path))) => {

View file

@ -175,7 +175,7 @@ fn collect_pat_paths<'a>(acc: &mut Vec<Ty<'a>>, cx: &LateContext<'a>, pat: &Pat<
let p_ty = cx.typeck_results().pat_ty(p); let p_ty = cx.typeck_results().pat_ty(p);
collect_pat_paths(acc, cx, p, p_ty); collect_pat_paths(acc, cx, p, p_ty);
}), }),
PatKind::TupleStruct(..) | PatKind::Binding(BindingAnnotation::Unannotated, .., None) | PatKind::Path(_) => { PatKind::TupleStruct(..) | PatKind::Binding(BindingAnnotation::NONE, .., None) | PatKind::Path(_) => {
acc.push(ty); acc.push(ty);
}, },
_ => {}, _ => {},

View file

@ -4,7 +4,7 @@ use clippy_utils::source::snippet_with_context;
use clippy_utils::sugg; use clippy_utils::sugg;
use clippy_utils::ty::is_copy; use clippy_utils::ty::is_copy;
use rustc_errors::Applicability; use rustc_errors::Applicability;
use rustc_hir::{BindingAnnotation, Expr, ExprKind, MatchSource, Node, PatKind, QPath}; use rustc_hir::{BindingAnnotation, ByRef, Expr, ExprKind, MatchSource, Node, PatKind, QPath};
use rustc_lint::LateContext; use rustc_lint::LateContext;
use rustc_middle::ty::{self, adjustment::Adjust}; use rustc_middle::ty::{self, adjustment::Adjust};
use rustc_span::symbol::{sym, Symbol}; use rustc_span::symbol::{sym, Symbol};
@ -101,12 +101,7 @@ pub(super) fn check(
_ => false, _ => false,
}, },
// local binding capturing a reference // local binding capturing a reference
Some(Node::Local(l)) Some(Node::Local(l)) if matches!(l.pat.kind, PatKind::Binding(BindingAnnotation(ByRef::Yes, _), ..)) => {
if matches!(
l.pat.kind,
PatKind::Binding(BindingAnnotation::Ref | BindingAnnotation::RefMut, ..)
) =>
{
return; return;
}, },
_ => false, _ => false,

View file

@ -24,7 +24,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, recv: &hir::Expr
if let Some(id) = path_to_local(recv); if let Some(id) = path_to_local(recv);
if let Node::Pat(pat) = cx.tcx.hir().get(id); if let Node::Pat(pat) = cx.tcx.hir().get(id);
if let PatKind::Binding(ann, _, _, _) = pat.kind; if let PatKind::Binding(ann, _, _, _) = pat.kind;
if ann != BindingAnnotation::Mutable; if ann != BindingAnnotation::MUT;
then { then {
application = Applicability::Unspecified; application = Applicability::Unspecified;
diag.span_help( diag.span_help(

View file

@ -33,13 +33,13 @@ pub(super) fn check<'tcx>(
let closure_expr = peel_blocks(&closure_body.value); let closure_expr = peel_blocks(&closure_body.value);
match closure_body.params[0].pat.kind { match closure_body.params[0].pat.kind {
hir::PatKind::Ref(inner, hir::Mutability::Not) => if let hir::PatKind::Binding( hir::PatKind::Ref(inner, hir::Mutability::Not) => if let hir::PatKind::Binding(
hir::BindingAnnotation::Unannotated, .., name, None hir::BindingAnnotation::NONE, .., name, None
) = inner.kind { ) = inner.kind {
if ident_eq(name, closure_expr) { if ident_eq(name, closure_expr) {
lint_explicit_closure(cx, e.span, recv.span, true, msrv); lint_explicit_closure(cx, e.span, recv.span, true, msrv);
} }
}, },
hir::PatKind::Binding(hir::BindingAnnotation::Unannotated, .., name, None) => { hir::PatKind::Binding(hir::BindingAnnotation::NONE, .., name, None) => {
match closure_expr.kind { match closure_expr.kind {
hir::ExprKind::Unary(hir::UnOp::Deref, inner) => { hir::ExprKind::Unary(hir::UnOp::Deref, inner) => {
if ident_eq(name, inner) { if ident_eq(name, inner) {

View file

@ -130,7 +130,7 @@ fn check_manual_split_once_indirect(
let ctxt = expr.span.ctxt(); let ctxt = expr.span.ctxt();
let mut parents = cx.tcx.hir().parent_iter(expr.hir_id); let mut parents = cx.tcx.hir().parent_iter(expr.hir_id);
if let (_, Node::Local(local)) = parents.next()? if let (_, Node::Local(local)) = parents.next()?
&& let PatKind::Binding(BindingAnnotation::Mutable, iter_binding_id, iter_ident, None) = local.pat.kind && let PatKind::Binding(BindingAnnotation::MUT, iter_binding_id, iter_ident, None) = local.pat.kind
&& let (iter_stmt_id, Node::Stmt(_)) = parents.next()? && let (iter_stmt_id, Node::Stmt(_)) = parents.next()?
&& let (_, Node::Block(enclosing_block)) = parents.next()? && let (_, Node::Block(enclosing_block)) = parents.next()?
@ -212,11 +212,10 @@ fn indirect_usage<'tcx>(
ctxt: SyntaxContext, ctxt: SyntaxContext,
) -> Option<IndirectUsage<'tcx>> { ) -> Option<IndirectUsage<'tcx>> {
if let StmtKind::Local(Local { if let StmtKind::Local(Local {
pat: pat: Pat {
Pat { kind: PatKind::Binding(BindingAnnotation::NONE, _, ident, None),
kind: PatKind::Binding(BindingAnnotation::Unannotated, _, ident, None), ..
.. },
},
init: Some(init_expr), init: Some(init_expr),
hir_id: local_hir_id, hir_id: local_hir_id,
.. ..

View file

@ -5,8 +5,8 @@ use rustc_ast::ast::LitKind;
use rustc_errors::Applicability; use rustc_errors::Applicability;
use rustc_hir::intravisit::FnKind; use rustc_hir::intravisit::FnKind;
use rustc_hir::{ use rustc_hir::{
self as hir, def, BinOpKind, BindingAnnotation, Body, Expr, ExprKind, FnDecl, HirId, Mutability, PatKind, Stmt, self as hir, def, BinOpKind, BindingAnnotation, Body, ByRef, Expr, ExprKind, FnDecl, HirId, Mutability, PatKind,
StmtKind, TyKind, Stmt, StmtKind, TyKind,
}; };
use rustc_lint::{LateContext, LateLintPass}; use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::lint::in_external_macro; use rustc_middle::lint::in_external_macro;
@ -146,7 +146,7 @@ impl<'tcx> LateLintPass<'tcx> for MiscLints {
return; return;
} }
for arg in iter_input_pats(decl, body) { for arg in iter_input_pats(decl, body) {
if let PatKind::Binding(BindingAnnotation::Ref | BindingAnnotation::RefMut, ..) = arg.pat.kind { if let PatKind::Binding(BindingAnnotation(ByRef::Yes, _), ..) = arg.pat.kind {
span_lint( span_lint(
cx, cx,
TOPLEVEL_REF_ARG, TOPLEVEL_REF_ARG,
@ -162,9 +162,8 @@ impl<'tcx> LateLintPass<'tcx> for MiscLints {
if_chain! { if_chain! {
if !in_external_macro(cx.tcx.sess, stmt.span); if !in_external_macro(cx.tcx.sess, stmt.span);
if let StmtKind::Local(local) = stmt.kind; if let StmtKind::Local(local) = stmt.kind;
if let PatKind::Binding(an, .., name, None) = local.pat.kind; if let PatKind::Binding(BindingAnnotation(ByRef::Yes, mutabl), .., name, None) = local.pat.kind;
if let Some(init) = local.init; if let Some(init) = local.init;
if an == BindingAnnotation::Ref || an == BindingAnnotation::RefMut;
then { then {
// use the macro callsite when the init span (but not the whole local span) // use the macro callsite when the init span (but not the whole local span)
// comes from an expansion like `vec![1, 2, 3]` in `let ref _ = vec![1, 2, 3];` // comes from an expansion like `vec![1, 2, 3]` in `let ref _ = vec![1, 2, 3];`
@ -173,7 +172,7 @@ impl<'tcx> LateLintPass<'tcx> for MiscLints {
} else { } else {
Sugg::hir(cx, init, "..") Sugg::hir(cx, init, "..")
}; };
let (mutopt, initref) = if an == BindingAnnotation::RefMut { let (mutopt, initref) = if mutabl == Mutability::Mut {
("mut ", sugg_init.mut_addr()) ("mut ", sugg_init.mut_addr())
} else { } else {
("", sugg_init.addr()) ("", sugg_init.addr())

View file

@ -1,18 +1,12 @@
use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::diagnostics::span_lint_and_sugg;
use rustc_ast::ast::{BindingMode, Mutability, Pat, PatKind}; use rustc_ast::ast::{Pat, PatKind};
use rustc_errors::Applicability; use rustc_errors::Applicability;
use rustc_lint::EarlyContext; use rustc_lint::EarlyContext;
use super::REDUNDANT_PATTERN; use super::REDUNDANT_PATTERN;
pub(super) fn check(cx: &EarlyContext<'_>, pat: &Pat) { pub(super) fn check(cx: &EarlyContext<'_>, pat: &Pat) {
if let PatKind::Ident(left, ident, Some(ref right)) = pat.kind { if let PatKind::Ident(ann, ident, Some(ref right)) = pat.kind {
let left_binding = match left {
BindingMode::ByRef(Mutability::Mut) => "ref mut ",
BindingMode::ByRef(Mutability::Not) => "ref ",
BindingMode::ByValue(..) => "",
};
if let PatKind::Wild = right.kind { if let PatKind::Wild = right.kind {
span_lint_and_sugg( span_lint_and_sugg(
cx, cx,
@ -23,7 +17,7 @@ pub(super) fn check(cx: &EarlyContext<'_>, pat: &Pat) {
ident.name, ident.name, ident.name, ident.name,
), ),
"try", "try",
format!("{}{}", left_binding, ident.name), format!("{}{}", ann.prefix_str(), ident.name),
Applicability::MachineApplicable, Applicability::MachineApplicable,
); );
} }

View file

@ -1,6 +1,6 @@
use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::diagnostics::span_lint_and_sugg;
use if_chain::if_chain; use if_chain::if_chain;
use rustc_ast::ast::{BindingMode, Lifetime, Mutability, Param, PatKind, Path, TyKind}; use rustc_ast::ast::{BindingAnnotation, ByRef, Lifetime, Mutability, Param, PatKind, Path, TyKind};
use rustc_errors::Applicability; use rustc_errors::Applicability;
use rustc_lint::{EarlyContext, EarlyLintPass}; use rustc_lint::{EarlyContext, EarlyLintPass};
use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_session::{declare_lint_pass, declare_tool_lint};
@ -120,14 +120,14 @@ impl EarlyLintPass for NeedlessArbitrarySelfType {
match &p.ty.kind { match &p.ty.kind {
TyKind::Path(None, path) => { TyKind::Path(None, path) => {
if let PatKind::Ident(BindingMode::ByValue(mutbl), _, _) = p.pat.kind { if let PatKind::Ident(BindingAnnotation(ByRef::No, mutbl), _, _) = p.pat.kind {
check_param_inner(cx, path, p.span.to(p.ty.span), &Mode::Value, mutbl); check_param_inner(cx, path, p.span.to(p.ty.span), &Mode::Value, mutbl);
} }
}, },
TyKind::Rptr(lifetime, mut_ty) => { TyKind::Rptr(lifetime, mut_ty) => {
if_chain! { if_chain! {
if let TyKind::Path(None, path) = &mut_ty.ty.kind; if let TyKind::Path(None, path) = &mut_ty.ty.kind;
if let PatKind::Ident(BindingMode::ByValue(Mutability::Not), _, _) = p.pat.kind; if let PatKind::Ident(BindingAnnotation::NONE, _, _) = p.pat.kind;
then { then {
check_param_inner(cx, path, p.span.to(p.ty.span), &Mode::Ref(*lifetime), mut_ty.mutbl); check_param_inner(cx, path, p.span.to(p.ty.span), &Mode::Ref(*lifetime), mut_ty.mutbl);
} }

View file

@ -59,7 +59,7 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessBorrowedRef {
if let PatKind::Ref(sub_pat, Mutability::Not) = pat.kind; if let PatKind::Ref(sub_pat, Mutability::Not) = pat.kind;
// Check sub_pat got a `ref` keyword (excluding `ref mut`). // Check sub_pat got a `ref` keyword (excluding `ref mut`).
if let PatKind::Binding(BindingAnnotation::Ref, .., spanned_name, _) = sub_pat.kind; if let PatKind::Binding(BindingAnnotation::REF, .., spanned_name, _) = sub_pat.kind;
let parent_id = cx.tcx.hir().get_parent_node(pat.hir_id); let parent_id = cx.tcx.hir().get_parent_node(pat.hir_id);
if let Some(parent_node) = cx.tcx.hir().find(parent_id); if let Some(parent_node) = cx.tcx.hir().find(parent_id);
then { then {

View file

@ -373,7 +373,7 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessLateInit {
if let Local { if let Local {
init: None, init: None,
pat: &Pat { pat: &Pat {
kind: PatKind::Binding(BindingAnnotation::Unannotated, binding_id, _, None), kind: PatKind::Binding(BindingAnnotation::NONE, binding_id, _, None),
.. ..
}, },
source: LocalSource::Normal, source: LocalSource::Normal,

View file

@ -8,7 +8,9 @@ use rustc_ast::ast::Attribute;
use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::fx::FxHashSet;
use rustc_errors::{Applicability, Diagnostic}; use rustc_errors::{Applicability, Diagnostic};
use rustc_hir::intravisit::FnKind; use rustc_hir::intravisit::FnKind;
use rustc_hir::{BindingAnnotation, Body, FnDecl, GenericArg, HirId, Impl, ItemKind, Node, PatKind, QPath, TyKind}; use rustc_hir::{
BindingAnnotation, Body, FnDecl, GenericArg, HirId, Impl, ItemKind, Mutability, Node, PatKind, QPath, TyKind,
};
use rustc_hir::{HirIdMap, HirIdSet}; use rustc_hir::{HirIdMap, HirIdSet};
use rustc_infer::infer::TyCtxtInferExt; use rustc_infer::infer::TyCtxtInferExt;
use rustc_lint::{LateContext, LateLintPass}; use rustc_lint::{LateContext, LateLintPass};
@ -188,13 +190,9 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByValue {
if !implements_borrow_trait; if !implements_borrow_trait;
if !all_borrowable_trait; if !all_borrowable_trait;
if let PatKind::Binding(mode, canonical_id, ..) = arg.pat.kind; if let PatKind::Binding(BindingAnnotation(_, Mutability::Not), canonical_id, ..) = arg.pat.kind;
if !moved_vars.contains(&canonical_id); if !moved_vars.contains(&canonical_id);
then { then {
if mode == BindingAnnotation::Mutable || mode == BindingAnnotation::RefMut {
continue;
}
// Dereference suggestion // Dereference suggestion
let sugg = |diag: &mut Diagnostic| { let sugg = |diag: &mut Diagnostic| {
if let ty::Adt(def, ..) = ty.kind() { if let ty::Adt(def, ..) = ty.kind() {

View file

@ -130,7 +130,7 @@ fn try_get_option_occurence<'tcx>(
.filter_map(|(id, &c)| none_captures.get(id).map(|&c2| (c, c2))) .filter_map(|(id, &c)| none_captures.get(id).map(|&c2| (c, c2)))
.all(|(x, y)| x.is_imm_ref() && y.is_imm_ref()); .all(|(x, y)| x.is_imm_ref() && y.is_imm_ref());
then { then {
let capture_mut = if bind_annotation == BindingAnnotation::Mutable { "mut " } else { "" }; let capture_mut = if bind_annotation == BindingAnnotation::MUT { "mut " } else { "" };
let some_body = peel_blocks(if_then); let some_body = peel_blocks(if_then);
let none_body = peel_blocks(if_else); let none_body = peel_blocks(if_else);
let method_sugg = if eager_or_lazy::switch_to_eager_eval(cx, none_body) { "map_or" } else { "map_or_else" }; let method_sugg = if eager_or_lazy::switch_to_eager_eval(cx, none_body) { "map_or" } else { "map_or_else" };
@ -138,7 +138,7 @@ fn try_get_option_occurence<'tcx>(
let (as_ref, as_mut) = match &expr.kind { let (as_ref, as_mut) = match &expr.kind {
ExprKind::AddrOf(_, Mutability::Not, _) => (true, false), ExprKind::AddrOf(_, Mutability::Not, _) => (true, false),
ExprKind::AddrOf(_, Mutability::Mut, _) => (false, true), ExprKind::AddrOf(_, Mutability::Mut, _) => (false, true),
_ => (bind_annotation == BindingAnnotation::Ref, bind_annotation == BindingAnnotation::RefMut), _ => (bind_annotation == BindingAnnotation::REF, bind_annotation == BindingAnnotation::REF_MUT),
}; };
// Check if captures the closure will need conflict with borrows made in the scrutinee. // Check if captures the closure will need conflict with borrows made in the scrutinee.

View file

@ -221,7 +221,7 @@ impl<'tcx> PassByRefOrValue {
// if function has a body and parameter is annotated with mut, ignore // if function has a body and parameter is annotated with mut, ignore
if let Some(param) = fn_body.and_then(|body| body.params.get(index)) { if let Some(param) = fn_body.and_then(|body| body.params.get(index)) {
match param.pat.kind { match param.pat.kind {
PatKind::Binding(BindingAnnotation::Unannotated, _, _, _) => {}, PatKind::Binding(BindingAnnotation::NONE, _, _, _) => {},
_ => continue, _ => continue,
} }
} }

View file

@ -571,7 +571,7 @@ fn check_ptr_arg_usage<'tcx>(cx: &LateContext<'tcx>, body: &'tcx Body<'_>, args:
Some((Node::Stmt(_), _)) => (), Some((Node::Stmt(_), _)) => (),
Some((Node::Local(l), _)) => { Some((Node::Local(l), _)) => {
// Only trace simple bindings. e.g `let x = y;` // Only trace simple bindings. e.g `let x = y;`
if let PatKind::Binding(BindingAnnotation::Unannotated, id, _, None) = l.pat.kind { if let PatKind::Binding(BindingAnnotation::NONE, id, _, None) = l.pat.kind {
self.bindings.insert(id, args_idx); self.bindings.insert(id, args_idx);
} else { } else {
set_skip_flag(); set_skip_flag();
@ -647,7 +647,7 @@ fn check_ptr_arg_usage<'tcx>(cx: &LateContext<'tcx>, body: &'tcx Body<'_>, args:
.filter_map(|(i, arg)| { .filter_map(|(i, arg)| {
let param = &body.params[arg.idx]; let param = &body.params[arg.idx];
match param.pat.kind { match param.pat.kind {
PatKind::Binding(BindingAnnotation::Unannotated, id, _, None) PatKind::Binding(BindingAnnotation::NONE, id, _, None)
if !is_lint_allowed(cx, PTR_ARG, param.hir_id) => if !is_lint_allowed(cx, PTR_ARG, param.hir_id) =>
{ {
Some((id, i)) Some((id, i))

View file

@ -9,7 +9,7 @@ use clippy_utils::{
use if_chain::if_chain; use if_chain::if_chain;
use rustc_errors::Applicability; use rustc_errors::Applicability;
use rustc_hir::LangItem::{OptionNone, OptionSome, ResultErr, ResultOk}; use rustc_hir::LangItem::{OptionNone, OptionSome, ResultErr, ResultOk};
use rustc_hir::{BindingAnnotation, Expr, ExprKind, Node, PatKind, PathSegment, QPath}; use rustc_hir::{BindingAnnotation, ByRef, Expr, ExprKind, Node, PatKind, PathSegment, QPath};
use rustc_lint::{LateContext, LateLintPass}; use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty::Ty; use rustc_middle::ty::Ty;
use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_session::{declare_lint_pass, declare_tool_lint};
@ -123,7 +123,7 @@ fn check_if_let_some_or_err_and_early_return<'tcx>(cx: &LateContext<'tcx>, expr:
if let Some(higher::IfLet { let_pat, let_expr, if_then, if_else }) = higher::IfLet::hir(cx, expr); if let Some(higher::IfLet { let_pat, let_expr, if_then, if_else }) = higher::IfLet::hir(cx, expr);
if !is_else_clause(cx.tcx, expr); if !is_else_clause(cx.tcx, expr);
if let PatKind::TupleStruct(ref path1, [field], None) = let_pat.kind; if let PatKind::TupleStruct(ref path1, [field], None) = let_pat.kind;
if let PatKind::Binding(annot, bind_id, ident, None) = field.kind; if let PatKind::Binding(BindingAnnotation(by_ref, _), bind_id, ident, None) = field.kind;
let caller_ty = cx.typeck_results().expr_ty(let_expr); let caller_ty = cx.typeck_results().expr_ty(let_expr);
let if_block = IfBlockType::IfLet(path1, caller_ty, ident.name, let_expr, if_then, if_else); let if_block = IfBlockType::IfLet(path1, caller_ty, ident.name, let_expr, if_then, if_else);
if (is_early_return(sym::Option, cx, &if_block) && path_to_local_id(peel_blocks(if_then), bind_id)) if (is_early_return(sym::Option, cx, &if_block) && path_to_local_id(peel_blocks(if_then), bind_id))
@ -132,12 +132,11 @@ fn check_if_let_some_or_err_and_early_return<'tcx>(cx: &LateContext<'tcx>, expr:
then { then {
let mut applicability = Applicability::MachineApplicable; let mut applicability = Applicability::MachineApplicable;
let receiver_str = snippet_with_applicability(cx, let_expr.span, "..", &mut applicability); let receiver_str = snippet_with_applicability(cx, let_expr.span, "..", &mut applicability);
let by_ref = matches!(annot, BindingAnnotation::Ref | BindingAnnotation::RefMut);
let requires_semi = matches!(get_parent_node(cx.tcx, expr.hir_id), Some(Node::Stmt(_))); let requires_semi = matches!(get_parent_node(cx.tcx, expr.hir_id), Some(Node::Stmt(_)));
let sugg = format!( let sugg = format!(
"{}{}?{}", "{}{}?{}",
receiver_str, receiver_str,
if by_ref { ".as_ref()" } else { "" }, if by_ref == ByRef::Yes { ".as_ref()" } else { "" },
if requires_semi { ";" } else { "" } if requires_semi { ";" } else { "" }
); );
span_lint_and_sugg( span_lint_and_sugg(

View file

@ -99,7 +99,7 @@ impl<'tcx> LateLintPass<'tcx> for SlowVectorInit {
// Matches statements which initializes vectors. For example: `let mut vec = Vec::with_capacity(10)` // Matches statements which initializes vectors. For example: `let mut vec = Vec::with_capacity(10)`
if_chain! { if_chain! {
if let StmtKind::Local(local) = stmt.kind; if let StmtKind::Local(local) = stmt.kind;
if let PatKind::Binding(BindingAnnotation::Mutable, local_id, _, None) = local.pat.kind; if let PatKind::Binding(BindingAnnotation::MUT, local_id, _, None) = local.pat.kind;
if let Some(init) = local.init; if let Some(init) = local.init;
if let Some(len_arg) = Self::is_vec_with_capacity(cx, init); if let Some(len_arg) = Self::is_vec_with_capacity(cx, init);

View file

@ -137,12 +137,12 @@ fn insert_necessary_parens(pat: &mut P<Pat>) {
struct Visitor; struct Visitor;
impl MutVisitor for Visitor { impl MutVisitor for Visitor {
fn visit_pat(&mut self, pat: &mut P<Pat>) { fn visit_pat(&mut self, pat: &mut P<Pat>) {
use ast::{BindingMode::*, Mutability::*}; use ast::BindingAnnotation;
noop_visit_pat(pat, self); noop_visit_pat(pat, self);
let target = match &mut pat.kind { let target = match &mut pat.kind {
// `i @ a | b`, `box a | b`, and `& mut? a | b`. // `i @ a | b`, `box a | b`, and `& mut? a | b`.
Ident(.., Some(p)) | Box(p) | Ref(p, _) if matches!(&p.kind, Or(ps) if ps.len() > 1) => p, Ident(.., Some(p)) | Box(p) | Ref(p, _) if matches!(&p.kind, Or(ps) if ps.len() > 1) => p,
Ref(p, Not) if matches!(p.kind, Ident(ByValue(Mut), ..)) => p, // `&(mut x)` Ref(p, Mutability::Not) if matches!(p.kind, Ident(BindingAnnotation::MUT, ..)) => p, // `&(mut x)`
_ => return, _ => return,
}; };
target.kind = Paren(P(take_pat(target))); target.kind = Paren(P(take_pat(target)));

View file

@ -6,7 +6,9 @@ use rustc_ast::ast::{LitFloatType, LitKind};
use rustc_ast::LitIntType; use rustc_ast::LitIntType;
use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::fx::FxHashMap;
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::{ArrayLen, Closure, ExprKind, FnRetTy, HirId, Lit, PatKind, QPath, StmtKind, TyKind}; use rustc_hir::{
ArrayLen, BindingAnnotation, Closure, ExprKind, FnRetTy, HirId, Lit, PatKind, QPath, StmtKind, TyKind,
};
use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_lint::{LateContext, LateLintPass, LintContext};
use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::symbol::{Ident, Symbol}; use rustc_span::symbol::{Ident, Symbol};
@ -610,10 +612,16 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> {
match pat.value.kind { match pat.value.kind {
PatKind::Wild => kind!("Wild"), PatKind::Wild => kind!("Wild"),
PatKind::Binding(anno, .., name, sub) => { PatKind::Binding(ann, _, name, sub) => {
bind!(self, name); bind!(self, name);
opt_bind!(self, sub); opt_bind!(self, sub);
kind!("Binding(BindingAnnotation::{anno:?}, _, {name}, {sub})"); let ann = match ann {
BindingAnnotation::NONE => "NONE",
BindingAnnotation::REF => "REF",
BindingAnnotation::MUT => "MUT",
BindingAnnotation::REF_MUT => "REF_MUT",
};
kind!("Binding(BindingAnnotation::{ann}, _, {name}, {sub})");
self.ident(name); self.ident(name);
sub.if_some(|p| self.pat(p)); sub.if_some(|p| self.pat(p));
}, },

View file

@ -157,7 +157,7 @@ impl<'tcx> LateLintPass<'tcx> for VecInitThenPush {
fn check_local(&mut self, cx: &LateContext<'tcx>, local: &'tcx Local<'tcx>) { fn check_local(&mut self, cx: &LateContext<'tcx>, local: &'tcx Local<'tcx>) {
if let Some(init_expr) = local.init if let Some(init_expr) = local.init
&& let PatKind::Binding(BindingAnnotation::Mutable, id, name, None) = local.pat.kind && let PatKind::Binding(BindingAnnotation::MUT, id, name, None) = local.pat.kind
&& !in_external_macro(cx.sess(), local.span) && !in_external_macro(cx.sess(), local.span)
&& let Some(init) = get_vec_init_kind(cx, init_expr) && let Some(init) = get_vec_init_kind(cx, init_expr)
&& !matches!(init, VecInitKind::WithExprCapacity(_)) && !matches!(init, VecInitKind::WithExprCapacity(_))

View file

@ -6,9 +6,9 @@ use rustc_data_structures::fx::FxHasher;
use rustc_hir::def::Res; use rustc_hir::def::Res;
use rustc_hir::HirIdMap; use rustc_hir::HirIdMap;
use rustc_hir::{ use rustc_hir::{
ArrayLen, BinOpKind, Block, BodyId, Closure, Expr, ExprField, ExprKind, FnRetTy, GenericArg, GenericArgs, Guard, ArrayLen, BinOpKind, BindingAnnotation, Block, BodyId, Closure, Expr, ExprField, ExprKind, FnRetTy, GenericArg,
HirId, InlineAsmOperand, Let, Lifetime, LifetimeName, ParamName, Pat, PatField, PatKind, Path, PathSegment, QPath, GenericArgs, Guard, HirId, InlineAsmOperand, Let, Lifetime, LifetimeName, ParamName, Pat, PatField, PatKind, Path,
Stmt, StmtKind, Ty, TyKind, TypeBinding, PathSegment, QPath, Stmt, StmtKind, Ty, TyKind, TypeBinding,
}; };
use rustc_lexer::{tokenize, TokenKind}; use rustc_lexer::{tokenize, TokenKind};
use rustc_lint::LateContext; use rustc_lint::LateContext;
@ -822,8 +822,9 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> {
pub fn hash_pat(&mut self, pat: &Pat<'_>) { pub fn hash_pat(&mut self, pat: &Pat<'_>) {
std::mem::discriminant(&pat.kind).hash(&mut self.s); std::mem::discriminant(&pat.kind).hash(&mut self.s);
match pat.kind { match pat.kind {
PatKind::Binding(ann, _, _, pat) => { PatKind::Binding(BindingAnnotation(by_ref, mutability), _, _, pat) => {
std::mem::discriminant(&ann).hash(&mut self.s); std::mem::discriminant(&by_ref).hash(&mut self.s);
std::mem::discriminant(&mutability).hash(&mut self.s);
if let Some(pat) = pat { if let Some(pat) = pat {
self.hash_pat(pat); self.hash_pat(pat);
} }

View file

@ -192,7 +192,7 @@ pub fn find_binding_init<'tcx>(cx: &LateContext<'tcx>, hir_id: HirId) -> Option<
let hir = cx.tcx.hir(); let hir = cx.tcx.hir();
if_chain! { if_chain! {
if let Some(Node::Pat(pat)) = hir.find(hir_id); if let Some(Node::Pat(pat)) = hir.find(hir_id);
if matches!(pat.kind, PatKind::Binding(BindingAnnotation::Unannotated, ..)); if matches!(pat.kind, PatKind::Binding(BindingAnnotation::NONE, ..));
let parent = hir.get_parent_node(hir_id); let parent = hir.get_parent_node(hir_id);
if let Some(Node::Local(local)) = hir.find(parent); if let Some(Node::Local(local)) = hir.find(parent);
then { then {

View file

@ -6,7 +6,7 @@ if_chain! {
if match_qpath(qpath, &["char"]); if match_qpath(qpath, &["char"]);
if let ExprKind::Lit(ref lit) = expr.kind; if let ExprKind::Lit(ref lit) = expr.kind;
if let LitKind::Int(69, LitIntType::Unsuffixed) = lit.node; if let LitKind::Int(69, LitIntType::Unsuffixed) = lit.node;
if let PatKind::Binding(BindingAnnotation::Unannotated, _, name, None) = local.pat.kind; if let PatKind::Binding(BindingAnnotation::NONE, _, name, None) = local.pat.kind;
if name.as_str() == "x"; if name.as_str() == "x";
then { then {
// report your lint here // report your lint here

View file

@ -5,13 +5,13 @@ if_chain! {
if let Some(init) = local.init; if let Some(init) = local.init;
if let ExprKind::Lit(ref lit) = init.kind; if let ExprKind::Lit(ref lit) = init.kind;
if let LitKind::Int(42, LitIntType::Signed(IntTy::I32)) = lit.node; if let LitKind::Int(42, LitIntType::Signed(IntTy::I32)) = lit.node;
if let PatKind::Binding(BindingAnnotation::Unannotated, _, name, None) = local.pat.kind; if let PatKind::Binding(BindingAnnotation::NONE, _, name, None) = local.pat.kind;
if name.as_str() == "x"; if name.as_str() == "x";
if let StmtKind::Local(local1) = block.stmts[1].kind; if let StmtKind::Local(local1) = block.stmts[1].kind;
if let Some(init1) = local1.init; if let Some(init1) = local1.init;
if let ExprKind::Lit(ref lit1) = init1.kind; if let ExprKind::Lit(ref lit1) = init1.kind;
if let LitKind::Float(_, LitFloatType::Suffixed(FloatTy::F32)) = lit1.node; if let LitKind::Float(_, LitFloatType::Suffixed(FloatTy::F32)) = lit1.node;
if let PatKind::Binding(BindingAnnotation::Unannotated, _, name1, None) = local1.pat.kind; if let PatKind::Binding(BindingAnnotation::NONE, _, name1, None) = local1.pat.kind;
if name1.as_str() == "_t"; if name1.as_str() == "_t";
if let StmtKind::Semi(e) = block.stmts[2].kind; if let StmtKind::Semi(e) = block.stmts[2].kind;
if let ExprKind::Unary(UnOp::Neg, inner) = e.kind; if let ExprKind::Unary(UnOp::Neg, inner) = e.kind;
@ -31,7 +31,7 @@ if_chain! {
if let ExprKind::Path(ref qpath) = func.kind; if let ExprKind::Path(ref qpath) = func.kind;
if match_qpath(qpath, &["String", "new"]); if match_qpath(qpath, &["String", "new"]);
if args.is_empty(); if args.is_empty();
if let PatKind::Binding(BindingAnnotation::Unannotated, _, name, None) = local.pat.kind; if let PatKind::Binding(BindingAnnotation::NONE, _, name, None) = local.pat.kind;
if name.as_str() == "expr"; if name.as_str() == "expr";
if let Some(trailing_expr) = block.expr; if let Some(trailing_expr) = block.expr;
if let ExprKind::Call(func1, args1) = trailing_expr.kind; if let ExprKind::Call(func1, args1) = trailing_expr.kind;

View file

@ -1,6 +1,6 @@
if_chain! { if_chain! {
if let Some(higher::ForLoop { pat: pat, arg: arg, body: body, .. }) = higher::ForLoop::hir(expr); if let Some(higher::ForLoop { pat: pat, arg: arg, body: body, .. }) = higher::ForLoop::hir(expr);
if let PatKind::Binding(BindingAnnotation::Unannotated, _, name, None) = pat.kind; if let PatKind::Binding(BindingAnnotation::NONE, _, name, None) = pat.kind;
if name.as_str() == "y"; if name.as_str() == "y";
if let ExprKind::Struct(qpath, fields, None) = arg.kind; if let ExprKind::Struct(qpath, fields, None) = arg.kind;
if matches!(qpath, QPath::LangItem(LangItem::Range, _)); if matches!(qpath, QPath::LangItem(LangItem::Range, _));
@ -17,7 +17,7 @@ if_chain! {
if let Some(init) = local.init; if let Some(init) = local.init;
if let ExprKind::Path(ref qpath1) = init.kind; if let ExprKind::Path(ref qpath1) = init.kind;
if match_qpath(qpath1, &["y"]); if match_qpath(qpath1, &["y"]);
if let PatKind::Binding(BindingAnnotation::Unannotated, _, name1, None) = local.pat.kind; if let PatKind::Binding(BindingAnnotation::NONE, _, name1, None) = local.pat.kind;
if name1.as_str() == "z"; if name1.as_str() == "z";
if block.expr.is_none(); if block.expr.is_none();
then { then {

View file

@ -21,7 +21,7 @@ if_chain! {
if let Some(init1) = local1.init; if let Some(init1) = local1.init;
if let ExprKind::Lit(ref lit4) = init1.kind; if let ExprKind::Lit(ref lit4) = init1.kind;
if let LitKind::Int(3, LitIntType::Unsuffixed) = lit4.node; if let LitKind::Int(3, LitIntType::Unsuffixed) = lit4.node;
if let PatKind::Binding(BindingAnnotation::Unannotated, _, name, None) = local1.pat.kind; if let PatKind::Binding(BindingAnnotation::NONE, _, name, None) = local1.pat.kind;
if name.as_str() == "x"; if name.as_str() == "x";
if let Some(trailing_expr) = block.expr; if let Some(trailing_expr) = block.expr;
if let ExprKind::Path(ref qpath) = trailing_expr.kind; if let ExprKind::Path(ref qpath) = trailing_expr.kind;
@ -30,7 +30,7 @@ if_chain! {
if arms[2].guard.is_none(); if arms[2].guard.is_none();
if let ExprKind::Lit(ref lit5) = arms[2].body.kind; if let ExprKind::Lit(ref lit5) = arms[2].body.kind;
if let LitKind::Int(1, LitIntType::Unsuffixed) = lit5.node; if let LitKind::Int(1, LitIntType::Unsuffixed) = lit5.node;
if let PatKind::Binding(BindingAnnotation::Unannotated, _, name1, None) = local.pat.kind; if let PatKind::Binding(BindingAnnotation::NONE, _, name1, None) = local.pat.kind;
if name1.as_str() == "a"; if name1.as_str() == "a";
then { then {
// report your lint here // report your lint here