about summary refs log tree commit diff
path: root/library/core/src/fmt/rt.rs
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2025-05-02 04:26:54 +0000
committerbors <bors@rust-lang.org>2025-05-02 04:26:54 +0000
commitcb0d6e76d0515b19d249c0147d246296b9d3d124 (patch)
treecbc84e7a1a9c4d3f69b400af805e9dad805c9763 /library/core/src/fmt/rt.rs
parent3350c1eb3fd8fe1bee1ed4c76944d707bd256876 (diff)
parentd42e3ace2be27a05d8474720025a1e611328ca8b (diff)
downloadrust-cb0d6e76d0515b19d249c0147d246296b9d3d124.tar.gz
rust-cb0d6e76d0515b19d249c0147d246296b9d3d124.zip
Auto merge of #140565 - GuillaumeGomez:rollup-gv4ed14, r=GuillaumeGomez
Rollup of 12 pull requests

Successful merges:

 - #138703 (chore: remove redundant words in comment)
 - #139186 (Refactor `diy_float`)
 - #139780 (docs: Add example to `Iterator::take` with `by_ref`)
 - #139802 (Fix some grammar errors and hyperlinks in doc for `trait Allocator`)
 - #140034 (simd_select_bitmask: the 'padding' bits in the mask are just ignored)
 - #140062 (std: mention `remove_dir_all` can emit `DirectoryNotEmpty` when concurrently written into)
 - #140420 (rustdoc: Fix doctest heuristic for main fn wrapping)
 - #140460 (Fix handling of LoongArch target features not supported by LLVM 19)
 - #140538 (rustc-dev-guide subtree update)
 - #140544 (Clean up "const" situation in format_args!(). )
 - #140552 (allow `#[rustc_std_internal_symbol]` in combination with `#[naked]`)
 - #140556 (Improve error output in case `nodejs` or `npm` is not installed for rustdoc-gui test suite)

r? `@ghost`
`@rustbot` modify labels: rollup
Diffstat (limited to 'library/core/src/fmt/rt.rs')
-rw-r--r--library/core/src/fmt/rt.rs89
1 files changed, 69 insertions, 20 deletions
diff --git a/library/core/src/fmt/rt.rs b/library/core/src/fmt/rt.rs
index e409771362e..c2a8a39bcac 100644
--- a/library/core/src/fmt/rt.rs
+++ b/library/core/src/fmt/rt.rs
@@ -1,7 +1,10 @@
 #![allow(missing_debug_implementations)]
 #![unstable(feature = "fmt_internals", reason = "internal to format_args!", issue = "none")]
 
-//! These are the lang items used by format_args!().
+//! All types and methods in this file are used by the compiler in
+//! the expansion/lowering of format_args!().
+//!
+//! Do not modify them without understanding the consequences for the format_args!() macro.
 
 use super::*;
 use crate::hint::unreachable_unchecked;
@@ -110,46 +113,45 @@ macro_rules! argument_new {
     };
 }
 
-#[rustc_diagnostic_item = "ArgumentMethods"]
 impl Argument<'_> {
     #[inline]
-    pub fn new_display<T: Display>(x: &T) -> Argument<'_> {
+    pub const fn new_display<T: Display>(x: &T) -> Argument<'_> {
         argument_new!(T, x, <T as Display>::fmt)
     }
     #[inline]
-    pub fn new_debug<T: Debug>(x: &T) -> Argument<'_> {
+    pub const fn new_debug<T: Debug>(x: &T) -> Argument<'_> {
         argument_new!(T, x, <T as Debug>::fmt)
     }
     #[inline]
-    pub fn new_debug_noop<T: Debug>(x: &T) -> Argument<'_> {
+    pub const fn new_debug_noop<T: Debug>(x: &T) -> Argument<'_> {
         argument_new!(T, x, |_: &T, _| Ok(()))
     }
     #[inline]
-    pub fn new_octal<T: Octal>(x: &T) -> Argument<'_> {
+    pub const fn new_octal<T: Octal>(x: &T) -> Argument<'_> {
         argument_new!(T, x, <T as Octal>::fmt)
     }
     #[inline]
-    pub fn new_lower_hex<T: LowerHex>(x: &T) -> Argument<'_> {
+    pub const fn new_lower_hex<T: LowerHex>(x: &T) -> Argument<'_> {
         argument_new!(T, x, <T as LowerHex>::fmt)
     }
     #[inline]
-    pub fn new_upper_hex<T: UpperHex>(x: &T) -> Argument<'_> {
+    pub const fn new_upper_hex<T: UpperHex>(x: &T) -> Argument<'_> {
         argument_new!(T, x, <T as UpperHex>::fmt)
     }
     #[inline]
-    pub fn new_pointer<T: Pointer>(x: &T) -> Argument<'_> {
+    pub const fn new_pointer<T: Pointer>(x: &T) -> Argument<'_> {
         argument_new!(T, x, <T as Pointer>::fmt)
     }
     #[inline]
-    pub fn new_binary<T: Binary>(x: &T) -> Argument<'_> {
+    pub const fn new_binary<T: Binary>(x: &T) -> Argument<'_> {
         argument_new!(T, x, <T as Binary>::fmt)
     }
     #[inline]
-    pub fn new_lower_exp<T: LowerExp>(x: &T) -> Argument<'_> {
+    pub const fn new_lower_exp<T: LowerExp>(x: &T) -> Argument<'_> {
         argument_new!(T, x, <T as LowerExp>::fmt)
     }
     #[inline]
-    pub fn new_upper_exp<T: UpperExp>(x: &T) -> Argument<'_> {
+    pub const fn new_upper_exp<T: UpperExp>(x: &T) -> Argument<'_> {
         argument_new!(T, x, <T as UpperExp>::fmt)
     }
     #[inline]
@@ -200,15 +202,8 @@ impl Argument<'_> {
     /// let f = format_args!("{}", "a");
     /// println!("{f}");
     /// ```
-    ///
-    /// This function should _not_ be const, to make sure we don't accept
-    /// format_args!() and panic!() with arguments in const, even when not evaluated:
-    ///
-    /// ```compile_fail,E0015
-    /// const _: () = if false { panic!("a {}", "a") };
-    /// ```
     #[inline]
-    pub fn none() -> [Self; 0] {
+    pub const fn none() -> [Self; 0] {
         []
     }
 }
@@ -229,3 +224,57 @@ impl UnsafeArg {
         Self { _private: () }
     }
 }
+
+/// Used by the format_args!() macro to create a fmt::Arguments object.
+#[doc(hidden)]
+#[unstable(feature = "fmt_internals", issue = "none")]
+#[rustc_diagnostic_item = "FmtArgumentsNew"]
+impl<'a> Arguments<'a> {
+    #[inline]
+    pub const fn new_const<const N: usize>(pieces: &'a [&'static str; N]) -> Self {
+        const { assert!(N <= 1) };
+        Arguments { pieces, fmt: None, args: &[] }
+    }
+
+    /// When using the format_args!() macro, this function is used to generate the
+    /// Arguments structure.
+    ///
+    /// This function should _not_ be const, to make sure we don't accept
+    /// format_args!() and panic!() with arguments in const, even when not evaluated:
+    ///
+    /// ```compile_fail,E0015
+    /// const _: () = if false { panic!("a {}", "a") };
+    /// ```
+    #[inline]
+    pub fn new_v1<const P: usize, const A: usize>(
+        pieces: &'a [&'static str; P],
+        args: &'a [rt::Argument<'a>; A],
+    ) -> Arguments<'a> {
+        const { assert!(P >= A && P <= A + 1, "invalid args") }
+        Arguments { pieces, fmt: None, args }
+    }
+
+    /// Specifies nonstandard formatting parameters.
+    ///
+    /// An `rt::UnsafeArg` is required because the following invariants must be held
+    /// in order for this function to be safe:
+    /// 1. The `pieces` slice must be at least as long as `fmt`.
+    /// 2. Every `rt::Placeholder::position` value within `fmt` must be a valid index of `args`.
+    /// 3. Every `rt::Count::Param` within `fmt` must contain a valid index of `args`.
+    ///
+    /// This function should _not_ be const, to make sure we don't accept
+    /// format_args!() and panic!() with arguments in const, even when not evaluated:
+    ///
+    /// ```compile_fail,E0015
+    /// const _: () = if false { panic!("a {:1}", "a") };
+    /// ```
+    #[inline]
+    pub fn new_v1_formatted(
+        pieces: &'a [&'static str],
+        args: &'a [rt::Argument<'a>],
+        fmt: &'a [rt::Placeholder],
+        _unsafe_arg: rt::UnsafeArg,
+    ) -> Arguments<'a> {
+        Arguments { pieces, fmt: Some(fmt), args }
+    }
+}