diff --git a/compiler/rustc_const_eval/src/check_consts/ops.rs b/compiler/rustc_const_eval/src/check_consts/ops.rs index 7756e51c4c5f2..1e5b98675c4f0 100644 --- a/compiler/rustc_const_eval/src/check_consts/ops.rs +++ b/compiler/rustc_const_eval/src/check_consts/ops.rs @@ -352,7 +352,7 @@ fn build_error_for_const_call<'tcx>( ); err } - _ if tcx.opt_parent(callee) == tcx.get_diagnostic_item(sym::ArgumentMethods) => { + _ if tcx.opt_parent(callee) == tcx.get_diagnostic_item(sym::FmtArgumentsNew) => { ccx.dcx().create_err(errors::NonConstFmtMacroCall { span, kind: ccx.const_kind(), diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index ba3e6d7ca826c..7a1fb36324bf9 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -174,7 +174,6 @@ symbols! { Arc, ArcWeak, Argument, - ArgumentMethods, ArrayIntoIter, AsMut, AsRef, @@ -249,6 +248,7 @@ symbols! { Error, File, FileType, + FmtArgumentsNew, Fn, FnMut, FnOnce, diff --git a/library/core/src/fmt/mod.rs b/library/core/src/fmt/mod.rs index 580f95eddce71..4f7f8a5b84dd5 100644 --- a/library/core/src/fmt/mod.rs +++ b/library/core/src/fmt/mod.rs @@ -622,44 +622,9 @@ pub struct Arguments<'a> { args: &'a [rt::Argument<'a>], } -/// Used by the format_args!() macro to create a fmt::Arguments object. #[doc(hidden)] #[unstable(feature = "fmt_internals", issue = "none")] impl<'a> Arguments<'a> { - #[inline] - pub const fn new_const(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. - #[inline] - pub const fn new_v1( - 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`. - #[inline] - pub const 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 } - } - /// Estimates the length of the formatted text. /// /// This is intended to be used for setting initial `String` capacity diff --git a/library/core/src/fmt/rt.rs b/library/core/src/fmt/rt.rs index e409771362e47..c2a8a39bcac8f 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(x: &T) -> Argument<'_> { + pub const fn new_display(x: &T) -> Argument<'_> { argument_new!(T, x, ::fmt) } #[inline] - pub fn new_debug(x: &T) -> Argument<'_> { + pub const fn new_debug(x: &T) -> Argument<'_> { argument_new!(T, x, ::fmt) } #[inline] - pub fn new_debug_noop(x: &T) -> Argument<'_> { + pub const fn new_debug_noop(x: &T) -> Argument<'_> { argument_new!(T, x, |_: &T, _| Ok(())) } #[inline] - pub fn new_octal(x: &T) -> Argument<'_> { + pub const fn new_octal(x: &T) -> Argument<'_> { argument_new!(T, x, ::fmt) } #[inline] - pub fn new_lower_hex(x: &T) -> Argument<'_> { + pub const fn new_lower_hex(x: &T) -> Argument<'_> { argument_new!(T, x, ::fmt) } #[inline] - pub fn new_upper_hex(x: &T) -> Argument<'_> { + pub const fn new_upper_hex(x: &T) -> Argument<'_> { argument_new!(T, x, ::fmt) } #[inline] - pub fn new_pointer(x: &T) -> Argument<'_> { + pub const fn new_pointer(x: &T) -> Argument<'_> { argument_new!(T, x, ::fmt) } #[inline] - pub fn new_binary(x: &T) -> Argument<'_> { + pub const fn new_binary(x: &T) -> Argument<'_> { argument_new!(T, x, ::fmt) } #[inline] - pub fn new_lower_exp(x: &T) -> Argument<'_> { + pub const fn new_lower_exp(x: &T) -> Argument<'_> { argument_new!(T, x, ::fmt) } #[inline] - pub fn new_upper_exp(x: &T) -> Argument<'_> { + pub const fn new_upper_exp(x: &T) -> Argument<'_> { argument_new!(T, x, ::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(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( + 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 } + } +} diff --git a/tests/mir-opt/sroa/lifetimes.foo.ScalarReplacementOfAggregates.diff b/tests/mir-opt/sroa/lifetimes.foo.ScalarReplacementOfAggregates.diff index a1df868cde051..33f1ad9bef4ef 100644 --- a/tests/mir-opt/sroa/lifetimes.foo.ScalarReplacementOfAggregates.diff +++ b/tests/mir-opt/sroa/lifetimes.foo.ScalarReplacementOfAggregates.diff @@ -121,7 +121,7 @@ StorageDead(_18); _16 = &_17; _15 = &(*_16); - _11 = Arguments::<'_>::new_v1::<3, 2>(move _12, move _15) -> [return: bb5, unwind unreachable]; + _11 = core::fmt::rt::>::new_v1::<3, 2>(move _12, move _15) -> [return: bb5, unwind unreachable]; } bb5: { diff --git a/tests/pretty/issue-4264.pp b/tests/pretty/issue-4264.pp index 3cff6ca33dab9..eb808f7122a9d 100644 --- a/tests/pretty/issue-4264.pp +++ b/tests/pretty/issue-4264.pp @@ -34,7 +34,7 @@ ((::alloc::fmt::format as for<'a> fn(Arguments<'a>) -> String {format})(((format_arguments::new_const as - fn(&[&'static str; 1]) -> Arguments<'_> {Arguments::<'_>::new_const::<1>})((&([("test" + fn(&[&'static str; 1]) -> Arguments<'_> {core::fmt::rt::>::new_const::<1>})((&([("test" as &str)] as [&str; 1]) as &[&str; 1])) as Arguments<'_>)) as String) } as String)) as String); diff --git a/tests/ui/consts/const-eval/format.stderr b/tests/ui/consts/const-eval/format.stderr index 4c4cbb372a7fd..2f202705b7f96 100644 --- a/tests/ui/consts/const-eval/format.stderr +++ b/tests/ui/consts/const-eval/format.stderr @@ -1,16 +1,16 @@ error[E0015]: cannot call non-const formatting macro in constant functions - --> $DIR/format.rs:2:13 + --> $DIR/format.rs:2:5 | LL | panic!("{:?}", 0); - | ^^^^ + | ^^^^^^^^^^^^^^^^^ | = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants error[E0015]: cannot call non-const formatting macro in constant functions - --> $DIR/format.rs:7:15 + --> $DIR/format.rs:7:5 | LL | println!("{:?}", 0); - | ^^^^ + | ^^^^^^^^^^^^^^^^^^^ | = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)