about summary refs log tree commit diff
path: root/library/core/src
diff options
context:
space:
mode:
authorMara Bos <m-ou.se@m-ou.se>2023-02-01 17:39:14 +0100
committerMara Bos <m-ou.se@m-ou.se>2023-03-16 11:21:50 +0100
commitf2f6bcc4998c6f2a2e044bac428a7ca16028c148 (patch)
treeca515130d8ac8165a049aa86af09dd5b6387b238 /library/core/src
parent96d252160ea80dfa1cb26acc174a31cf94a09520 (diff)
downloadrust-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/src')
-rw-r--r--library/core/src/fmt/mod.rs26
-rw-r--r--library/core/src/panicking.rs4
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]