@@ -482,7 +482,7 @@ impl FormattingOptions {
482
482
///
483
483
/// You may alternatively use [`Formatter::new()`].
484
484
#[ unstable( feature = "formatting_options" , issue = "118117" ) ]
485
- pub fn create_formatter < ' a > ( self , write : & ' a mut ( dyn Write + ' a ) ) -> Formatter < ' a > {
485
+ pub fn create_formatter < ' a > ( & ' a self , write : & ' a mut ( dyn Write + ' a ) ) -> Formatter < ' a > {
486
486
Formatter { options : self , buf : write }
487
487
}
488
488
@@ -530,9 +530,8 @@ impl Default for FormattingOptions {
530
530
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
531
531
#[ rustc_diagnostic_item = "Formatter" ]
532
532
pub struct Formatter < ' a > {
533
- options : FormattingOptions ,
534
-
535
533
buf : & ' a mut ( dyn Write + ' a ) ,
534
+ options : & ' a FormattingOptions ,
536
535
}
537
536
538
537
impl < ' a > Formatter < ' a > {
@@ -544,14 +543,21 @@ impl<'a> Formatter<'a> {
544
543
///
545
544
/// You may alternatively use [`FormattingOptions::create_formatter()`].
546
545
#[ unstable( feature = "formatting_options" , issue = "118117" ) ]
547
- pub fn new ( write : & ' a mut ( dyn Write + ' a ) , options : FormattingOptions ) -> Self {
548
- Formatter { options, buf : write }
546
+ pub fn new ( write : & ' a mut ( dyn Write + ' a ) , options : & ' a FormattingOptions ) -> Self {
547
+ Formatter { buf : write, options }
548
+ }
549
+
550
+ fn reborrow ( & mut self ) -> Formatter < ' _ > {
551
+ Formatter { buf : self . buf , options : self . options }
549
552
}
550
553
551
554
/// Creates a new formatter based on this one with given [`FormattingOptions`].
552
555
#[ unstable( feature = "formatting_options" , issue = "118117" ) ]
553
- pub fn with_options < ' b > ( & ' b mut self , options : FormattingOptions ) -> Formatter < ' b > {
554
- Formatter { options, buf : self . buf }
556
+ pub fn with_options < ' f , ' o > ( & ' f mut self , options : & ' o FormattingOptions ) -> Formatter < ' f >
557
+ where
558
+ ' o : ' f ,
559
+ {
560
+ Formatter { buf : self . buf , options }
555
561
}
556
562
}
557
563
@@ -1429,7 +1435,7 @@ pub trait UpperExp {
1429
1435
/// [`write!`]: crate::write!
1430
1436
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
1431
1437
pub fn write ( output : & mut dyn Write , args : Arguments < ' _ > ) -> Result {
1432
- let mut formatter = Formatter :: new ( output, FormattingOptions :: new ( ) ) ;
1438
+ let mut formatter = Formatter :: new ( output, const { & FormattingOptions :: new ( ) } ) ;
1433
1439
let mut idx = 0 ;
1434
1440
1435
1441
match args. fmt {
@@ -1478,15 +1484,17 @@ pub fn write(output: &mut dyn Write, args: Arguments<'_>) -> Result {
1478
1484
}
1479
1485
1480
1486
unsafe fn run ( fmt : & mut Formatter < ' _ > , arg : & rt:: Placeholder , args : & [ rt:: Argument < ' _ > ] ) -> Result {
1481
- fmt. options . fill = arg. fill ;
1482
- fmt. options . align = arg. align . into ( ) ;
1483
- fmt. options . flags = arg. flags ;
1484
- // SAFETY: arg and args come from the same Arguments,
1485
- // which guarantees the indexes are always within bounds.
1486
- unsafe {
1487
- fmt. options . width = getcount ( args, & arg. width ) ;
1488
- fmt. options . precision = getcount ( args, & arg. precision ) ;
1489
- }
1487
+ let options = FormattingOptions {
1488
+ flags : arg. flags ,
1489
+ fill : arg. fill ,
1490
+ align : arg. align . into ( ) ,
1491
+ // SAFETY: arg and args come from the same Arguments,
1492
+ // which guarantees the indexes are always within bounds.
1493
+ width : unsafe { getcount ( args, & arg. width ) } ,
1494
+ // SAFETY: likewise.
1495
+ precision : unsafe { getcount ( args, & arg. precision ) } ,
1496
+ } ;
1497
+ let mut fmt = fmt. with_options ( & options) ;
1490
1498
1491
1499
// Extract the correct argument
1492
1500
debug_assert ! ( arg. position < args. len( ) ) ;
@@ -1496,7 +1504,7 @@ unsafe fn run(fmt: &mut Formatter<'_>, arg: &rt::Placeholder, args: &[rt::Argume
1496
1504
1497
1505
// Then actually do some printing
1498
1506
// SAFETY: this is a placeholder argument.
1499
- unsafe { value. fmt ( fmt) }
1507
+ unsafe { value. fmt ( & mut fmt) }
1500
1508
}
1501
1509
1502
1510
unsafe fn getcount ( args : & [ rt:: Argument < ' _ > ] , cnt : & rt:: Count ) -> Option < usize > {
@@ -1641,16 +1649,16 @@ impl<'a> Formatter<'a> {
1641
1649
// The sign and prefix goes before the padding if the fill character
1642
1650
// is zero
1643
1651
Some ( min) if self . sign_aware_zero_pad ( ) => {
1644
- let old_fill = crate :: mem :: replace ( & mut self . options . fill , '0' ) ;
1645
- let old_align =
1646
- crate :: mem :: replace ( & mut self . options . align , Some ( Alignment :: Right ) ) ;
1647
- write_prefix ( self , sign , prefix ) ? ;
1648
- let post_padding = self . padding ( min - width , Alignment :: Right ) ? ;
1649
- self . buf . write_str ( buf ) ? ;
1650
- post_padding . write ( self ) ?;
1651
- self . options . fill = old_fill ;
1652
- self . options . align = old_align ;
1653
- Ok ( ( ) )
1652
+ let options = FormattingOptions {
1653
+ fill : '0' ,
1654
+ align : Some ( Alignment :: Right ) ,
1655
+ .. self . options ( ) . clone ( )
1656
+ } ;
1657
+ let mut f = self . with_options ( & options ) ;
1658
+ write_prefix ( & mut f , sign , prefix ) ?;
1659
+ let post_padding = f . padding ( min - width , Alignment :: Right ) ? ;
1660
+ f . write_str ( buf ) ? ;
1661
+ post_padding . write ( & mut f )
1654
1662
}
1655
1663
// Otherwise, the sign and prefix goes after the padding
1656
1664
Some ( min) => {
@@ -1776,37 +1784,40 @@ impl<'a> Formatter<'a> {
1776
1784
// for the sign-aware zero padding, we render the sign first and
1777
1785
// behave as if we had no sign from the beginning.
1778
1786
let mut formatted = formatted. clone ( ) ;
1779
- let old_fill = self . options . fill ;
1780
- let old_align = self . options . align ;
1781
- if self . sign_aware_zero_pad ( ) {
1787
+
1788
+ let options;
1789
+ let mut f = if self . sign_aware_zero_pad ( ) {
1782
1790
// a sign always goes first
1783
1791
let sign = formatted. sign ;
1784
1792
self . buf . write_str ( sign) ?;
1785
1793
1786
1794
// remove the sign from the formatted parts
1787
1795
formatted. sign = "" ;
1788
1796
width = width. saturating_sub ( sign. len ( ) ) ;
1789
- self . options . fill = '0' ;
1790
- self . options . align = Some ( Alignment :: Right ) ;
1791
- }
1797
+ options = FormattingOptions {
1798
+ fill : '0' ,
1799
+ align : Some ( Alignment :: Right ) ,
1800
+ ..self . options ( ) . clone ( )
1801
+ } ;
1802
+ self . with_options ( & options)
1803
+ } else {
1804
+ self . reborrow ( )
1805
+ } ;
1792
1806
1793
1807
// remaining parts go through the ordinary padding process.
1794
1808
let len = formatted. len ( ) ;
1795
- let ret = if width <= len {
1809
+ if width <= len {
1796
1810
// no padding
1797
1811
// SAFETY: Per the precondition.
1798
- unsafe { self . write_formatted_parts ( & formatted) }
1812
+ unsafe { f . write_formatted_parts ( & formatted) }
1799
1813
} else {
1800
- let post_padding = self . padding ( width - len, Alignment :: Right ) ?;
1814
+ let post_padding = f . padding ( width - len, Alignment :: Right ) ?;
1801
1815
// SAFETY: Per the precondition.
1802
1816
unsafe {
1803
- self . write_formatted_parts ( & formatted) ?;
1817
+ f . write_formatted_parts ( & formatted) ?;
1804
1818
}
1805
- post_padding. write ( self )
1806
- } ;
1807
- self . options . fill = old_fill;
1808
- self . options . align = old_align;
1809
- ret
1819
+ post_padding. write ( & mut f)
1820
+ }
1810
1821
} else {
1811
1822
// this is the common case and we take a shortcut
1812
1823
// SAFETY: Per the precondition.
@@ -2610,7 +2621,7 @@ impl<'a> Formatter<'a> {
2610
2621
2611
2622
/// Returns the formatting options this formatter corresponds to.
2612
2623
#[ unstable( feature = "formatting_options" , issue = "118117" ) ]
2613
- pub const fn options ( & self ) -> FormattingOptions {
2624
+ pub const fn options ( & self ) -> & FormattingOptions {
2614
2625
self . options
2615
2626
}
2616
2627
}
@@ -2789,28 +2800,22 @@ impl<T: ?Sized> Pointer for *const T {
2789
2800
///
2790
2801
/// [problematic]: https://github.com/rust-lang/rust/issues/95489
2791
2802
pub ( crate ) fn pointer_fmt_inner ( ptr_addr : usize , f : & mut Formatter < ' _ > ) -> Result {
2792
- let old_width = f. options . width ;
2793
- let old_flags = f. options . flags ;
2803
+ let mut options = f. options ( ) . clone ( ) ;
2794
2804
2795
2805
// The alternate flag is already treated by LowerHex as being special-
2796
2806
// it denotes whether to prefix with 0x. We use it to work out whether
2797
2807
// or not to zero extend, and then unconditionally set it to get the
2798
2808
// prefix.
2799
2809
if f. alternate ( ) {
2800
- f . options . flags |= 1 << ( rt:: Flag :: SignAwareZeroPad as u32 ) ;
2810
+ options. flags |= 1 << ( rt:: Flag :: SignAwareZeroPad as u32 ) ;
2801
2811
2802
- if f . options . width . is_none ( ) {
2803
- f . options . width = Some ( ( usize:: BITS / 4 ) as usize + 2 ) ;
2812
+ if options. width . is_none ( ) {
2813
+ options. width = Some ( ( usize:: BITS / 4 ) as usize + 2 ) ;
2804
2814
}
2805
2815
}
2806
- f. options . flags |= 1 << ( rt:: Flag :: Alternate as u32 ) ;
2807
-
2808
- let ret = LowerHex :: fmt ( & ptr_addr, f) ;
2809
-
2810
- f. options . width = old_width;
2811
- f. options . flags = old_flags;
2816
+ options. flags |= 1 << ( rt:: Flag :: Alternate as u32 ) ;
2812
2817
2813
- ret
2818
+ LowerHex :: fmt ( & ptr_addr , & mut f . with_options ( & options ) )
2814
2819
}
2815
2820
2816
2821
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
0 commit comments