Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion compiler/rustc_const_eval/src/check_consts/ops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(),
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_span/src/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,6 @@ symbols! {
Arc,
ArcWeak,
Argument,
ArgumentMethods,
ArrayIntoIter,
AsMut,
AsRef,
Expand Down Expand Up @@ -249,6 +248,7 @@ symbols! {
Error,
File,
FileType,
FmtArgumentsNew,
Fn,
FnMut,
FnOnce,
Expand Down
35 changes: 0 additions & 35 deletions library/core/src/fmt/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<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.
#[inline]
pub const 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`.
#[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
Expand Down
89 changes: 69 additions & 20 deletions library/core/src/fmt/rt.rs
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -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]
Expand Down Expand Up @@ -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] {
[]
}
}
Expand All @@ -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 }
}
}
8 changes: 4 additions & 4 deletions tests/ui/consts/const-eval/format.stderr
Original file line number Diff line number Diff line change
@@ -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)
Expand Down
Loading