@@ -8,7 +8,7 @@ use arrayvec::ArrayVec;
88use itertools:: { izip, Either , Itertools } ;
99use rustc_ast:: ast:: LitKind ;
1010use 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 } ;
1212use rustc_lexer:: unescape:: unescape_literal;
1313use rustc_lexer:: { tokenize, unescape, LiteralKind , TokenKind } ;
1414use rustc_lint:: LateContext ;
@@ -485,64 +485,49 @@ struct ParamPosition {
485485 precision : Option < usize > ,
486486}
487487
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+ _ => { } ,
501519 }
502520 }
521+ }
503522
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 > {
504525 if let ExprKind :: AddrOf ( .., array) = fmt_arg. kind
505526 && let ExprKind :: Array ( specs) = array. kind
506527 {
507528 Some ( specs. iter ( ) . map ( |spec| {
508529 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) ;
546531 position
547532 } ) )
548533 } else {
0 commit comments