# Allow panic! macro to take static strings as only argument

**URL:** <https://internals.rust-lang.org/t/allow-panic-macro-to-take-static-strings-as-only-argument/23613>\
**Category:** compiler\
**Created:** [October 11, 2025, 4:29pm UTC](https://internals.rust-lang.org/t/allow-panic-macro-to-take-static-strings-as-only-argument/23613 "2025-10-11T16:29:04Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![Reginald](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/reginald/32/13694_2.png) [@Reginald](https://internals.rust-lang.org/u/Reginald)\
**Post date:** [October 11, 2025, 4:29pm UTC](https://internals.rust-lang.org/t/allow-panic-macro-to-take-static-strings-as-only-argument/23613/1 "2025-10-11T16:29:04Z")

</div>

I'm making an embedded library and I have multiple parts of my code which panic under similar conditions with the same message. Originally I just used string literals, but in an effort to clean up my code I wanted to use a single static string to be referenced and just panic with that.

The issue is when you panic via `panic!("{}", STATIC_MSG);`, it adds all the formatting code as well, which is ~2kb in total. This isn't much, but when you're programming for embedded systems with limited memory this can be a big problem.

I propose allowing the `panic!` macro to take a static string as it's first argument, or, if more desirable, make `panicking::panic()` a non-nightly function. Having it reference a static string directly would reduce program size and allow for more readable and consistent code.

---

<div class="post-metadata">

**Author:** ![cuviper](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/cuviper/32/1897_2.png) [@cuviper](https://internals.rust-lang.org/u/cuviper)\
**Post date:** [October 11, 2025, 4:50pm UTC](https://internals.rust-lang.org/t/allow-panic-macro-to-take-static-strings-as-only-argument/23613/2 "2025-10-11T16:50:49Z")

</div>

As a workaround, you could make a macro for your repeated message:

```rust
macro_rules! panic_foo {
    () => { panic!("oh, phooey!") }
}

```

Or even just a function:

```rust
fn panic_foo() -> ! {
    panic!("oh, phooey!");
}

```

---

<div class="post-metadata">

**Author:** ![kpreid](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/kpreid/32/8484_2.png) [@kpreid](https://internals.rust-lang.org/u/kpreid)\
**Post date:** [October 11, 2025, 4:56pm UTC](https://internals.rust-lang.org/t/allow-panic-macro-to-take-static-strings-as-only-argument/23613/3 "2025-10-11T16:56:57Z")

</div>

> [@Reginald](#):
>
> I propose allowing the `panic!` macro to take a static string as it's first argument,

In other languages, it has proven to be a bad idea to have any ambiguity whatsoever over whether a string is a format string (containing instructions for what to print) or a value (to be printed literally). `panic!` [used to have some of this confusion](https://doc.rust-lang.org/std/macro.panic.html#2018-and-2015), and it was removed in the 2021 edition and later.

However, I have an alternative to propose: there are already optimizations for particular cases of format strings, and it seems plausible to me to say that `panic!("{}", STATIC_MSG)` or `panic!("{STATIC_MSG}")`, where the format string is exactly one `{}` and the argument is a string type, should be handled without invoking the general formatting system. This gets the effect you want without changing the meaning of `panic!()` in general.

* * *

As the best available option in _current_ Rust, I would suggest writing a function such as @cuviper’s `panic_foo()` example. This has another code size advantage — it avoids storing the panic [location](https://doc.rust-lang.org/std/panic/struct.Location.html) information for each separate call site, combining them into one location. (And if this is undesirable, you can add `#[track_caller]` to the function.)

---

<div class="post-metadata">

**Author:** ![ais523](https://avatars.discourse-cdn.com/v4/letter/a/a183cd/32.png) [@ais523](https://internals.rust-lang.org/u/ais523)\
**Post date:** [October 11, 2025, 6:18pm UTC](https://internals.rust-lang.org/t/allow-panic-macro-to-take-static-strings-as-only-argument/23613/4 "2025-10-11T18:18:27Z")

</div>

Would [`panic_any`](https://doc.rust-lang.org/stable/std/panic/fn.panic_any.html) work for this use case? It should be able to accept `&'static str` just fine. One potential problem is that it seems to be only in `std`, not `core` or `alloc` (this may be partly because it uses a memory allocator – but `panic!` would also need one if the panic is handled, and neither conceptually needs one if the panic isn't handled).

It's possible that it's only in `std` because `panic_any` is primarily intended for panics that are handled, whereas `panic!` is primarily intended for panics that are unhandled.

There's also [`core::panicking::panic`](https://doc.rust-lang.org/stable/core/panicking/fn.panic.html) which is exactly what you want, but nightly-only (and it doesn't link a tracking issue, implying that it may be perma-unstable).

---

<div class="post-metadata">

**Author:** ![bjorn3](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/bjorn3/32/2736_2.png) [@bjorn3](https://internals.rust-lang.org/u/bjorn3)\
**Post date:** [October 11, 2025, 10:55pm UTC](https://internals.rust-lang.org/t/allow-panic-macro-to-take-static-strings-as-only-argument/23613/5 "2025-10-11T22:55:05Z")

</div>

> [@ais523](#):
>
> Would [`panic_any`](https://doc.rust-lang.org/stable/std/panic/fn.panic_any.html) work for this use case?

That is not available with no\_std and requires a memory allocation.

---

<div class="post-metadata">

**Author:** ![Reginald](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/reginald/32/13694_2.png) [@Reginald](https://internals.rust-lang.org/u/Reginald)\
**Post date:** [October 12, 2025, 12:25am UTC](https://internals.rust-lang.org/t/allow-panic-macro-to-take-static-strings-as-only-argument/23613/6 "2025-10-12T00:25:21Z")

</div>

I'll go with a panic function, my proposal was mostly just because I assumed it would be the easiest to implement, but it looks like the `panic!` macro used to do that and was specifically designed to not do that in later editions.

It would probably be the easiest and most straightforward to just make a non-nightly version of the nightly panic function, though I also know that features like that can take a while to implement..

Something like `core::panic::panic_with_str()` perhaps?

---

<div class="post-metadata">

**Author:** ![sahnehaeubchen](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/sahnehaeubchen/32/9709_2.png) [@sahnehaeubchen](https://internals.rust-lang.org/u/sahnehaeubchen)\
**Post date:** [October 12, 2025, 7:09am UTC](https://internals.rust-lang.org/t/allow-panic-macro-to-take-static-strings-as-only-argument/23613/7 "2025-10-12T07:09:44Z")

</div>

The previous version of this post was wrong.

`std::panic::panic_any(MY_STATIC_STR)` does the same as `std::panic!(MY_STATIC_STR)` did in editions 2015 and 2018. It does allocate for a place to store the `&str` but it does not invoke `format_args!`. But as bjorn3 pointed out this requires std.

On the other hand, `core::panic(MY_STATIC_STR)`[invokes `format_args!` in all editions where it is allowed](https://github.com/rust-lang/rust/blob/3be68033b67dfc2aa3ae4cfe735aa5805aebae43/library/core/src/panicking.rs#L263).

> **previous version of this post with correction**
>
> From the \*\*2015 and 2018\*\* `core::panic` documentation:
> 
> > core::panic!(x) with a single argument requires that x be &str, but otherwise behaves like std::panic!. In particular, the string need not be a literal, and is not interpreted as a format string.
