about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMatthias Krüger <476013+matthiaskrgr@users.noreply.github.com>2025-04-30 17:27:57 +0200
committerGitHub <noreply@github.com>2025-04-30 17:27:57 +0200
commitbc99a045cb0786b8a6f92abc5e80acd04dc74886 (patch)
tree735fdd1b13bb9dcfd8d95c31685f919dca9706f3
parent555df301f820e97083207f47864a3321eeee425c (diff)
parent56426db0b634fcd8d7e5842f39593651a594e602 (diff)
downloadrust-bc99a045cb0786b8a6f92abc5e80acd04dc74886.tar.gz
rust-bc99a045cb0786b8a6f92abc5e80acd04dc74886.zip
Rollup merge of #139624 - m-ou-se:unconst-format-args, r=jhpratt
Don't allow flattened format_args in const.

Fixes https://github.com/rust-lang/rust/issues/139136

Fixes https://github.com/rust-lang/rust/issues/139621

We allow `format_args!("a")` in const, but don't allow any format_args with arguments in const, such as `format_args!("{}", arg)`.

However, we accidentally allow `format_args!("hello {}", "world")` in const, as it gets flattened to `format_args!("hello world")`.

This also applies to panic in const.

This wasn't supposed to happen. I added protection against this in the format args flattening code, ~~but I accidentally marked a function as const that shouldn't have been const~~ but this was removed in https://github.com/rust-lang/rust/pull/135139.

This is a breaking change. The crater found no breakage, however.

This breaks things like:

```rust
const _: () = if false { panic!("a {}", "a") };
```

and

```rust
const F: std::fmt::Arguments<'static> = format_args!("a {}", "a");
```
-rw-r--r--library/core/src/fmt/rt.rs9
-rw-r--r--tests/ui/consts/const-eval/format.rs5
-rw-r--r--tests/ui/consts/const-eval/format.stderr10
3 files changed, 22 insertions, 2 deletions
diff --git a/library/core/src/fmt/rt.rs b/library/core/src/fmt/rt.rs
index adcfdd309b7..e409771362e 100644
--- a/library/core/src/fmt/rt.rs
+++ b/library/core/src/fmt/rt.rs
@@ -200,8 +200,15 @@ 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 const fn none() -> [Self; 0] {
+    pub fn none() -> [Self; 0] {
         []
     }
 }
diff --git a/tests/ui/consts/const-eval/format.rs b/tests/ui/consts/const-eval/format.rs
index 1878fc03827..a8085a786e1 100644
--- a/tests/ui/consts/const-eval/format.rs
+++ b/tests/ui/consts/const-eval/format.rs
@@ -9,4 +9,9 @@ const fn print() {
     //~| ERROR cannot call non-const function `_print` in constant functions
 }
 
+const fn format_args() {
+    format_args!("{}", 0);
+    //~^ ERROR cannot call non-const formatting macro in constant functions
+}
+
 fn main() {}
diff --git a/tests/ui/consts/const-eval/format.stderr b/tests/ui/consts/const-eval/format.stderr
index e8d7bbcea09..4c4cbb372a7 100644
--- a/tests/ui/consts/const-eval/format.stderr
+++ b/tests/ui/consts/const-eval/format.stderr
@@ -24,6 +24,14 @@ 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 `println` (in Nightly builds, run with -Z macro-backtrace for more info)
 
-error: aborting due to 3 previous errors
+error[E0015]: cannot call non-const formatting macro in constant functions
+  --> $DIR/format.rs:13:5
+   |
+LL |     format_args!("{}", 0);
+   |     ^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
+
+error: aborting due to 4 previous errors
 
 For more information about this error, try `rustc --explain E0015`.