adjust applicability and suggest making binding mutable
This commit is contained in:
parent
9058b040c8
commit
23ac72316d
3 changed files with 66 additions and 10 deletions
|
|
@ -1,6 +1,7 @@
|
|||
use clippy_utils::diagnostics::{span_lint, span_lint_and_sugg};
|
||||
use clippy_utils::diagnostics::{span_lint, span_lint_and_then};
|
||||
use clippy_utils::source::snippet;
|
||||
use clippy_utils::ty::implements_trait;
|
||||
use rustc_ast::{BindingAnnotation, Mutability};
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir as hir;
|
||||
use rustc_lint::LateContext;
|
||||
|
|
@ -8,6 +9,21 @@ use rustc_span::sym;
|
|||
|
||||
use super::FILTER_NEXT;
|
||||
|
||||
fn path_to_local(expr: &hir::Expr<'_>) -> Option<hir::HirId> {
|
||||
match expr.kind {
|
||||
hir::ExprKind::Field(f, _) => path_to_local(f),
|
||||
hir::ExprKind::Index(recv, _) => path_to_local(recv),
|
||||
hir::ExprKind::Path(hir::QPath::Resolved(
|
||||
_,
|
||||
hir::Path {
|
||||
res: rustc_hir::def::Res::Local(local),
|
||||
..
|
||||
},
|
||||
)) => Some(*local),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
/// lint use of `filter().next()` for `Iterators`
|
||||
pub(super) fn check<'tcx>(
|
||||
cx: &LateContext<'tcx>,
|
||||
|
|
@ -26,15 +42,30 @@ pub(super) fn check<'tcx>(
|
|||
if filter_snippet.lines().count() <= 1 {
|
||||
let iter_snippet = snippet(cx, recv.span, "..");
|
||||
// add note if not multi-line
|
||||
span_lint_and_sugg(
|
||||
cx,
|
||||
FILTER_NEXT,
|
||||
expr.span,
|
||||
msg,
|
||||
"try",
|
||||
format!("{iter_snippet}.find({filter_snippet})"),
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
span_lint_and_then(cx, FILTER_NEXT, expr.span, msg, |diag| {
|
||||
let (applicability, pat) = if let Some(id) = path_to_local(recv)
|
||||
&& let Some(hir::Node::Pat(pat)) = cx.tcx.hir().find(id)
|
||||
&& let hir::PatKind::Binding(BindingAnnotation(_, Mutability::Not), _, ident, _) = pat.kind
|
||||
{
|
||||
(Applicability::Unspecified, Some((pat.span, ident)))
|
||||
} else {
|
||||
(Applicability::MachineApplicable, None)
|
||||
};
|
||||
|
||||
diag.span_suggestion(
|
||||
expr.span,
|
||||
"try",
|
||||
format!("{iter_snippet}.find({filter_snippet})"),
|
||||
applicability,
|
||||
);
|
||||
|
||||
if let Some((pat_span, ident)) = pat {
|
||||
diag.span_help(
|
||||
pat_span,
|
||||
format!("you will also need to make `{ident}` mutable, because `find` takes `&mut self`"),
|
||||
);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
span_lint(cx, FILTER_NEXT, expr.span, msg);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue