Skip to content

Commit a3e6d8a

Browse files
committed
Add case for when we can just use repeat rather than repeat_with
1 parent 18fa70d commit a3e6d8a

File tree

3 files changed

+48
-27
lines changed

3 files changed

+48
-27
lines changed

clippy_lints/src/methods/map_with_unused_argument_over_ranges.rs

Lines changed: 44 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use crate::methods::MAP_WITH_UNUSED_ARGUMENT_OVER_RANGES;
22
use clippy_config::msrvs::{self, Msrv};
33
use clippy_utils::diagnostics::span_lint_and_then;
44
use clippy_utils::source::snippet_with_applicability;
5-
use clippy_utils::usage;
5+
use clippy_utils::{eager_or_lazy, higher, usage};
66
use rustc_ast::ast::RangeLimits;
77
use rustc_ast::LitKind;
88
use rustc_data_structures::packed::Pu128;
@@ -69,30 +69,52 @@ pub(super) fn check(
6969
}
7070
let mut applicability = Applicability::MaybeIncorrect;
7171
if let Some(range) = higher::Range::hir(receiver)
72-
&& let ExprKind::Closure(Closure { body, .. }) = arg.kind
72+
&& let ExprKind::Closure(Closure { body, fn_decl_span, .. }) = arg.kind
7373
&& let body_hir = cx.tcx.hir().body(*body)
74-
&& let Body { params: [param], .. } = body_hir
74+
&& let Body {
75+
params: [param],
76+
value: body_expr,
77+
} = body_hir
7578
&& !usage::BindingUsageFinder::are_params_used(cx, body_hir)
7679
&& let Some(count) = extract_count_with_applicability(cx, range, &mut applicability)
7780
{
78-
// TODO: Check if we can switch_to_eager_eval here and do away with `repeat_with` and instad use
79-
// `repeat`
80-
span_lint_and_then(
81-
cx,
82-
MAP_WITH_UNUSED_ARGUMENT_OVER_RANGES,
83-
ex.span,
84-
"map of a closure that does not depend on its parameter over a range",
85-
|diag| {
86-
diag.multipart_suggestion(
87-
"remove the explicit range and use `repeat_with` and `take`",
88-
vec![
89-
(receiver.span.to(method_call_span), "std::iter::repeat_with".to_owned()),
90-
(param.span, String::new()),
91-
(ex.span.shrink_to_hi(), format!(".take({count})")),
92-
],
93-
applicability,
94-
);
95-
},
96-
);
81+
if eager_or_lazy::switch_to_eager_eval(cx, body_expr) {
82+
let body_snippet = snippet_with_applicability(cx, body_expr.span, "..", &mut applicability);
83+
span_lint_and_then(
84+
cx,
85+
MAP_WITH_UNUSED_ARGUMENT_OVER_RANGES,
86+
ex.span,
87+
"map of a closure that does not depend on its parameter over a range",
88+
|diag| {
89+
diag.multipart_suggestion(
90+
"remove the explicit range and use `repeat` and `take`",
91+
vec![
92+
(receiver.span.to(method_call_span), "std::iter::repeat".to_owned()),
93+
(arg.span, body_snippet.to_string()),
94+
(ex.span.shrink_to_hi(), format!(".take({count})")),
95+
],
96+
applicability,
97+
);
98+
},
99+
);
100+
} else {
101+
span_lint_and_then(
102+
cx,
103+
MAP_WITH_UNUSED_ARGUMENT_OVER_RANGES,
104+
ex.span,
105+
"map of a closure that does not depend on its parameter over a range",
106+
|diag| {
107+
diag.multipart_suggestion(
108+
"remove the explicit range and use `repeat_with` and `take`",
109+
vec![
110+
(receiver.span.to(method_call_span), "std::iter::repeat_with".to_owned()),
111+
(param.span, String::new()),
112+
(ex.span.shrink_to_hi(), format!(".take({count})")),
113+
],
114+
applicability,
115+
);
116+
},
117+
);
118+
}
97119
}
98120
}

tests/ui/map_with_unused_argument_over_ranges.fixed

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ fn main() {
2222
std::iter::repeat_with(|| do_something()).take(11);
2323
std::iter::repeat_with(|| do_something()).take(7);
2424
std::iter::repeat_with(|| do_something()).take(8);
25-
std::iter::repeat_with(|| 3).take(10);
25+
std::iter::repeat(3).take(10);
2626
std::iter::repeat_with(|| {
2727
let x = 3;
2828
x + 2

tests/ui/map_with_unused_argument_over_ranges.stderr

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -66,11 +66,10 @@ error: map of a closure that does not depend on its parameter over a range
6666
LL | (0..10).map(|_| 3);
6767
| ^^^^^^^^^^^^^^^^^^
6868
|
69-
help: remove the explicit range and use `repeat_with` and `take`
70-
|
71-
LL - (0..10).map(|_| 3);
72-
LL + std::iter::repeat_with(|| 3).take(10);
69+
help: remove the explicit range and use `repeat` and `take`
7370
|
71+
LL | std::iter::repeat(3).take(10);
72+
| ~~~~~~~~~~~~~~~~~ ~ +++++++++
7473

7574
error: map of a closure that does not depend on its parameter over a range
7675
--> tests/ui/map_with_unused_argument_over_ranges.rs:26:5

0 commit comments

Comments
 (0)