|
| 1 | +use clippy_utils::diagnostics::span_lint_and_sugg; |
| 2 | +use clippy_utils::msrvs::{self, Msrv}; |
| 3 | +use clippy_utils::source::{snippet, snippet_with_context}; |
| 4 | +use clippy_utils::{expr_use_ctxt, fn_def_id, is_trait_method, std_or_core}; |
| 5 | +use rustc_errors::Applicability; |
| 6 | +use rustc_hir::{Expr, ExprKind}; |
| 7 | +use rustc_lint::LateContext; |
| 8 | +use rustc_span::sym; |
| 9 | + |
| 10 | +use super::MANUAL_REPEAT_N; |
| 11 | + |
| 12 | +pub(super) fn check<'tcx>( |
| 13 | + cx: &LateContext<'tcx>, |
| 14 | + expr: &'tcx Expr<'tcx>, |
| 15 | + repeat_expr: &Expr<'_>, |
| 16 | + take_arg: &Expr<'_>, |
| 17 | + msrv: &Msrv, |
| 18 | +) { |
| 19 | + if msrv.meets(msrvs::REPEAT_N) |
| 20 | + && !expr.span.from_expansion() |
| 21 | + && is_trait_method(cx, expr, sym::Iterator) |
| 22 | + && let ExprKind::Call(_, [repeat_arg]) = repeat_expr.kind |
| 23 | + && let Some(def_id) = fn_def_id(cx, repeat_expr) |
| 24 | + && cx.tcx.is_diagnostic_item(sym::iter_repeat, def_id) |
| 25 | + && !expr_use_ctxt(cx, expr).is_ty_unified |
| 26 | + && let Some(std_or_core) = std_or_core(cx) |
| 27 | + { |
| 28 | + let mut app = Applicability::MachineApplicable; |
| 29 | + span_lint_and_sugg( |
| 30 | + cx, |
| 31 | + MANUAL_REPEAT_N, |
| 32 | + expr.span, |
| 33 | + "this `repeat().take()` can be written more concisely", |
| 34 | + "consider using `repeat_n()` instead", |
| 35 | + format!( |
| 36 | + "{std_or_core}::iter::repeat_n({}, {})", |
| 37 | + snippet_with_context(cx, repeat_arg.span, expr.span.ctxt(), "..", &mut app).0, |
| 38 | + snippet(cx, take_arg.span, "..") |
| 39 | + ), |
| 40 | + app, |
| 41 | + ); |
| 42 | + } |
| 43 | +} |
0 commit comments