1
+ use crate :: methods:: MAP_WITH_UNUSED_ARGUMENT_OVER_RANGES ;
1
2
use clippy_config:: msrvs:: { self , Msrv } ;
2
3
use clippy_utils:: diagnostics:: span_lint_and_sugg;
3
4
use clippy_utils:: higher;
@@ -7,47 +8,7 @@ use rustc_ast::LitKind;
7
8
use rustc_data_structures:: packed:: Pu128 ;
8
9
use rustc_errors:: Applicability ;
9
10
use 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 ;
51
12
52
13
fn extract_count_with_applicability (
53
14
cx : & LateContext < ' _ > ,
@@ -90,21 +51,22 @@ fn extract_count_with_applicability(
90
51
None
91
52
}
92
53
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 ) {
94
55
if !msrv. meets ( msrvs:: REPEAT_WITH ) {
95
56
return ;
96
57
}
97
58
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
102
61
&& let Body { params : [ param] , .. } = cx. tcx . hir ( ) . body ( * body)
62
+ // TODO: We should also look for a named, but unused parameter here
103
63
&& matches ! ( param. pat. kind, PatKind :: Wild )
104
64
&& let Some ( count) = extract_count_with_applicability ( cx, range, & mut applicability)
105
65
{
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 ) ;
108
70
span_lint_and_sugg (
109
71
cx,
110
72
MAP_WITH_UNUSED_ARGUMENT_OVER_RANGES ,
0 commit comments