@@ -103,10 +103,8 @@ fn flatten_format_args(mut fmt: Cow<'_, FormatArgs>) -> Cow<'_, FormatArgs> {
103103///
104104/// `format_args!("Hello, World! {}", 123)`.
105105fn 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 ;
110108
111109 for i in 0 ..fmt. template . len ( ) {
112110 let FormatArgsPiece :: Placeholder ( placeholder) = & fmt. template [ i] else { continue } ;
@@ -123,30 +121,34 @@ fn inline_literals(mut fmt: Cow<'_, FormatArgs>) -> Cow<'_, FormatArgs> {
123121 let fmt = fmt. to_mut ( ) ;
124122 // Replace the placeholder with the literal.
125123 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 ;
132126 }
133127 }
134128
135129 // Remove the arguments that were inlined.
136- if remove . iter ( ) . any ( | & x| x == Some ( true ) ) {
130+ if inlined_anything {
137131 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+
138138 // Drop all the arguments that are marked for removal.
139139 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+
141142 // Calculate the mapping of old to new indexes for the remaining arguments.
142143 let index_map: Vec < usize > = remove
143144 . into_iter ( )
144145 . scan ( 0 , |i, remove| {
145146 let mapped = * i;
146- * i += ( remove != Some ( true ) ) as usize ;
147+ * i += !remove as usize ;
147148 Some ( mapped)
148149 } )
149150 . collect ( ) ;
151+
150152 // Correct the indexes that refer to arguments that have shifted position.
151153 for_all_argument_indexes ( & mut fmt. template , |index| * index = index_map[ * index] ) ;
152154 }
0 commit comments