diff --git a/library/alloc/src/fmt.rs b/library/alloc/src/fmt.rs index e40de13f3d4a9..ce481ce1cff84 100644 --- a/library/alloc/src/fmt.rs +++ b/library/alloc/src/fmt.rs @@ -645,8 +645,7 @@ pub fn format(args: Arguments<'_>) -> string::String { fn format_inner(args: Arguments<'_>) -> string::String { let capacity = args.estimated_capacity(); let mut output = string::String::with_capacity(capacity); - output - .write_fmt(args) + core::fmt::write(&mut output, args) .expect("a formatting trait implementation returned an error when the underlying stream did not"); output } diff --git a/library/alloc/src/string.rs b/library/alloc/src/string.rs index 9236f5cb8d1f0..0b712e34a6fab 100644 --- a/library/alloc/src/string.rs +++ b/library/alloc/src/string.rs @@ -3172,6 +3172,15 @@ impl fmt::Write for String { self.push(c); Ok(()) } + + fn write_fmt(&mut self, args: fmt::Arguments<'_>) -> fmt::Result { + if let Some(s) = args.as_statically_known_str() { + self.write_str(s) + } else { + self.reserve(args.estimated_capacity()); + fmt::write(self, args) + } + } } /// An iterator over the [`char`]s of a string. diff --git a/library/std/src/ffi/os_str.rs b/library/std/src/ffi/os_str.rs index aa25ff5293c71..f1ca0328ef160 100644 --- a/library/std/src/ffi/os_str.rs +++ b/library/std/src/ffi/os_str.rs @@ -799,10 +799,20 @@ impl Hash for OsString { #[stable(feature = "os_string_fmt_write", since = "1.64.0")] impl fmt::Write for OsString { + #[inline] fn write_str(&mut self, s: &str) -> fmt::Result { self.push(s); Ok(()) } + + fn write_fmt(&mut self, args: fmt::Arguments<'_>) -> fmt::Result { + if let Some(s) = args.as_statically_known_str() { + self.write_str(s) + } else { + self.reserve(args.estimated_capacity()); + fmt::write(self, args) + } + } } impl OsStr { diff --git a/library/std/src/io/cursor.rs b/library/std/src/io/cursor.rs index d7131e2fe92fd..20c457a9ea28e 100644 --- a/library/std/src/io/cursor.rs +++ b/library/std/src/io/cursor.rs @@ -2,9 +2,9 @@ mod tests; use crate::alloc::Allocator; -use crate::cmp; use crate::io::prelude::*; use crate::io::{self, BorrowedCursor, ErrorKind, IoSlice, IoSliceMut, SeekFrom}; +use crate::{cmp, fmt}; /// A `Cursor` wraps an in-memory buffer and provides it with a /// [`Seek`] implementation. @@ -647,6 +647,15 @@ where Ok(()) } + fn write_fmt(&mut self, args: fmt::Arguments<'_>) -> io::Result<()> { + if let Some(s) = args.as_statically_known_str() { + self.write_all(s.as_bytes()) + } else { + self.inner.reserve(args.estimated_capacity()); + io::default_write_fmt(self, args) + } + } + #[inline] fn flush(&mut self) -> io::Result<()> { Ok(()) @@ -681,6 +690,15 @@ where Ok(()) } + fn write_fmt(&mut self, args: fmt::Arguments<'_>) -> io::Result<()> { + if let Some(s) = args.as_statically_known_str() { + self.write_all(s.as_bytes()) + } else { + self.inner.reserve(args.estimated_capacity()); + io::default_write_fmt(self, args) + } + } + #[inline] fn flush(&mut self) -> io::Result<()> { Ok(()) diff --git a/library/std/src/io/impls.rs b/library/std/src/io/impls.rs index d0245f3d4984c..c3a4db9a2714c 100644 --- a/library/std/src/io/impls.rs +++ b/library/std/src/io/impls.rs @@ -511,6 +511,15 @@ impl Write for Vec { Ok(()) } + fn write_fmt(&mut self, args: fmt::Arguments<'_>) -> io::Result<()> { + if let Some(s) = args.as_statically_known_str() { + self.write_all(s.as_bytes()) + } else { + self.reserve(args.estimated_capacity()); + io::default_write_fmt(self, args) + } + } + #[inline] fn flush(&mut self) -> io::Result<()> { Ok(()) @@ -662,6 +671,15 @@ impl Write for VecDeque { Ok(()) } + fn write_fmt(&mut self, args: fmt::Arguments<'_>) -> io::Result<()> { + if let Some(s) = args.as_statically_known_str() { + self.write_all(s.as_bytes()) + } else { + self.reserve(args.estimated_capacity()); + io::default_write_fmt(self, args) + } + } + #[inline] fn flush(&mut self) -> io::Result<()> { Ok(())