Skip to content

Commit 5da3837

Browse files
committed
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").
1 parent 5c69f9d commit 5da3837

File tree

2 files changed

+26
-4
lines changed

2 files changed

+26
-4
lines changed

core/src/fmt/mod.rs

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -392,8 +392,31 @@ enum FlagV1 {
392392
}
393393

394394
impl<'a> Arguments<'a> {
395+
#[doc(hidden)]
396+
#[inline]
397+
#[unstable(feature = "fmt_internals", issue = "none")]
398+
#[rustc_const_unstable(feature = "const_fmt_arguments_new", issue = "none")]
399+
pub const fn new_const(pieces: &'a [&'static str]) -> Self {
400+
if pieces.len() > 1 {
401+
panic!("invalid args");
402+
}
403+
Arguments { pieces, fmt: None, args: &[] }
404+
}
405+
395406
/// When using the format_args!() macro, this function is used to generate the
396407
/// Arguments structure.
408+
#[cfg(not(bootstrap))]
409+
#[doc(hidden)]
410+
#[inline]
411+
#[unstable(feature = "fmt_internals", reason = "internal to format_args!", issue = "none")]
412+
pub fn new_v1(pieces: &'a [&'static str], args: &'a [ArgumentV1<'a>]) -> Arguments<'a> {
413+
if pieces.len() < args.len() || pieces.len() > args.len() + 1 {
414+
panic!("invalid args");
415+
}
416+
Arguments { pieces, fmt: None, args }
417+
}
418+
419+
#[cfg(bootstrap)]
397420
#[doc(hidden)]
398421
#[inline]
399422
#[unstable(feature = "fmt_internals", reason = "internal to format_args!", issue = "none")]
@@ -417,8 +440,7 @@ impl<'a> Arguments<'a> {
417440
#[doc(hidden)]
418441
#[inline]
419442
#[unstable(feature = "fmt_internals", reason = "internal to format_args!", issue = "none")]
420-
#[rustc_const_unstable(feature = "const_fmt_arguments_new", issue = "none")]
421-
pub const fn new_v1_formatted(
443+
pub fn new_v1_formatted(
422444
pieces: &'a [&'static str],
423445
args: &'a [ArgumentV1<'a>],
424446
fmt: &'a [rt::v1::Argument],

core/src/panicking.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ pub const fn panic(expr: &'static str) -> ! {
111111
// truncation and padding (even though none is used here). Using
112112
// Arguments::new_v1 may allow the compiler to omit Formatter::pad from the
113113
// output binary, saving up to a few kilobytes.
114-
panic_fmt(fmt::Arguments::new_v1(&[expr], &[]));
114+
panic_fmt(fmt::Arguments::new_const(&[expr]));
115115
}
116116

117117
/// 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) -> ! {
120120
#[lang = "panic_nounwind"] // needed by codegen for non-unwinding panics
121121
#[rustc_nounwind]
122122
pub fn panic_nounwind(expr: &'static str) -> ! {
123-
panic_nounwind_fmt(fmt::Arguments::new_v1(&[expr], &[]));
123+
panic_nounwind_fmt(fmt::Arguments::new_const(&[expr]));
124124
}
125125

126126
#[inline]

0 commit comments

Comments
 (0)