diff options
| author | Matthias Krüger <476013+matthiaskrgr@users.noreply.github.com> | 2025-04-30 17:27:57 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-04-30 17:27:57 +0200 |
| commit | bc99a045cb0786b8a6f92abc5e80acd04dc74886 (patch) | |
| tree | 735fdd1b13bb9dcfd8d95c31685f919dca9706f3 | |
| parent | 555df301f820e97083207f47864a3321eeee425c (diff) | |
| parent | 56426db0b634fcd8d7e5842f39593651a594e602 (diff) | |
| download | rust-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.rs | 9 | ||||
| -rw-r--r-- | tests/ui/consts/const-eval/format.rs | 5 | ||||
| -rw-r--r-- | tests/ui/consts/const-eval/format.stderr | 10 |
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`. |
