@@ -103,10 +103,8 @@ fn flatten_format_args(mut fmt: Cow<'_, FormatArgs>) -> Cow<'_, FormatArgs> {
103
103
///
104
104
/// `format_args!("Hello, World! {}", 123)`.
105
105
fn inline_literals ( mut fmt : Cow < ' _ , FormatArgs > ) -> Cow < ' _ , FormatArgs > {
106
- // None: Not sure yet.
107
- // Some(true): Remove, because it was inlined. (Might be set to false later if it is used in another way.)
108
- // Some(false): Do not remove, because some non-inlined placeholder uses it.
109
- let mut remove = vec ! [ None ; fmt. arguments. all_args( ) . len( ) ] ;
106
+ let mut was_inlined = vec ! [ false ; fmt. arguments. all_args( ) . len( ) ] ;
107
+ let mut inlined_anything = false ;
110
108
111
109
for i in 0 ..fmt. template . len ( ) {
112
110
let FormatArgsPiece :: Placeholder ( placeholder) = & fmt. template [ i] else { continue } ;
@@ -123,30 +121,34 @@ fn inline_literals(mut fmt: Cow<'_, FormatArgs>) -> Cow<'_, FormatArgs> {
123
121
let fmt = fmt. to_mut ( ) ;
124
122
// Replace the placeholder with the literal.
125
123
fmt. template [ i] = FormatArgsPiece :: Literal ( s) ;
126
- // Only remove it wasn't set to 'do not remove'.
127
- remove[ arg_index] . get_or_insert ( true ) ;
128
- } else {
129
- // Never remove an argument that's used by a non-inlined placeholder,
130
- // even if this argument is inlined in another place.
131
- remove[ arg_index] = Some ( false ) ;
124
+ was_inlined[ arg_index] = true ;
125
+ inlined_anything = true ;
132
126
}
133
127
}
134
128
135
129
// Remove the arguments that were inlined.
136
- if remove . iter ( ) . any ( | & x| x == Some ( true ) ) {
130
+ if inlined_anything {
137
131
let fmt = fmt. to_mut ( ) ;
132
+
133
+ let mut remove = was_inlined;
134
+
135
+ // Don't remove anything that's still used.
136
+ for_all_argument_indexes ( & mut fmt. template , |index| remove[ * index] = false ) ;
137
+
138
138
// Drop all the arguments that are marked for removal.
139
139
let mut remove_it = remove. iter ( ) ;
140
- fmt. arguments . all_args_mut ( ) . retain ( |_| remove_it. next ( ) != Some ( & Some ( true ) ) ) ;
140
+ fmt. arguments . all_args_mut ( ) . retain ( |_| remove_it. next ( ) != Some ( & true ) ) ;
141
+
141
142
// Calculate the mapping of old to new indexes for the remaining arguments.
142
143
let index_map: Vec < usize > = remove
143
144
. into_iter ( )
144
145
. scan ( 0 , |i, remove| {
145
146
let mapped = * i;
146
- * i += ( remove != Some ( true ) ) as usize ;
147
+ * i += !remove as usize ;
147
148
Some ( mapped)
148
149
} )
149
150
. collect ( ) ;
151
+
150
152
// Correct the indexes that refer to arguments that have shifted position.
151
153
for_all_argument_indexes ( & mut fmt. template , |index| * index = index_map[ * index] ) ;
152
154
}
0 commit comments