@@ -251,145 +251,48 @@ impl<'a> Formatter<'a> {
251251 }
252252}
253253
254- // NB. Argument is essentially an optimized partially applied formatting function,
255- // equivalent to `exists T.(&T, fn(&T, &mut Formatter<'_>) -> Result`.
256-
257- extern "C" {
258- type Opaque ;
259- }
260-
261- /// This struct represents the generic "argument" which is taken by the Xprintf
262- /// family of functions. It contains a function to format the given value. At
263- /// compile time it is ensured that the function and the value have the correct
264- /// types, and then this struct is used to canonicalize arguments to one type.
265- #[ lang = "format_argument" ]
254+ /// This structure represents a safely precompiled version of a format string
255+ /// and its arguments. This cannot be generated at runtime because it cannot
256+ /// safely be done, so no constructors are given and the fields are private
257+ /// to prevent modification.
258+ ///
259+ /// The [`format_args!`] macro will safely create an instance of this structure.
260+ /// The macro validates the format string at compile-time so usage of the
261+ /// [`write()`] and [`format()`] functions can be safely performed.
262+ ///
263+ /// You can use the `Arguments<'a>` that [`format_args!`] returns in `Debug`
264+ /// and `Display` contexts as seen below. The example also shows that `Debug`
265+ /// and `Display` format to the same thing: the interpolated format string
266+ /// in `format_args!`.
267+ ///
268+ /// ```rust
269+ /// let debug = format!("{:?}", format_args!("{} foo {:?}", 1, 2));
270+ /// let display = format!("{}", format_args!("{} foo {:?}", 1, 2));
271+ /// assert_eq!("1 foo 2", display);
272+ /// assert_eq!(display, debug);
273+ /// ```
274+ ///
275+ /// [`format()`]: ../../std/fmt/fn.format.html
276+ #[ lang = "format_arguments" ]
277+ #[ stable( feature = "rust1" , since = "1.0.0" ) ]
266278#[ derive( Copy , Clone ) ]
267- #[ allow( missing_debug_implementations) ]
268- #[ unstable( feature = "fmt_internals" , reason = "internal to format_args!" , issue = "none" ) ]
269- #[ doc( hidden) ]
270- pub struct Argument < ' a > {
271- value : & ' a Opaque ,
272- formatter : fn ( & Opaque , & mut Formatter < ' _ > ) -> Result ,
273- }
274-
275- /// This struct represents the unsafety of constructing an `Arguments`.
276- /// It exists, rather than an unsafe function, in order to simplify the expansion
277- /// of `format_args!(..)` and reduce the scope of the `unsafe` block.
278- #[ lang = "format_unsafe_arg" ]
279- #[ allow( missing_debug_implementations) ]
280- #[ doc( hidden) ]
281- #[ unstable( feature = "fmt_internals" , reason = "internal to format_args!" , issue = "none" ) ]
282- pub struct UnsafeArg {
283- _private : ( ) ,
284- }
285-
286- impl UnsafeArg {
287- /// See documentation where `UnsafeArg` is required to know when it is safe to
288- /// create and use `UnsafeArg`.
289- #[ doc( hidden) ]
290- #[ unstable( feature = "fmt_internals" , reason = "internal to format_args!" , issue = "none" ) ]
291- #[ inline( always) ]
292- pub unsafe fn new ( ) -> Self {
293- Self { _private : ( ) }
294- }
295- }
296-
297- // This guarantees a single stable value for the function pointer associated with
298- // indices/counts in the formatting infrastructure.
299- //
300- // Note that a function defined as such would not be correct as functions are
301- // always tagged unnamed_addr with the current lowering to LLVM IR, so their
302- // address is not considered important to LLVM and as such the as_usize cast
303- // could have been miscompiled. In practice, we never call as_usize on non-usize
304- // containing data (as a matter of static generation of the formatting
305- // arguments), so this is merely an additional check.
306- //
307- // We primarily want to ensure that the function pointer at `USIZE_MARKER` has
308- // an address corresponding *only* to functions that also take `&usize` as their
309- // first argument. The read_volatile here ensures that we can safely ready out a
310- // usize from the passed reference and that this address does not point at a
311- // non-usize taking function.
312- #[ unstable( feature = "fmt_internals" , reason = "internal to format_args!" , issue = "none" ) ]
313- static USIZE_MARKER : fn ( & usize , & mut Formatter < ' _ > ) -> Result = |ptr, _| {
314- // SAFETY: ptr is a reference
315- let _v: usize = unsafe { crate :: ptr:: read_volatile ( ptr) } ;
316- loop { }
317- } ;
318-
319- macro_rules! arg_new {
320- ( $f: ident, $t: ident) => {
321- #[ doc( hidden) ]
322- #[ unstable( feature = "fmt_internals" , reason = "internal to format_args!" , issue = "none" ) ]
323- #[ inline]
324- pub fn $f<' b, T : $t>( x: & ' b T ) -> Argument <' _> {
325- Self :: new( x, $t:: fmt)
326- }
327- } ;
328- }
329-
330- #[ rustc_diagnostic_item = "ArgumentMethods" ]
331- impl < ' a > Argument < ' a > {
332- #[ doc( hidden) ]
333- #[ unstable( feature = "fmt_internals" , reason = "internal to format_args!" , issue = "none" ) ]
334- #[ inline]
335- pub fn new < ' b , T > ( x : & ' b T , f : fn ( & T , & mut Formatter < ' _ > ) -> Result ) -> Argument < ' b > {
336- // SAFETY: `mem::transmute(x)` is safe because
337- // 1. `&'b T` keeps the lifetime it originated with `'b`
338- // (so as to not have an unbounded lifetime)
339- // 2. `&'b T` and `&'b Opaque` have the same memory layout
340- // (when `T` is `Sized`, as it is here)
341- // `mem::transmute(f)` is safe since `fn(&T, &mut Formatter<'_>) -> Result`
342- // and `fn(&Opaque, &mut Formatter<'_>) -> Result` have the same ABI
343- // (as long as `T` is `Sized`)
344- unsafe { Argument { formatter : mem:: transmute ( f) , value : mem:: transmute ( x) } }
345- }
346-
347- arg_new ! ( new_display, Display ) ;
348- arg_new ! ( new_debug, Debug ) ;
349- arg_new ! ( new_octal, Octal ) ;
350- arg_new ! ( new_lower_hex, LowerHex ) ;
351- arg_new ! ( new_upper_hex, UpperHex ) ;
352- arg_new ! ( new_pointer, Pointer ) ;
353- arg_new ! ( new_binary, Binary ) ;
354- arg_new ! ( new_lower_exp, LowerExp ) ;
355- arg_new ! ( new_upper_exp, UpperExp ) ;
279+ pub struct Arguments < ' a > {
280+ // Format string pieces to print.
281+ pieces : & ' a [ & ' static str ] ,
356282
357- #[ doc( hidden) ]
358- #[ unstable( feature = "fmt_internals" , reason = "internal to format_args!" , issue = "none" ) ]
359- pub fn from_usize ( x : & usize ) -> Argument < ' _ > {
360- Argument :: new ( x, USIZE_MARKER )
361- }
362-
363- fn as_usize ( & self ) -> Option < usize > {
364- // We are type punning a bit here: USIZE_MARKER only takes an &usize but
365- // formatter takes an &Opaque. Rust understandably doesn't think we should compare
366- // the function pointers if they don't have the same signature, so we cast to
367- // usizes to tell it that we just want to compare addresses.
368- if self . formatter as usize == USIZE_MARKER as usize {
369- // SAFETY: The `formatter` field is only set to USIZE_MARKER if
370- // the value is a usize, so this is safe
371- Some ( unsafe { * ( self . value as * const _ as * const usize ) } )
372- } else {
373- None
374- }
375- }
376- }
283+ // Placeholder specs, or `None` if all specs are default (as in "{}{}").
284+ fmt : Option < & ' a [ rt:: Placeholder ] > ,
377285
378- // flags available in the v1 format of format_args
379- #[ derive( Copy , Clone ) ]
380- enum Flag {
381- SignPlus ,
382- SignMinus ,
383- Alternate ,
384- SignAwareZeroPad ,
385- DebugLowerHex ,
386- DebugUpperHex ,
286+ // Dynamic arguments for interpolation, to be interleaved with string
287+ // pieces. (Every argument is preceded by a string piece.)
288+ args : & ' a [ rt:: Argument < ' a > ] ,
387289}
388290
291+ /// Used by the format_args!() macro to create a fmt::Arguments object.
292+ #[ doc( hidden) ]
293+ #[ unstable( feature = "fmt_internals" , issue = "none" ) ]
389294impl < ' a > Arguments < ' a > {
390- #[ doc( hidden) ]
391295 #[ inline]
392- #[ unstable( feature = "fmt_internals" , issue = "none" ) ]
393296 #[ rustc_const_unstable( feature = "const_fmt_arguments_new" , issue = "none" ) ]
394297 pub const fn new_const ( pieces : & ' a [ & ' static str ] ) -> Self {
395298 if pieces. len ( ) > 1 {
@@ -401,22 +304,18 @@ impl<'a> Arguments<'a> {
401304 /// When using the format_args!() macro, this function is used to generate the
402305 /// Arguments structure.
403306 #[ cfg( not( bootstrap) ) ]
404- #[ doc( hidden) ]
405307 #[ inline]
406- #[ unstable( feature = "fmt_internals" , reason = "internal to format_args!" , issue = "none" ) ]
407- pub fn new_v1 ( pieces : & ' a [ & ' static str ] , args : & ' a [ Argument < ' a > ] ) -> Arguments < ' a > {
308+ pub fn new_v1 ( pieces : & ' a [ & ' static str ] , args : & ' a [ rt:: Argument < ' a > ] ) -> Arguments < ' a > {
408309 if pieces. len ( ) < args. len ( ) || pieces. len ( ) > args. len ( ) + 1 {
409310 panic ! ( "invalid args" ) ;
410311 }
411312 Arguments { pieces, fmt : None , args }
412313 }
413314
414315 #[ cfg( bootstrap) ]
415- #[ doc( hidden) ]
416316 #[ inline]
417- #[ unstable( feature = "fmt_internals" , reason = "internal to format_args!" , issue = "none" ) ]
418317 #[ rustc_const_unstable( feature = "const_fmt_arguments_new" , issue = "none" ) ]
419- pub const fn new_v1 ( pieces : & ' a [ & ' static str ] , args : & ' a [ Argument < ' a > ] ) -> Arguments < ' a > {
318+ pub const fn new_v1 ( pieces : & ' a [ & ' static str ] , args : & ' a [ rt :: Argument < ' a > ] ) -> Arguments < ' a > {
420319 if pieces. len ( ) < args. len ( ) || pieces. len ( ) > args. len ( ) + 1 {
421320 panic ! ( "invalid args" ) ;
422321 }
@@ -425,19 +324,17 @@ impl<'a> Arguments<'a> {
425324
426325 /// This function is used to specify nonstandard formatting parameters.
427326 ///
428- /// An `UnsafeArg` is required because the following invariants must be held
327+ /// An `rt:: UnsafeArg` is required because the following invariants must be held
429328 /// in order for this function to be safe:
430329 /// 1. The `pieces` slice must be at least as long as `fmt`.
431330 /// 2. Every `rt::Placeholder::position` value within `fmt` must be a valid index of `args`.
432331 /// 3. Every `rt::Count::Param` within `fmt` must contain a valid index of `args`.
433- #[ doc( hidden) ]
434332 #[ inline]
435- #[ unstable( feature = "fmt_internals" , reason = "internal to format_args!" , issue = "none" ) ]
436333 pub fn new_v1_formatted (
437334 pieces : & ' a [ & ' static str ] ,
438- args : & ' a [ Argument < ' a > ] ,
335+ args : & ' a [ rt :: Argument < ' a > ] ,
439336 fmt : & ' a [ rt:: Placeholder ] ,
440- _unsafe_arg : UnsafeArg ,
337+ _unsafe_arg : rt :: UnsafeArg ,
441338 ) -> Arguments < ' a > {
442339 Arguments { pieces, fmt : Some ( fmt) , args }
443340 }
@@ -446,9 +343,7 @@ impl<'a> Arguments<'a> {
446343 ///
447344 /// This is intended to be used for setting initial `String` capacity
448345 /// when using `format!`. Note: this is neither the lower nor upper bound.
449- #[ doc( hidden) ]
450346 #[ inline]
451- #[ unstable( feature = "fmt_internals" , reason = "internal to format_args!" , issue = "none" ) ]
452347 pub fn estimated_capacity ( & self ) -> usize {
453348 let pieces_length: usize = self . pieces . iter ( ) . map ( |x| x. len ( ) ) . sum ( ) ;
454349
@@ -468,43 +363,6 @@ impl<'a> Arguments<'a> {
468363 }
469364}
470365
471- /// This structure represents a safely precompiled version of a format string
472- /// and its arguments. This cannot be generated at runtime because it cannot
473- /// safely be done, so no constructors are given and the fields are private
474- /// to prevent modification.
475- ///
476- /// The [`format_args!`] macro will safely create an instance of this structure.
477- /// The macro validates the format string at compile-time so usage of the
478- /// [`write()`] and [`format()`] functions can be safely performed.
479- ///
480- /// You can use the `Arguments<'a>` that [`format_args!`] returns in `Debug`
481- /// and `Display` contexts as seen below. The example also shows that `Debug`
482- /// and `Display` format to the same thing: the interpolated format string
483- /// in `format_args!`.
484- ///
485- /// ```rust
486- /// let debug = format!("{:?}", format_args!("{} foo {:?}", 1, 2));
487- /// let display = format!("{}", format_args!("{} foo {:?}", 1, 2));
488- /// assert_eq!("1 foo 2", display);
489- /// assert_eq!(display, debug);
490- /// ```
491- ///
492- /// [`format()`]: ../../std/fmt/fn.format.html
493- #[ lang = "format_arguments" ]
494- #[ stable( feature = "rust1" , since = "1.0.0" ) ]
495- #[ derive( Copy , Clone ) ]
496- pub struct Arguments < ' a > {
497- // Format string pieces to print.
498- pieces : & ' a [ & ' static str ] ,
499-
500- // Placeholder specs, or `None` if all specs are default (as in "{}{}").
501- fmt : Option < & ' a [ rt:: Placeholder ] > ,
502-
503- // Dynamic arguments for interpolation, to be interleaved with string
504- // pieces. (Every argument is preceded by a string piece.)
505- args : & ' a [ Argument < ' a > ] ,
506- }
507-
508366impl < ' a > Arguments < ' a > {
509367 /// Get the formatted string, if it has no arguments to be formatted at runtime.
510368 ///
@@ -1244,7 +1102,7 @@ pub fn write(output: &mut dyn Write, args: Arguments<'_>) -> Result {
12441102 if !piece. is_empty ( ) {
12451103 formatter. buf . write_str ( * piece) ?;
12461104 }
1247- ( arg. formatter ) ( arg . value , & mut formatter) ?;
1105+ arg. fmt ( & mut formatter) ?;
12481106 idx += 1 ;
12491107 }
12501108 }
@@ -1274,7 +1132,7 @@ pub fn write(output: &mut dyn Write, args: Arguments<'_>) -> Result {
12741132 Ok ( ( ) )
12751133}
12761134
1277- unsafe fn run ( fmt : & mut Formatter < ' _ > , arg : & rt:: Placeholder , args : & [ Argument < ' _ > ] ) -> Result {
1135+ unsafe fn run ( fmt : & mut Formatter < ' _ > , arg : & rt:: Placeholder , args : & [ rt :: Argument < ' _ > ] ) -> Result {
12781136 fmt. fill = arg. fill ;
12791137 fmt. align = arg. align ;
12801138 fmt. flags = arg. flags ;
@@ -1292,10 +1150,10 @@ unsafe fn run(fmt: &mut Formatter<'_>, arg: &rt::Placeholder, args: &[Argument<'
12921150 let value = unsafe { args. get_unchecked ( arg. position ) } ;
12931151
12941152 // Then actually do some printing
1295- ( value. formatter ) ( value . value , fmt)
1153+ value. fmt ( fmt)
12961154}
12971155
1298- unsafe fn getcount ( args : & [ Argument < ' _ > ] , cnt : & rt:: Count ) -> Option < usize > {
1156+ unsafe fn getcount ( args : & [ rt :: Argument < ' _ > ] , cnt : & rt:: Count ) -> Option < usize > {
12991157 match * cnt {
13001158 rt:: Count :: Is ( n) => Some ( n) ,
13011159 rt:: Count :: Implied => None ,
@@ -1878,7 +1736,7 @@ impl<'a> Formatter<'a> {
18781736 #[ must_use]
18791737 #[ stable( feature = "fmt_flags" , since = "1.5.0" ) ]
18801738 pub fn sign_plus ( & self ) -> bool {
1881- self . flags & ( 1 << Flag :: SignPlus as u32 ) != 0
1739+ self . flags & ( 1 << rt :: Flag :: SignPlus as u32 ) != 0
18821740 }
18831741
18841742 /// Determines if the `-` flag was specified.
@@ -1907,7 +1765,7 @@ impl<'a> Formatter<'a> {
19071765 #[ must_use]
19081766 #[ stable( feature = "fmt_flags" , since = "1.5.0" ) ]
19091767 pub fn sign_minus ( & self ) -> bool {
1910- self . flags & ( 1 << Flag :: SignMinus as u32 ) != 0
1768+ self . flags & ( 1 << rt :: Flag :: SignMinus as u32 ) != 0
19111769 }
19121770
19131771 /// Determines if the `#` flag was specified.
@@ -1935,7 +1793,7 @@ impl<'a> Formatter<'a> {
19351793 #[ must_use]
19361794 #[ stable( feature = "fmt_flags" , since = "1.5.0" ) ]
19371795 pub fn alternate ( & self ) -> bool {
1938- self . flags & ( 1 << Flag :: Alternate as u32 ) != 0
1796+ self . flags & ( 1 << rt :: Flag :: Alternate as u32 ) != 0
19391797 }
19401798
19411799 /// Determines if the `0` flag was specified.
@@ -1961,17 +1819,17 @@ impl<'a> Formatter<'a> {
19611819 #[ must_use]
19621820 #[ stable( feature = "fmt_flags" , since = "1.5.0" ) ]
19631821 pub fn sign_aware_zero_pad ( & self ) -> bool {
1964- self . flags & ( 1 << Flag :: SignAwareZeroPad as u32 ) != 0
1822+ self . flags & ( 1 << rt :: Flag :: SignAwareZeroPad as u32 ) != 0
19651823 }
19661824
19671825 // FIXME: Decide what public API we want for these two flags.
19681826 // https://github.com/rust-lang/rust/issues/48584
19691827 fn debug_lower_hex ( & self ) -> bool {
1970- self . flags & ( 1 << Flag :: DebugLowerHex as u32 ) != 0
1828+ self . flags & ( 1 << rt :: Flag :: DebugLowerHex as u32 ) != 0
19711829 }
19721830
19731831 fn debug_upper_hex ( & self ) -> bool {
1974- self . flags & ( 1 << Flag :: DebugUpperHex as u32 ) != 0
1832+ self . flags & ( 1 << rt :: Flag :: DebugUpperHex as u32 ) != 0
19751833 }
19761834
19771835 /// Creates a [`DebugStruct`] builder designed to assist with creation of
@@ -2531,13 +2389,13 @@ pub(crate) fn pointer_fmt_inner(ptr_addr: usize, f: &mut Formatter<'_>) -> Resul
25312389 // or not to zero extend, and then unconditionally set it to get the
25322390 // prefix.
25332391 if f. alternate ( ) {
2534- f. flags |= 1 << ( Flag :: SignAwareZeroPad as u32 ) ;
2392+ f. flags |= 1 << ( rt :: Flag :: SignAwareZeroPad as u32 ) ;
25352393
25362394 if f. width . is_none ( ) {
25372395 f. width = Some ( ( usize:: BITS / 4 ) as usize + 2 ) ;
25382396 }
25392397 }
2540- f. flags |= 1 << ( Flag :: Alternate as u32 ) ;
2398+ f. flags |= 1 << ( rt :: Flag :: Alternate as u32 ) ;
25412399
25422400 let ret = LowerHex :: fmt ( & ptr_addr, f) ;
25432401
0 commit comments