@@ -8,7 +8,7 @@ use arrayvec::ArrayVec;
8
8
use itertools:: { izip, Either , Itertools } ;
9
9
use rustc_ast:: ast:: LitKind ;
10
10
use rustc_hir:: intravisit:: Visitor ;
11
- use rustc_hir:: { self as hir, Expr , ExprKind , HirId , Node , QPath } ;
11
+ use rustc_hir:: { self as hir, Expr , ExprField , ExprKind , HirId , Node , QPath } ;
12
12
use rustc_lexer:: unescape:: unescape_literal;
13
13
use rustc_lexer:: { tokenize, unescape, LiteralKind , TokenKind } ;
14
14
use rustc_lint:: LateContext ;
@@ -485,64 +485,49 @@ struct ParamPosition {
485
485
precision : Option < usize > ,
486
486
}
487
487
488
- /// Parses the `fmt` arg of `Arguments::new_v1_formatted(pieces, args, fmt, _)`
489
- fn parse_rt_fmt < ' tcx > ( fmt_arg : & ' tcx Expr < ' tcx > ) -> Option < impl Iterator < Item = ParamPosition > + ' tcx > {
490
- fn parse_count ( expr : & Expr < ' _ > ) -> Option < usize > {
491
- // ::core::fmt::rt::v1::Count::Param(1usize),
492
- if let ExprKind :: Call ( ctor, [ val] ) = expr. kind
493
- && let ExprKind :: Path ( QPath :: Resolved ( _, path) ) = ctor. kind
494
- && path. segments . last ( ) ?. ident . name == sym:: Param
495
- && let ExprKind :: Lit ( lit) = & val. kind
496
- && let LitKind :: Int ( pos, _) = lit. node
497
- {
498
- Some ( pos as usize )
499
- } else {
500
- None
488
+ impl < ' tcx > Visitor < ' tcx > for ParamPosition {
489
+ fn visit_expr_field ( & mut self , field : & ' tcx ExprField < ' tcx > ) {
490
+ fn parse_count ( expr : & Expr < ' _ > ) -> Option < usize > {
491
+ // ::core::fmt::rt::v1::Count::Param(1usize),
492
+ if let ExprKind :: Call ( ctor, [ val] ) = expr. kind
493
+ && let ExprKind :: Path ( QPath :: Resolved ( _, path) ) = ctor. kind
494
+ && path. segments . last ( ) ?. ident . name == sym:: Param
495
+ && let ExprKind :: Lit ( lit) = & val. kind
496
+ && let LitKind :: Int ( pos, _) = lit. node
497
+ {
498
+ Some ( pos as usize )
499
+ } else {
500
+ None
501
+ }
502
+ }
503
+
504
+ match field. ident . name {
505
+ sym:: position => {
506
+ if let ExprKind :: Lit ( lit) = & field. expr . kind
507
+ && let LitKind :: Int ( pos, _) = lit. node
508
+ {
509
+ self . value = pos as usize ;
510
+ }
511
+ } ,
512
+ sym:: precision => {
513
+ self . precision = parse_count ( field. expr ) ;
514
+ } ,
515
+ sym:: width => {
516
+ self . width = parse_count ( field. expr ) ;
517
+ } ,
518
+ _ => { } ,
501
519
}
502
520
}
521
+ }
503
522
523
+ /// Parses the `fmt` arg of `Arguments::new_v1_formatted(pieces, args, fmt, _)`
524
+ fn parse_rt_fmt < ' tcx > ( fmt_arg : & ' tcx Expr < ' tcx > ) -> Option < impl Iterator < Item = ParamPosition > + ' tcx > {
504
525
if let ExprKind :: AddrOf ( .., array) = fmt_arg. kind
505
526
&& let ExprKind :: Array ( specs) = array. kind
506
527
{
507
528
Some ( specs. iter ( ) . map ( |spec| {
508
529
let mut position = ParamPosition :: default ( ) ;
509
-
510
- // ::core::fmt::rt::v1::Argument {
511
- // position: 0usize,
512
- // format: ::core::fmt::rt::v1::FormatSpec {
513
- // ..
514
- // precision: ::core::fmt::rt::v1::Count::Implied,
515
- // width: ::core::fmt::rt::v1::Count::Implied,
516
- // },
517
- // }
518
-
519
- // TODO: this can be made much nicer next sync with `Visitor::visit_expr_field`
520
- if let ExprKind :: Struct ( _, fields, _) = spec. kind {
521
- for field in fields {
522
- match ( field. ident . name , & field. expr . kind ) {
523
- ( sym:: position, ExprKind :: Lit ( lit) ) => {
524
- if let LitKind :: Int ( pos, _) = lit. node {
525
- position. value = pos as usize ;
526
- }
527
- } ,
528
- ( sym:: format, & ExprKind :: Struct ( _, spec_fields, _) ) => {
529
- for spec_field in spec_fields {
530
- match spec_field. ident . name {
531
- sym:: precision => {
532
- position. precision = parse_count ( spec_field. expr ) ;
533
- } ,
534
- sym:: width => {
535
- position. width = parse_count ( spec_field. expr ) ;
536
- } ,
537
- _ => { } ,
538
- }
539
- }
540
- } ,
541
- _ => { } ,
542
- }
543
- }
544
- }
545
-
530
+ position. visit_expr ( spec) ;
546
531
position
547
532
} ) )
548
533
} else {
0 commit comments