about summary refs log tree commit diff
path: root/library/core/src/fmt/rt.rs
diff options
context:
space:
mode:
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 }
+    }
+}