Arguments::as_str allows code to handle argument-less fmt::Arguments like format_args!("literal") specially by not pulling in any formatting code.
We should investigate if we can improve format_args!("hello: {}", "literal") to result in the same trivial fmt::Arguments as format_args!("hello: literal"), such that any .as_str()-based optimizations are also available for it.
That could also make things like panic!("{}", "message"); work with const_panic, removing the need for panic!(CONST_STR).
This makes panic!("hello") exactly as cheap (and const) as panic!("{}", "hello"), which is also important for #78088 to make sure there are no downsides to its suggestions.
It'd also reduce the need for using concat!(..), since it'd no longer be less efficient to add a {} placeholder to concat literals in a formatting string instead.
As a bonus: format_args!("a: {}", format_args!("b: {}", ..)) could maybe also improved to produce the same as format_args!("a: b: {}", ..).
Assigning to myself to investigate some time Soonâ„¢.
Do we expect this kind of thing to actually happen right now? It seems like we should if anything just lint against it, and the workaround for the single-arg-panic string could be to do panic::panic_any("{}") instead of panic!("{}", "{}").
Do we expect this kind of thing to actually happen right now? It seems like we should if anything just lint against it, and the workaround for the single-arg-panic string could be to do
panic::panic_any("{}")instead ofpanic!("{}", "{}").
would that actually work in #![no_std]? I don't think there's a core::panic::panic_any...
Do we expect this kind of thing to actually happen right now?
If you're asking if anyone has time to implement this: Yes, I believe I can find the time for this some time soon.
the workaround for the single-arg-panic string could be to do
panic::panic_any("{}")instead ofpanic!("{}", "{}").
panic_any will only exist in std, not core. The bloat problem is mostly a problem in no_std programs.
If you're asking if anyone has time to implement this
Sorry, I'm asking if we expect that something like println!("hello: {}", "world") actually exists in codebases in significant numbers.
panic_any will only exist in std, not core. The bloat problem is mostly a problem in no_std programs.
Suggesting core::panicking::panic would be the thing then I suppose.
I'm asking if we expect that something like
println!("hello: {}", "world")actually exists in codebases in significant numbers.
Ah. I think it mostly happens as the result of macro expansion. E.g. error!("x") expanding to eprintln!("error: {}", "x"). Though, many macros use concat!() and panic(thing) directly. E.g. println!("Failure: {}", stringify!(expr)) is sometimes println!(concat!("Failure: ", stringify!(expr)) (which then breaks for expressions with braces). Or panic!("error: {}", format_args!(fmt, args...)) is sometimes written panic!(concat!("error: ", fmt), args...), etc.
Suggesting
core::panicking::panicwould be the thing then I suppose.
That one requires a 'static lifetime, so then the suggestion would be different for 'static strings and non-'static strings. Would be nice if it didn't require a special case. (It'd also require that function to become stable.)
Anyway, I opened this issue just as a reminder to investigate the possibility, not because I think we should definitely do this. There are good ways to avoid the need for this like you mention (core::panicking::panic), but it might be nice if no special cases were necessary while implementing macros like assert!(), and "{}", ".." was just as efficient as any other solution.
My observations have consistently suggested that people use format! or write! for seemingly "trivial" reasons All The Time because when you start with println! it's what feels like the most natural and easiest way. And then they do wrap it in other macros, yes, so it is best to try to take the effort to reduce the amount of overhead going on here.
Most helpful comment
Ah. I think it mostly happens as the result of macro expansion. E.g.
error!("x")expanding toeprintln!("error: {}", "x"). Though, many macros useconcat!()andpanic(thing)directly. E.g.println!("Failure: {}", stringify!(expr))is sometimesprintln!(concat!("Failure: ", stringify!(expr))(which then breaks for expressions with braces). Orpanic!("error: {}", format_args!(fmt, args...))is sometimes writtenpanic!(concat!("error: ", fmt), args...), etc.That one requires a
'staticlifetime, so then the suggestion would be different for'staticstrings and non-'staticstrings. Would be nice if it didn't require a special case. (It'd also require that function to become stable.)Anyway, I opened this issue just as a reminder to investigate the possibility, not because I think we should definitely do this. There are good ways to avoid the need for this like you mention (
core::panicking::panic), but it might be nice if no special cases were necessary while implementing macros likeassert!(), and"{}", ".."was just as efficient as any other solution.