1
- use clippy_utils:: diagnostics:: { span_lint_and_sugg , span_lint_and_then } ;
1
+ use clippy_utils:: diagnostics:: span_lint_hir_and_then ;
2
2
use clippy_utils:: higher:: VecArgs ;
3
3
use clippy_utils:: source:: { snippet_opt, snippet_with_applicability} ;
4
4
use clippy_utils:: ty:: get_type_diagnostic_name;
@@ -108,14 +108,20 @@ fn check_closure<'tcx>(cx: &LateContext<'tcx>, outer_receiver: Option<&Expr<'tcx
108
108
{
109
109
let vec_crate = if is_no_std_crate ( cx) { "alloc" } else { "std" } ;
110
110
// replace `|| vec![]` with `Vec::new`
111
- span_lint_and_sugg (
111
+ span_lint_hir_and_then (
112
112
cx,
113
113
REDUNDANT_CLOSURE ,
114
+ expr. hir_id ,
114
115
expr. span ,
115
116
"redundant closure" ,
116
- "replace the closure with `Vec::new`" ,
117
- format ! ( "{vec_crate}::vec::Vec::new" ) ,
118
- Applicability :: MachineApplicable ,
117
+ |diag| {
118
+ diag. span_suggestion (
119
+ expr. span ,
120
+ "replace the closure with `Vec::new`" ,
121
+ format ! ( "{vec_crate}::vec::Vec::new" ) ,
122
+ Applicability :: MachineApplicable ,
123
+ ) ;
124
+ } ,
119
125
) ;
120
126
}
121
127
// skip `foo(|| macro!())`
@@ -197,41 +203,48 @@ fn check_closure<'tcx>(cx: &LateContext<'tcx>, outer_receiver: Option<&Expr<'tcx
197
203
// For now ignore all callee types which reference a type parameter.
198
204
&& !generic_args. types ( ) . any ( |t| matches ! ( t. kind( ) , ty:: Param ( _) ) )
199
205
{
200
- span_lint_and_then ( cx, REDUNDANT_CLOSURE , expr. span , "redundant closure" , |diag| {
201
- if let Some ( mut snippet) = snippet_opt ( cx, callee. span ) {
202
- if path_to_local ( callee) . is_some_and ( |l| {
203
- // FIXME: Do we really need this `local_used_in` check?
204
- // Isn't it checking something like... `callee(callee)`?
205
- // If somehow this check is needed, add some test for it,
206
- // 'cuz currently nothing changes after deleting this check.
207
- local_used_in ( cx, l, args) || local_used_after_expr ( cx, l, expr)
208
- } ) {
209
- match cx
210
- . tcx
211
- . infer_ctxt ( )
212
- . build ( cx. typing_mode ( ) )
213
- . err_ctxt ( )
214
- . type_implements_fn_trait (
215
- cx. param_env ,
216
- Binder :: bind_with_vars ( callee_ty_adjusted, List :: empty ( ) ) ,
217
- ty:: PredicatePolarity :: Positive ,
218
- ) {
219
- // Mutable closure is used after current expr; we cannot consume it.
220
- Ok ( ( ClosureKind :: FnMut , _) ) => snippet = format ! ( "&mut {snippet}" ) ,
221
- Ok ( ( ClosureKind :: Fn , _) ) if !callee_ty_raw. is_ref ( ) => {
222
- snippet = format ! ( "&{snippet}" ) ;
223
- } ,
224
- _ => ( ) ,
206
+ span_lint_hir_and_then (
207
+ cx,
208
+ REDUNDANT_CLOSURE ,
209
+ expr. hir_id ,
210
+ expr. span ,
211
+ "redundant closure" ,
212
+ |diag| {
213
+ if let Some ( mut snippet) = snippet_opt ( cx, callee. span ) {
214
+ if path_to_local ( callee) . is_some_and ( |l| {
215
+ // FIXME: Do we really need this `local_used_in` check?
216
+ // Isn't it checking something like... `callee(callee)`?
217
+ // If somehow this check is needed, add some test for it,
218
+ // 'cuz currently nothing changes after deleting this check.
219
+ local_used_in ( cx, l, args) || local_used_after_expr ( cx, l, expr)
220
+ } ) {
221
+ match cx
222
+ . tcx
223
+ . infer_ctxt ( )
224
+ . build ( cx. typing_mode ( ) )
225
+ . err_ctxt ( )
226
+ . type_implements_fn_trait (
227
+ cx. param_env ,
228
+ Binder :: bind_with_vars ( callee_ty_adjusted, List :: empty ( ) ) ,
229
+ ty:: PredicatePolarity :: Positive ,
230
+ ) {
231
+ // Mutable closure is used after current expr; we cannot consume it.
232
+ Ok ( ( ClosureKind :: FnMut , _) ) => snippet = format ! ( "&mut {snippet}" ) ,
233
+ Ok ( ( ClosureKind :: Fn , _) ) if !callee_ty_raw. is_ref ( ) => {
234
+ snippet = format ! ( "&{snippet}" ) ;
235
+ } ,
236
+ _ => ( ) ,
237
+ }
225
238
}
239
+ diag. span_suggestion (
240
+ expr. span ,
241
+ "replace the closure with the function itself" ,
242
+ snippet,
243
+ Applicability :: MachineApplicable ,
244
+ ) ;
226
245
}
227
- diag. span_suggestion (
228
- expr. span ,
229
- "replace the closure with the function itself" ,
230
- snippet,
231
- Applicability :: MachineApplicable ,
232
- ) ;
233
- }
234
- } ) ;
246
+ } ,
247
+ ) ;
235
248
}
236
249
} ,
237
250
ExprKind :: MethodCall ( path, self_, args, _) if check_inputs ( typeck, body. params , Some ( self_) , args) => {
@@ -244,9 +257,10 @@ fn check_closure<'tcx>(cx: &LateContext<'tcx>, outer_receiver: Option<&Expr<'tcx
244
257
Some ( span) => format ! ( "::{}" , snippet_with_applicability( cx, span, "<..>" , & mut app) ) ,
245
258
None => String :: new ( ) ,
246
259
} ;
247
- span_lint_and_then (
260
+ span_lint_hir_and_then (
248
261
cx,
249
262
REDUNDANT_CLOSURE_FOR_METHOD_CALLS ,
263
+ expr. hir_id ,
250
264
expr. span ,
251
265
"redundant closure" ,
252
266
|diag| {
0 commit comments