@@ -482,7 +482,7 @@ impl FormattingOptions {
482482 ///
483483 /// You may alternatively use [`Formatter::new()`].
484484 #[ 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 > {
486486 Formatter { options : self , buf : write }
487487 }
488488
@@ -530,9 +530,8 @@ impl Default for FormattingOptions {
530530#[ stable( feature = "rust1" , since = "1.0.0" ) ]
531531#[ rustc_diagnostic_item = "Formatter" ]
532532pub struct Formatter < ' a > {
533- options : FormattingOptions ,
534-
535533 buf : & ' a mut ( dyn Write + ' a ) ,
534+ options : & ' a FormattingOptions ,
536535}
537536
538537impl < ' a > Formatter < ' a > {
@@ -544,14 +543,21 @@ impl<'a> Formatter<'a> {
544543 ///
545544 /// You may alternatively use [`FormattingOptions::create_formatter()`].
546545 #[ 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 }
549552 }
550553
551554 /// Creates a new formatter based on this one with given [`FormattingOptions`].
552555 #[ 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 }
555561 }
556562}
557563
@@ -1429,7 +1435,7 @@ pub trait UpperExp {
14291435/// [`write!`]: crate::write!
14301436#[ stable( feature = "rust1" , since = "1.0.0" ) ]
14311437pub 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 ( ) } ) ;
14331439 let mut idx = 0 ;
14341440
14351441 match args. fmt {
@@ -1478,15 +1484,17 @@ pub fn write(output: &mut dyn Write, args: Arguments<'_>) -> Result {
14781484}
14791485
14801486unsafe 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) ;
14901498
14911499 // Extract the correct argument
14921500 debug_assert ! ( arg. position < args. len( ) ) ;
@@ -1496,7 +1504,7 @@ unsafe fn run(fmt: &mut Formatter<'_>, arg: &rt::Placeholder, args: &[rt::Argume
14961504
14971505 // Then actually do some printing
14981506 // SAFETY: this is a placeholder argument.
1499- unsafe { value. fmt ( fmt) }
1507+ unsafe { value. fmt ( & mut fmt) }
15001508}
15011509
15021510unsafe fn getcount ( args : & [ rt:: Argument < ' _ > ] , cnt : & rt:: Count ) -> Option < usize > {
@@ -1641,16 +1649,16 @@ impl<'a> Formatter<'a> {
16411649 // The sign and prefix goes before the padding if the fill character
16421650 // is zero
16431651 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 )
16541662 }
16551663 // Otherwise, the sign and prefix goes after the padding
16561664 Some ( min) => {
@@ -1776,37 +1784,40 @@ impl<'a> Formatter<'a> {
17761784 // for the sign-aware zero padding, we render the sign first and
17771785 // behave as if we had no sign from the beginning.
17781786 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 ( ) {
17821790 // a sign always goes first
17831791 let sign = formatted. sign ;
17841792 self . buf . write_str ( sign) ?;
17851793
17861794 // remove the sign from the formatted parts
17871795 formatted. sign = "" ;
17881796 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+ } ;
17921806
17931807 // remaining parts go through the ordinary padding process.
17941808 let len = formatted. len ( ) ;
1795- let ret = if width <= len {
1809+ if width <= len {
17961810 // no padding
17971811 // SAFETY: Per the precondition.
1798- unsafe { self . write_formatted_parts ( & formatted) }
1812+ unsafe { f . write_formatted_parts ( & formatted) }
17991813 } else {
1800- let post_padding = self . padding ( width - len, Alignment :: Right ) ?;
1814+ let post_padding = f . padding ( width - len, Alignment :: Right ) ?;
18011815 // SAFETY: Per the precondition.
18021816 unsafe {
1803- self . write_formatted_parts ( & formatted) ?;
1817+ f . write_formatted_parts ( & formatted) ?;
18041818 }
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+ }
18101821 } else {
18111822 // this is the common case and we take a shortcut
18121823 // SAFETY: Per the precondition.
@@ -2610,7 +2621,7 @@ impl<'a> Formatter<'a> {
26102621
26112622 /// Returns the formatting options this formatter corresponds to.
26122623 #[ unstable( feature = "formatting_options" , issue = "118117" ) ]
2613- pub const fn options ( & self ) -> FormattingOptions {
2624+ pub const fn options ( & self ) -> & FormattingOptions {
26142625 self . options
26152626 }
26162627}
@@ -2789,28 +2800,22 @@ impl<T: ?Sized> Pointer for *const T {
27892800///
27902801/// [problematic]: https://github.com/rust-lang/rust/issues/95489
27912802pub ( 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 ( ) ;
27942804
27952805 // The alternate flag is already treated by LowerHex as being special-
27962806 // it denotes whether to prefix with 0x. We use it to work out whether
27972807 // or not to zero extend, and then unconditionally set it to get the
27982808 // prefix.
27992809 if f. alternate ( ) {
2800- f . options . flags |= 1 << ( rt:: Flag :: SignAwareZeroPad as u32 ) ;
2810+ options. flags |= 1 << ( rt:: Flag :: SignAwareZeroPad as u32 ) ;
28012811
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 ) ;
28042814 }
28052815 }
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 ) ;
28122817
2813- ret
2818+ LowerHex :: fmt ( & ptr_addr , & mut f . with_options ( & options ) )
28142819}
28152820
28162821#[ stable( feature = "rust1" , since = "1.0.0" ) ]
0 commit comments