1
1
//! A group of attributes that can be attached to Rust code in order
2
2
//! to generate a clippy lint detecting said code automatically.
3
3
4
+ use clippy_utils:: macros:: { collect_format_args, is_format_macro, root_macro_call_first_node} ;
4
5
use clippy_utils:: { get_attr, higher} ;
5
6
use rustc_ast:: ast:: { LitFloatType , LitKind } ;
6
7
use rustc_ast:: LitIntType ;
@@ -239,14 +240,14 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> {
239
240
}
240
241
}
241
242
242
- fn slice < T > ( & self , slice : & Binding < & [ T ] > , f : impl Fn ( & Binding < & T > ) ) {
243
+ fn slice < T > ( & self , slice : & Binding < & [ T ] > , f : impl Fn ( Binding < & T > ) ) {
243
244
if slice. value . is_empty ( ) {
244
245
chain ! ( self , "{slice}.is_empty()" ) ;
245
246
} else {
246
247
chain ! ( self , "{slice}.len() == {}" , slice. value. len( ) ) ;
247
248
for ( i, value) in slice. value . iter ( ) . enumerate ( ) {
248
249
let name = format ! ( "{slice}[{i}]" ) ;
249
- f ( & Binding { name, value } ) ;
250
+ f ( Binding { name, value } ) ;
250
251
}
251
252
}
252
253
}
@@ -333,6 +334,24 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> {
333
334
334
335
#[ allow( clippy:: too_many_lines) ]
335
336
fn expr ( & self , expr : & Binding < & hir:: Expr < ' _ > > ) {
337
+ if let Some ( macro_call) = root_macro_call_first_node ( self . cx , expr. value )
338
+ && is_format_macro ( self . cx , macro_call. def_id )
339
+ {
340
+ let diag = self . cx . tcx . get_diagnostic_name ( macro_call. def_id ) . unwrap ( ) ;
341
+ bind ! ( self , macro_call) ;
342
+ chain ! ( self , "let Some({macro_call}) = macros::root_macro_call_first_node(cx, {expr})" ) ;
343
+ chain ! ( self , "cx.tcx.is_diagnostic_item(sym::{diag}, {macro_call}.def_id)" ) ;
344
+ let exprs = collect_format_args ( self . cx , expr. value , macro_call. value . expn ) ;
345
+ let args = exprs. as_slice ( ) ;
346
+ bind ! ( self , args) ;
347
+ chain ! ( self , "let {args} = macros::collect_format_args(cx, {expr}, {macro_call}.expn)" ) ;
348
+ self . slice ( args, |e| {
349
+ let expr = Binding { name : e. name , value : * e. value } ;
350
+ self . expr ( & expr) ;
351
+ } ) ;
352
+ return ;
353
+ }
354
+
336
355
if let Some ( higher:: While { condition, body } ) = higher:: While :: hir ( expr. value ) {
337
356
bind ! ( self , condition, body) ;
338
357
chain ! (
@@ -398,25 +417,25 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> {
398
417
ExprKind :: Array ( elements) => {
399
418
bind ! ( self , elements) ;
400
419
kind ! ( "Array({elements})" ) ;
401
- self . slice ( elements, |e| self . expr ( e) ) ;
420
+ self . slice ( elements, |e| self . expr ( & e) ) ;
402
421
} ,
403
422
ExprKind :: Call ( func, args) => {
404
423
bind ! ( self , func, args) ;
405
424
kind ! ( "Call({func}, {args})" ) ;
406
425
self . expr ( func) ;
407
- self . slice ( args, |e| self . expr ( e) ) ;
426
+ self . slice ( args, |e| self . expr ( & e) ) ;
408
427
} ,
409
428
ExprKind :: MethodCall ( method_name, receiver, args, _) => {
410
429
bind ! ( self , method_name, receiver, args) ;
411
430
kind ! ( "MethodCall({method_name}, {receiver}, {args}, _)" ) ;
412
431
self . ident ( field ! ( method_name. ident) ) ;
413
432
self . expr ( receiver) ;
414
- self . slice ( args, |e| self . expr ( e) ) ;
433
+ self . slice ( args, |e| self . expr ( & e) ) ;
415
434
} ,
416
435
ExprKind :: Tup ( elements) => {
417
436
bind ! ( self , elements) ;
418
437
kind ! ( "Tup({elements})" ) ;
419
- self . slice ( elements, |e| self . expr ( e) ) ;
438
+ self . slice ( elements, |e| self . expr ( & e) ) ;
420
439
} ,
421
440
ExprKind :: Binary ( op, left, right) => {
422
441
bind ! ( self , op, left, right) ;
@@ -469,7 +488,7 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> {
469
488
bind ! ( self , scrutinee, arms) ;
470
489
kind ! ( "Match({scrutinee}, {arms}, MatchSource::{des:?})" ) ;
471
490
self . expr ( scrutinee) ;
472
- self . slice ( arms, |arm| self . arm ( arm) ) ;
491
+ self . slice ( arms, |arm| self . arm ( & arm) ) ;
473
492
} ,
474
493
ExprKind :: Closure ( & Closure {
475
494
capture_clause,
@@ -593,7 +612,7 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> {
593
612
}
594
613
595
614
fn block ( & self , block : & Binding < & hir:: Block < ' _ > > ) {
596
- self . slice ( field ! ( block. stmts) , |stmt| self . stmt ( stmt) ) ;
615
+ self . slice ( field ! ( block. stmts) , |stmt| self . stmt ( & stmt) ) ;
597
616
self . option ( field ! ( block. expr) , "trailing_expr" , |expr| {
598
617
self . expr ( expr) ;
599
618
} ) ;
@@ -639,13 +658,13 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> {
639
658
PatKind :: Or ( fields) => {
640
659
bind ! ( self , fields) ;
641
660
kind ! ( "Or({fields})" ) ;
642
- self . slice ( fields, |pat| self . pat ( pat) ) ;
661
+ self . slice ( fields, |pat| self . pat ( & pat) ) ;
643
662
} ,
644
663
PatKind :: TupleStruct ( ref qpath, fields, skip_pos) => {
645
664
bind ! ( self , qpath, fields) ;
646
665
kind ! ( "TupleStruct(ref {qpath}, {fields}, {skip_pos:?})" ) ;
647
666
self . qpath ( qpath) ;
648
- self . slice ( fields, |pat| self . pat ( pat) ) ;
667
+ self . slice ( fields, |pat| self . pat ( & pat) ) ;
649
668
} ,
650
669
PatKind :: Path ( ref qpath) => {
651
670
bind ! ( self , qpath) ;
@@ -655,7 +674,7 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> {
655
674
PatKind :: Tuple ( fields, skip_pos) => {
656
675
bind ! ( self , fields) ;
657
676
kind ! ( "Tuple({fields}, {skip_pos:?})" ) ;
658
- self . slice ( fields, |field| self . pat ( field) ) ;
677
+ self . slice ( fields, |field| self . pat ( & field) ) ;
659
678
} ,
660
679
PatKind :: Box ( pat) => {
661
680
bind ! ( self , pat) ;
@@ -683,8 +702,8 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> {
683
702
opt_bind ! ( self , middle) ;
684
703
kind ! ( "Slice({start}, {middle}, {end})" ) ;
685
704
middle. if_some ( |p| self . pat ( p) ) ;
686
- self . slice ( start, |pat| self . pat ( pat) ) ;
687
- self . slice ( end, |pat| self . pat ( pat) ) ;
705
+ self . slice ( start, |pat| self . pat ( & pat) ) ;
706
+ self . slice ( end, |pat| self . pat ( & pat) ) ;
688
707
} ,
689
708
}
690
709
}
0 commit comments