diff options
Diffstat (limited to 'library/core/src/fmt/rt.rs')
| -rw-r--r-- | library/core/src/fmt/rt.rs | 89 | 
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 } + } +} | 
