1+ use crate :: methods:: MAP_WITH_UNUSED_ARGUMENT_OVER_RANGES ;
12use clippy_config:: msrvs:: { self , Msrv } ;
23use clippy_utils:: diagnostics:: span_lint_and_sugg;
34use clippy_utils:: higher;
@@ -7,47 +8,7 @@ use rustc_ast::LitKind;
78use rustc_data_structures:: packed:: Pu128 ;
89use rustc_errors:: Applicability ;
910use rustc_hir:: { Body , Closure , Expr , ExprKind , PatKind } ;
10- use rustc_lint:: { LateContext , LateLintPass } ;
11- use rustc_session:: impl_lint_pass;
12-
13- declare_clippy_lint ! {
14- /// ### What it does
15- ///
16- /// Checks for `Iterator::map` over ranges without using the parameter which
17- /// could be more clearly expressed using `std::iter::repeat_with(...).take(...)`.
18- ///
19- /// ### Why is this bad?
20- ///
21- /// It expresses the intent more clearly to `take` the correct number of times
22- /// from a generating function than to apply a closure to each number in a
23- /// range only to discard them.
24- ///
25- /// ### Example
26- /// ```no_run
27- /// let random_numbers : Vec<_> = (0..10).map(|_| { 3 + 1 }).collect();
28- /// ```
29- /// Use instead:
30- /// ```no_run
31- /// let f : Vec<_> = std::iter::repeat_with(|| { 3 + 1 }).take(10).collect();
32- /// ```
33- #[ clippy:: version = "1.81.0" ]
34- pub MAP_WITH_UNUSED_ARGUMENT_OVER_RANGES ,
35- style,
36- "map of a trivial closure (not dependent on parameter) over a range"
37- }
38-
39- pub struct MapWithUnusedArgumentOverRanges {
40- msrv : Msrv ,
41- }
42-
43- impl MapWithUnusedArgumentOverRanges {
44- #[ must_use]
45- pub fn new ( msrv : Msrv ) -> Self {
46- Self { msrv }
47- }
48- }
49-
50- impl_lint_pass ! ( MapWithUnusedArgumentOverRanges => [ MAP_WITH_UNUSED_ARGUMENT_OVER_RANGES ] ) ;
11+ use rustc_lint:: LateContext ;
5112
5213fn extract_count_with_applicability (
5314 cx : & LateContext < ' _ > ,
@@ -90,21 +51,22 @@ fn extract_count_with_applicability(
9051 None
9152}
9253
93- pub ( super ) fn check ( cx : & LateContext < ' _ > , ex : & Expr < ' _ > , recv : & Expr < ' _ > , arg : & Expr < ' _ > , msrv : & Msrv ) {
54+ pub ( super ) fn check ( cx : & LateContext < ' _ > , ex : & Expr < ' _ > , receiver : & Expr < ' _ > , arg : & Expr < ' _ > , msrv : & Msrv ) {
9455 if !msrv. meets ( msrvs:: REPEAT_WITH ) {
9556 return ;
9657 }
9758 let mut applicability = Applicability :: MaybeIncorrect ;
98- if let ExprKind :: MethodCall ( path, receiver, [ map_arg_expr] , _call_span) = ex. kind
99- && path. ident . name == rustc_span:: sym:: map
100- && let Some ( range) = higher:: Range :: hir ( receiver)
101- && let ExprKind :: Closure ( Closure { body, .. } ) = map_arg_expr. kind
59+ if let Some ( range) = higher:: Range :: hir ( receiver)
60+ && let ExprKind :: Closure ( Closure { body, .. } ) = arg. kind
10261 && let Body { params : [ param] , .. } = cx. tcx . hir ( ) . body ( * body)
62+ // TODO: We should also look for a named, but unused parameter here
10363 && matches ! ( param. pat. kind, PatKind :: Wild )
10464 && let Some ( count) = extract_count_with_applicability ( cx, range, & mut applicability)
10565 {
106- let snippet = snippet_with_applicability ( cx, map_arg_expr. span , "|| { ... }" , & mut applicability)
107- . replacen ( "|_|" , "||" , 1 ) ;
66+ // TODO: Check if we can switch_to_eager_eval here and do away with `repeat_with` and instad use
67+ // `repeat`
68+ let snippet =
69+ snippet_with_applicability ( cx, arg. span , "|| { ... }" , & mut applicability) . replacen ( "|_|" , "||" , 1 ) ;
10870 span_lint_and_sugg (
10971 cx,
11072 MAP_WITH_UNUSED_ARGUMENT_OVER_RANGES ,
0 commit comments