@@ -68,33 +68,21 @@ fn flatten_format_args(mut fmt: Cow<'_, FormatArgs>) -> Cow<'_, FormatArgs> {
68
68
args. extend ( remaining_args) ;
69
69
70
70
// 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 {
76
73
* index -= old_arg_offset;
77
74
* index += new_arg_offset;
78
75
}
79
- }
76
+ } ) ;
80
77
81
78
// Now merge the placeholders:
82
79
83
80
let rest = fmt. template . split_off ( i + 1 ) ;
84
81
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 ) ;
98
86
fmt. template . extend ( rest) ;
99
87
100
88
// 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> {
150
138
// Drop all the arguments that are marked for removal.
151
139
let mut remove_it = remove. iter ( ) ;
152
140
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 ( ) ;
153
150
// 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] ) ;
163
152
}
164
153
165
154
fmt
@@ -572,3 +561,22 @@ fn may_contain_yield_point(e: &ast::Expr) -> bool {
572
561
visitor. visit_expr ( e) ;
573
562
visitor. 0
574
563
}
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