You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The panic macro currently does not perform string formatting if
it only passed a single argument which is a string literal.
To be consistent with implicit named arguments and e.g.
`print!("{foo}")`, panic with a single string literal will need
to change to also use string formatting.
If this proposal were accepted, the following (currently invalid) macro invocation:
42
+
If this proposal were captured, the following (currently invalid) macro invocation:
43
43
44
44
format_args!("hello {person}")
45
45
@@ -377,7 +377,50 @@ Please see the discussion on [interpolation](#interpolation) as an alternative t
377
377
# Unresolved questions
378
378
[unresolved-questions]: #unresolved-questions
379
379
380
-
## Should implicit named arguments be accepted for formatting parameters?
380
+
## Interaction with `panic!`
381
+
382
+
The `panic!` macro forwards to `format_args!` for string formatting. For example, the below code compiles on stable Rust today:
383
+
384
+
fn main() {
385
+
panic!("Error code: {code}", code=1);
386
+
// thread 'main' panicked at 'Error code: 1' ...
387
+
}
388
+
389
+
However, in current stable Rust the `panic!` macro does not forward to `format_args!` if there is only a single argument. This would interact poorly with implicit named arguments. In the invocation below, for example, users familiar with implicit named argument capture would expect the panic message to be formatted. Instead, given `panic!`'s current semantics, the panic message would be the unformatted literal:
390
+
391
+
fn main() {
392
+
let code = 1;
393
+
panic!("Error code: {code}");
394
+
// thread 'main' panicked at 'Error code: {code}' ...
395
+
}
396
+
397
+
This semantic of `panic!` has previously been acknowledged as a "papercut", for example in [this Rust issue](https://github.com/rust-lang/rust/issues/22932). However, it has so far been left as-is because changing the design was low priority, and changing it may break existing code.
398
+
399
+
If this RFC were to be implemented, users will very likely expect invoking `panic!` with only a string literal will capture any implicit named arguments. This semantic would quickly become percieved as a major bug rather than a papercut.
400
+
401
+
Implementing this RFC therefore would bring strong motivation for making a small breaking change to `panic!`: when a single argument passed to panic is a string literal, instead of the final panic message being that literal (the current behavior), the final panic message will be the formatted literal, substituting any implicit named arguments denoted in the literal.
402
+
403
+
That is, the desired behavior is as the example below:
404
+
405
+
fn main() {
406
+
let code = 1;
407
+
panic!("Error code: {code}");
408
+
// thread 'main' panicked at 'Error code: 1' ...
409
+
}
410
+
411
+
This change to `panic!` would alter the behavior of existing code (such as the example above). It would also stop some code from being accepted, such as `panic!("{}")`, which is valid code today but would become a compile fail (because this would be a missing positional argument). Crates implementing macros with similar semantics to `panic!` (such as `failure`) may also wish to make changes to their crates in sync with the change to `panic!`. This suggests that this change to `panic!` would perhaps be ideal for release as part of a future Rust edition, say, 2021.
412
+
413
+
The details of this pathway to change panic are open to discussion. Some possible options:
414
+
415
+
*`panic!` itself could be made a builtin macro (which would allow its behavior to vary between editions)
416
+
417
+
* A `$expr:literal` match arm could be added to `panic!`. This arm could forward to a built-in macro which controlled behaviour appropriately.
418
+
419
+
* A new implementation of `panic!` could be written, and switching between them could be done with a new `std::prelude`.
420
+
421
+
Whichever route is chosen, it is agreed that this RFC should not be stabilised unless `format!("{foo}")` and `panic!("{foo}")` can be made consistent with respect to implicit named arguments.
422
+
423
+
## Should implicit named arguments be captured for formatting parameters?
381
424
382
425
Some of the formatting traits can accept additional formatting parameters to control how the argument is displayed. For example, the precision with which to display a floating-point number:
383
426
@@ -388,7 +431,7 @@ It is also possible for the precision to refer to either positional or named arg
388
431
println!("{:.1$}", x, 5);
389
432
println!("{:.prec$}", x, prec=5);
390
433
391
-
As a result of this RFC, formatting parameters could potentially also accept implicit named arguments:
434
+
As a result of this RFC, formatting parameters could potentially also make use implicit named argument capture:
0 commit comments