@@ -251,145 +251,48 @@ impl<'a> Formatter<'a> {
251
251
}
252
252
}
253
253
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" ) ]
266
278
#[ 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 ] ,
356
282
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 ] > ,
377
285
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 > ] ,
387
289
}
388
290
291
+ /// Used by the format_args!() macro to create a fmt::Arguments object.
292
+ #[ doc( hidden) ]
293
+ #[ unstable( feature = "fmt_internals" , issue = "none" ) ]
389
294
impl < ' a > Arguments < ' a > {
390
- #[ doc( hidden) ]
391
295
#[ inline]
392
- #[ unstable( feature = "fmt_internals" , issue = "none" ) ]
393
296
#[ rustc_const_unstable( feature = "const_fmt_arguments_new" , issue = "none" ) ]
394
297
pub const fn new_const ( pieces : & ' a [ & ' static str ] ) -> Self {
395
298
if pieces. len ( ) > 1 {
@@ -401,22 +304,18 @@ impl<'a> Arguments<'a> {
401
304
/// When using the format_args!() macro, this function is used to generate the
402
305
/// Arguments structure.
403
306
#[ cfg( not( bootstrap) ) ]
404
- #[ doc( hidden) ]
405
307
#[ 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 > {
408
309
if pieces. len ( ) < args. len ( ) || pieces. len ( ) > args. len ( ) + 1 {
409
310
panic ! ( "invalid args" ) ;
410
311
}
411
312
Arguments { pieces, fmt : None , args }
412
313
}
413
314
414
315
#[ cfg( bootstrap) ]
415
- #[ doc( hidden) ]
416
316
#[ inline]
417
- #[ unstable( feature = "fmt_internals" , reason = "internal to format_args!" , issue = "none" ) ]
418
317
#[ 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 > {
420
319
if pieces. len ( ) < args. len ( ) || pieces. len ( ) > args. len ( ) + 1 {
421
320
panic ! ( "invalid args" ) ;
422
321
}
@@ -425,19 +324,17 @@ impl<'a> Arguments<'a> {
425
324
426
325
/// This function is used to specify nonstandard formatting parameters.
427
326
///
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
429
328
/// in order for this function to be safe:
430
329
/// 1. The `pieces` slice must be at least as long as `fmt`.
431
330
/// 2. Every `rt::Placeholder::position` value within `fmt` must be a valid index of `args`.
432
331
/// 3. Every `rt::Count::Param` within `fmt` must contain a valid index of `args`.
433
- #[ doc( hidden) ]
434
332
#[ inline]
435
- #[ unstable( feature = "fmt_internals" , reason = "internal to format_args!" , issue = "none" ) ]
436
333
pub fn new_v1_formatted (
437
334
pieces : & ' a [ & ' static str ] ,
438
- args : & ' a [ Argument < ' a > ] ,
335
+ args : & ' a [ rt :: Argument < ' a > ] ,
439
336
fmt : & ' a [ rt:: Placeholder ] ,
440
- _unsafe_arg : UnsafeArg ,
337
+ _unsafe_arg : rt :: UnsafeArg ,
441
338
) -> Arguments < ' a > {
442
339
Arguments { pieces, fmt : Some ( fmt) , args }
443
340
}
@@ -446,9 +343,7 @@ impl<'a> Arguments<'a> {
446
343
///
447
344
/// This is intended to be used for setting initial `String` capacity
448
345
/// when using `format!`. Note: this is neither the lower nor upper bound.
449
- #[ doc( hidden) ]
450
346
#[ inline]
451
- #[ unstable( feature = "fmt_internals" , reason = "internal to format_args!" , issue = "none" ) ]
452
347
pub fn estimated_capacity ( & self ) -> usize {
453
348
let pieces_length: usize = self . pieces . iter ( ) . map ( |x| x. len ( ) ) . sum ( ) ;
454
349
@@ -468,43 +363,6 @@ impl<'a> Arguments<'a> {
468
363
}
469
364
}
470
365
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
-
508
366
impl < ' a > Arguments < ' a > {
509
367
/// Get the formatted string, if it has no arguments to be formatted at runtime.
510
368
///
@@ -1244,7 +1102,7 @@ pub fn write(output: &mut dyn Write, args: Arguments<'_>) -> Result {
1244
1102
if !piece. is_empty ( ) {
1245
1103
formatter. buf . write_str ( * piece) ?;
1246
1104
}
1247
- ( arg. formatter ) ( arg . value , & mut formatter) ?;
1105
+ arg. fmt ( & mut formatter) ?;
1248
1106
idx += 1 ;
1249
1107
}
1250
1108
}
@@ -1274,7 +1132,7 @@ pub fn write(output: &mut dyn Write, args: Arguments<'_>) -> Result {
1274
1132
Ok ( ( ) )
1275
1133
}
1276
1134
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 {
1278
1136
fmt. fill = arg. fill ;
1279
1137
fmt. align = arg. align ;
1280
1138
fmt. flags = arg. flags ;
@@ -1292,10 +1150,10 @@ unsafe fn run(fmt: &mut Formatter<'_>, arg: &rt::Placeholder, args: &[Argument<'
1292
1150
let value = unsafe { args. get_unchecked ( arg. position ) } ;
1293
1151
1294
1152
// Then actually do some printing
1295
- ( value. formatter ) ( value . value , fmt)
1153
+ value. fmt ( fmt)
1296
1154
}
1297
1155
1298
- unsafe fn getcount ( args : & [ Argument < ' _ > ] , cnt : & rt:: Count ) -> Option < usize > {
1156
+ unsafe fn getcount ( args : & [ rt :: Argument < ' _ > ] , cnt : & rt:: Count ) -> Option < usize > {
1299
1157
match * cnt {
1300
1158
rt:: Count :: Is ( n) => Some ( n) ,
1301
1159
rt:: Count :: Implied => None ,
@@ -1878,7 +1736,7 @@ impl<'a> Formatter<'a> {
1878
1736
#[ must_use]
1879
1737
#[ stable( feature = "fmt_flags" , since = "1.5.0" ) ]
1880
1738
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
1882
1740
}
1883
1741
1884
1742
/// Determines if the `-` flag was specified.
@@ -1907,7 +1765,7 @@ impl<'a> Formatter<'a> {
1907
1765
#[ must_use]
1908
1766
#[ stable( feature = "fmt_flags" , since = "1.5.0" ) ]
1909
1767
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
1911
1769
}
1912
1770
1913
1771
/// Determines if the `#` flag was specified.
@@ -1935,7 +1793,7 @@ impl<'a> Formatter<'a> {
1935
1793
#[ must_use]
1936
1794
#[ stable( feature = "fmt_flags" , since = "1.5.0" ) ]
1937
1795
pub fn alternate ( & self ) -> bool {
1938
- self . flags & ( 1 << Flag :: Alternate as u32 ) != 0
1796
+ self . flags & ( 1 << rt :: Flag :: Alternate as u32 ) != 0
1939
1797
}
1940
1798
1941
1799
/// Determines if the `0` flag was specified.
@@ -1961,17 +1819,17 @@ impl<'a> Formatter<'a> {
1961
1819
#[ must_use]
1962
1820
#[ stable( feature = "fmt_flags" , since = "1.5.0" ) ]
1963
1821
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
1965
1823
}
1966
1824
1967
1825
// FIXME: Decide what public API we want for these two flags.
1968
1826
// https://github.com/rust-lang/rust/issues/48584
1969
1827
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
1971
1829
}
1972
1830
1973
1831
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
1975
1833
}
1976
1834
1977
1835
/// 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
2531
2389
// or not to zero extend, and then unconditionally set it to get the
2532
2390
// prefix.
2533
2391
if f. alternate ( ) {
2534
- f. flags |= 1 << ( Flag :: SignAwareZeroPad as u32 ) ;
2392
+ f. flags |= 1 << ( rt :: Flag :: SignAwareZeroPad as u32 ) ;
2535
2393
2536
2394
if f. width . is_none ( ) {
2537
2395
f. width = Some ( ( usize:: BITS / 4 ) as usize + 2 ) ;
2538
2396
}
2539
2397
}
2540
- f. flags |= 1 << ( Flag :: Alternate as u32 ) ;
2398
+ f. flags |= 1 << ( rt :: Flag :: Alternate as u32 ) ;
2541
2399
2542
2400
let ret = LowerHex :: fmt ( & ptr_addr, f) ;
2543
2401
0 commit comments