diff --git a/library/core/src/fmt/mod.rs b/library/core/src/fmt/mod.rs index e1b7b46a1ed2f..a1513515c09bf 100644 --- a/library/core/src/fmt/mod.rs +++ b/library/core/src/fmt/mod.rs @@ -201,14 +201,22 @@ pub trait Write { impl SpecWriteFmt for &mut W { #[inline] default fn spec_write_fmt(mut self, args: Arguments<'_>) -> Result { - write(&mut self, args) + if let Some(s) = args.as_const_str() { + self.write_str(s) + } else { + write(&mut self, args) + } } } impl SpecWriteFmt for &mut W { #[inline] fn spec_write_fmt(self, args: Arguments<'_>) -> Result { - write(self, args) + if let Some(s) = args.as_const_str() { + self.write_str(s) + } else { + write(self, args) + } } } @@ -430,6 +438,15 @@ impl<'a> Arguments<'a> { _ => None, } } + + /// Same as [`Arguments::as_str`], but will only return `Some(s)` if it can be determined at compile time. + #[must_use] + #[inline] + const fn as_const_str(&self) -> Option<&'static str> { + let s = self.as_str(); + // SAFETY: both cases are valid as the result + if unsafe { core::intrinsics::is_val_statically_known(s.is_some()) } { s } else { None } + } } #[stable(feature = "rust1", since = "1.0.0")] @@ -1582,8 +1599,9 @@ impl<'a> Formatter<'a> { /// assert_eq!(format!("{:0>8}", Foo(2)), "Foo 2"); /// ``` #[stable(feature = "rust1", since = "1.0.0")] + #[inline] pub fn write_fmt(&mut self, fmt: Arguments<'_>) -> Result { - write(self.buf, fmt) + if let Some(s) = fmt.as_const_str() { self.buf.write_str(s) } else { write(self.buf, fmt) } } /// Flags for formatting @@ -2272,8 +2290,13 @@ impl Write for Formatter<'_> { self.buf.write_char(c) } + #[inline] fn write_fmt(&mut self, args: Arguments<'_>) -> Result { - write(self.buf, args) + if let Some(s) = args.as_const_str() { + self.buf.write_str(s) + } else { + write(self.buf, args) + } } } diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index b54680a61b4d8..ffaf8af0b11d2 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -176,6 +176,7 @@ #![feature(ip)] #![feature(ip_bits)] #![feature(is_ascii_octdigit)] +#![feature(is_val_statically_known)] #![feature(isqrt)] #![feature(maybe_uninit_uninit_array)] #![feature(non_null_convenience)]