]> git.lizzy.rs Git - rust.git/blob - src/tools/clippy/clippy_lints/src/methods/iter_with_drain.rs
Rollup merge of #101655 - dns2utf8:box_docs, r=dtolnay
[rust.git] / src / tools / clippy / clippy_lints / src / methods / iter_with_drain.rs
1 use clippy_utils::diagnostics::span_lint_and_sugg;
2 use clippy_utils::higher::Range;
3 use clippy_utils::is_integer_const;
4 use rustc_ast::ast::RangeLimits;
5 use rustc_errors::Applicability;
6 use rustc_hir::{Expr, ExprKind, QPath};
7 use rustc_lint::LateContext;
8 use rustc_span::symbol::sym;
9 use rustc_span::Span;
10
11 use super::ITER_WITH_DRAIN;
12
13 pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, recv: &Expr<'_>, span: Span, arg: &Expr<'_>) {
14     if !matches!(recv.kind, ExprKind::Field(..))
15         && let Some(adt) = cx.typeck_results().expr_ty(recv).ty_adt_def()
16         && let Some(ty_name) = cx.tcx.get_diagnostic_name(adt.did())
17         && matches!(ty_name, sym::Vec | sym::VecDeque)
18         && let Some(range) = Range::hir(arg)
19         && is_full_range(cx, recv, range)
20     {
21         span_lint_and_sugg(
22             cx,
23             ITER_WITH_DRAIN,
24             span.with_hi(expr.span.hi()),
25             &format!("`drain(..)` used on a `{ty_name}`"),
26             "try this",
27             "into_iter()".to_string(),
28             Applicability::MaybeIncorrect,
29         );
30     };
31 }
32
33 fn is_full_range(cx: &LateContext<'_>, container: &Expr<'_>, range: Range<'_>) -> bool {
34     range.start.map_or(true, |e| is_integer_const(cx, e, 0))
35         && range.end.map_or(true, |e| {
36             if range.limits == RangeLimits::HalfOpen
37                 && let ExprKind::Path(QPath::Resolved(None, container_path)) = container.kind
38                 && let ExprKind::MethodCall(name, self_arg, [], _) = e.kind
39                 && name.ident.name == sym::len
40                 && let ExprKind::Path(QPath::Resolved(None, path)) = self_arg.kind
41             {
42                 container_path.res == path.res
43             } else {
44                 false
45             }
46         })
47 }