@@ -68,33 +68,21 @@ fn flatten_format_args(mut fmt: Cow<'_, FormatArgs>) -> Cow<'_, FormatArgs> {
6868 args. extend ( remaining_args) ;
6969
7070 // Correct the indexes that refer to the arguments after the newly inserted arguments.
71- for piece in & mut fmt. template {
72- if let FormatArgsPiece :: Placeholder ( placeholder) = piece
73- && let Ok ( index) = & mut placeholder. argument . index
74- && * index >= old_arg_offset
75- {
71+ for_all_argument_indexes ( & mut fmt. template , |index| {
72+ if * index >= old_arg_offset {
7673 * index -= old_arg_offset;
7774 * index += new_arg_offset;
7875 }
79- }
76+ } ) ;
8077
8178 // Now merge the placeholders:
8279
8380 let rest = fmt. template . split_off ( i + 1 ) ;
8481 fmt. template . pop ( ) ; // remove the placeholder for the nested fmt args.
85-
86- for piece in fmt2. template . drain ( ..) {
87- match piece {
88- FormatArgsPiece :: Literal ( s) => fmt. template . push ( FormatArgsPiece :: Literal ( s) ) ,
89- FormatArgsPiece :: Placeholder ( mut p) => {
90- // Correct the index to refer to the right place into the outer argument list.
91- if let Ok ( n) = & mut p. argument . index {
92- * n += arg_index;
93- }
94- fmt. template . push ( FormatArgsPiece :: Placeholder ( p) ) ;
95- }
96- }
97- }
82+ // Insert the pieces from the nested format args, but correct any
83+ // placeholders to point to the correct argument index.
84+ for_all_argument_indexes ( & mut fmt2. template , |index| * index += arg_index) ;
85+ fmt. template . append ( & mut fmt2. template ) ;
9886 fmt. template . extend ( rest) ;
9987
10088 // Don't increment `i` here, so we recurse into the newly added pieces.
@@ -150,16 +138,17 @@ fn inline_literals(mut fmt: Cow<'_, FormatArgs>) -> Cow<'_, FormatArgs> {
150138 // Drop all the arguments that are marked for removal.
151139 let mut remove_it = remove. iter ( ) ;
152140 fmt. arguments . all_args_mut ( ) . retain ( |_| remove_it. next ( ) != Some ( & Some ( true ) ) ) ;
141+ // Calculate the mapping of old to new indexes for the remaining arguments.
142+ let index_map: Vec < usize > = remove
143+ . into_iter ( )
144+ . scan ( 0 , |i, remove| {
145+ let mapped = * i;
146+ * i += ( remove != Some ( true ) ) as usize ;
147+ Some ( mapped)
148+ } )
149+ . collect ( ) ;
153150 // Correct the indexes that refer to arguments that have shifted position.
154- for piece in & mut fmt. template {
155- let FormatArgsPiece :: Placeholder ( placeholder) = piece else { continue } ;
156- let Ok ( arg_index) = & mut placeholder. argument . index else { continue } ;
157- for i in 0 ..* arg_index {
158- if remove[ i] == Some ( true ) {
159- * arg_index -= 1 ;
160- }
161- }
162- }
151+ for_all_argument_indexes ( & mut fmt. template , |index| * index = index_map[ * index] ) ;
163152 }
164153
165154 fmt
@@ -572,3 +561,22 @@ fn may_contain_yield_point(e: &ast::Expr) -> bool {
572561 visitor. visit_expr ( e) ;
573562 visitor. 0
574563}
564+
565+ fn for_all_argument_indexes ( template : & mut [ FormatArgsPiece ] , mut f : impl FnMut ( & mut usize ) ) {
566+ for piece in template {
567+ let FormatArgsPiece :: Placeholder ( placeholder) = piece else { continue } ;
568+ if let Ok ( index) = & mut placeholder. argument . index {
569+ f ( index) ;
570+ }
571+ if let Some ( FormatCount :: Argument ( FormatArgPosition { index : Ok ( index) , .. } ) ) =
572+ & mut placeholder. format_options . width
573+ {
574+ f ( index) ;
575+ }
576+ if let Some ( FormatCount :: Argument ( FormatArgPosition { index : Ok ( index) , .. } ) ) =
577+ & mut placeholder. format_options . precision
578+ {
579+ f ( index) ;
580+ }
581+ }
582+ }
0 commit comments