diff options
| author | Mara Bos <m-ou.se@m-ou.se> | 2023-02-01 17:39:14 +0100 |
|---|---|---|
| committer | Mara Bos <m-ou.se@m-ou.se> | 2023-03-16 11:21:50 +0100 |
| commit | f2f6bcc4998c6f2a2e044bac428a7ca16028c148 (patch) | |
| tree | ca515130d8ac8165a049aa86af09dd5b6387b238 /library/core | |
| parent | 96d252160ea80dfa1cb26acc174a31cf94a09520 (diff) | |
| download | rust-f2f6bcc4998c6f2a2e044bac428a7ca16028c148.tar.gz rust-f2f6bcc4998c6f2a2e044bac428a7ca16028c148.zip | |
Don't allow new const panic through format flattening.
panic!("a {}", "b") is still not allowed in const,
even if the hir flattens to panic!("a b").
Diffstat (limited to 'library/core')
| -rw-r--r-- | library/core/src/fmt/mod.rs | 26 | ||||
| -rw-r--r-- | library/core/src/panicking.rs | 4 |
2 files changed, 26 insertions, 4 deletions
diff --git a/library/core/src/fmt/mod.rs b/library/core/src/fmt/mod.rs index c9821bf8109..6d764237dc8 100644 --- a/library/core/src/fmt/mod.rs +++ b/library/core/src/fmt/mod.rs @@ -392,8 +392,31 @@ enum FlagV1 { } impl<'a> Arguments<'a> { + #[doc(hidden)] + #[inline] + #[unstable(feature = "fmt_internals", issue = "none")] + #[rustc_const_unstable(feature = "const_fmt_arguments_new", issue = "none")] + pub const fn new_const(pieces: &'a [&'static str]) -> Self { + if pieces.len() > 1 { + panic!("invalid args"); + } + Arguments { pieces, fmt: None, args: &[] } + } + /// When using the format_args!() macro, this function is used to generate the /// Arguments structure. + #[cfg(not(bootstrap))] + #[doc(hidden)] + #[inline] + #[unstable(feature = "fmt_internals", reason = "internal to format_args!", issue = "none")] + pub fn new_v1(pieces: &'a [&'static str], args: &'a [ArgumentV1<'a>]) -> Arguments<'a> { + if pieces.len() < args.len() || pieces.len() > args.len() + 1 { + panic!("invalid args"); + } + Arguments { pieces, fmt: None, args } + } + + #[cfg(bootstrap)] #[doc(hidden)] #[inline] #[unstable(feature = "fmt_internals", reason = "internal to format_args!", issue = "none")] @@ -417,8 +440,7 @@ impl<'a> Arguments<'a> { #[doc(hidden)] #[inline] #[unstable(feature = "fmt_internals", reason = "internal to format_args!", issue = "none")] - #[rustc_const_unstable(feature = "const_fmt_arguments_new", issue = "none")] - pub const fn new_v1_formatted( + pub fn new_v1_formatted( pieces: &'a [&'static str], args: &'a [ArgumentV1<'a>], fmt: &'a [rt::v1::Argument], diff --git a/library/core/src/panicking.rs b/library/core/src/panicking.rs index 805a1e51ae9..dd0105c0eb4 100644 --- a/library/core/src/panicking.rs +++ b/library/core/src/panicking.rs @@ -111,7 +111,7 @@ pub const fn panic(expr: &'static str) -> ! { // truncation and padding (even though none is used here). Using // Arguments::new_v1 may allow the compiler to omit Formatter::pad from the // output binary, saving up to a few kilobytes. - panic_fmt(fmt::Arguments::new_v1(&[expr], &[])); + panic_fmt(fmt::Arguments::new_const(&[expr])); } /// Like `panic`, but without unwinding and track_caller to reduce the impact on codesize. @@ -120,7 +120,7 @@ pub const fn panic(expr: &'static str) -> ! { #[lang = "panic_nounwind"] // needed by codegen for non-unwinding panics #[rustc_nounwind] pub fn panic_nounwind(expr: &'static str) -> ! { - panic_nounwind_fmt(fmt::Arguments::new_v1(&[expr], &[])); + panic_nounwind_fmt(fmt::Arguments::new_const(&[expr])); } #[inline] |
