@@ -2,7 +2,7 @@ use crate::methods::MAP_WITH_UNUSED_ARGUMENT_OVER_RANGES;
22use clippy_config:: msrvs:: { self , Msrv } ;
33use clippy_utils:: diagnostics:: span_lint_and_then;
44use clippy_utils:: source:: snippet_with_applicability;
5- use clippy_utils:: usage;
5+ use clippy_utils:: { eager_or_lazy , higher , usage} ;
66use rustc_ast:: ast:: RangeLimits ;
77use rustc_ast:: LitKind ;
88use 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}
0 commit comments