From 11167071db3ae7a6d0d5b116b07c911717f902e2 Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Thu, 28 Apr 2022 12:11:04 +0100 Subject: [PATCH 1/5] panic macro: Document edition differences Having a section for this inspired by the docs for array::IntoIterator --- library/core/src/macros/panic.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/library/core/src/macros/panic.md b/library/core/src/macros/panic.md index 8b549e187ba..e303893b391 100644 --- a/library/core/src/macros/panic.md +++ b/library/core/src/macros/panic.md @@ -64,6 +64,25 @@ For more detailed information about error handling check out the [book] or the If the main thread panics it will terminate all your threads and end your program with code `101`. +# Editions + +In Rust Editions prior to 2021, `std::panic!(x)` with a single +argument is equivalent to +[`std::panic::panic_any(x)`](../std/panic/fn.panic_any.html). +This is true even if the argument is a string literal. + +For example, in Rust 2015 `panic!("problem: {reason}")` panics with a +payload of literally `"problem: {reason}"` (a `&'static str`), which +is probably not what was intended. In current Rust this usage +captures and formats a variable `reason` from the surrounding scope. + +In Rust editions prior to 2021, `core::panic!(x)` requires that +`x` be `&str`, but does not require it to be a literal. In Rust 2021, +these cases must be written `panic!("{}", x)`. + +In Rust 2021 and later, `panic!` always requires a format string and +the applicable format arguments, and is the same in `core` and `std`. + # Examples ```should_panic From 55159e80adf82f733f81cbcb7ba9fd95dbca516d Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Thu, 28 Apr 2022 14:33:30 +0100 Subject: [PATCH 2/5] print macros: add xrefs to format syntax documentation --- library/std/src/macros.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/library/std/src/macros.rs b/library/std/src/macros.rs index ba1b8cbfa56..34b8b6b97b5 100644 --- a/library/std/src/macros.rs +++ b/library/std/src/macros.rs @@ -41,6 +41,9 @@ macro_rules! panic { /// Use `print!` only for the primary output of your program. Use /// [`eprint!`] instead to print error and progress messages. /// +/// See [the formatting documentation in `std::fmt`](../std/fmt/index.html) +/// for details of the macro argument syntax. +/// /// [flush]: crate::io::Write::flush /// [`println!`]: crate::println /// [`eprint!`]: crate::eprint @@ -103,6 +106,9 @@ macro_rules! print { /// Use `println!` only for the primary output of your program. Use /// [`eprintln!`] instead to print error and progress messages. /// +/// See [the formatting documentation in `std::fmt`](../std/fmt/index.html) +/// for details of the macro argument syntax. +/// /// [`std::fmt`]: crate::fmt /// [`eprintln!`]: crate::eprintln /// [lock]: crate::io::Stdout @@ -150,6 +156,9 @@ macro_rules! println { /// [`io::stderr`]: crate::io::stderr /// [`io::stdout`]: crate::io::stdout /// +/// See [the formatting documentation in `std::fmt`](../std/fmt/index.html) +/// for details of the macro argument syntax. +/// /// # Panics /// /// Panics if writing to `io::stderr` fails. @@ -181,6 +190,9 @@ macro_rules! eprint { /// Use `eprintln!` only for error and progress messages. Use `println!` /// instead for the primary output of your program. /// +/// See [the formatting documentation in `std::fmt`](../std/fmt/index.html) +/// for details of the macro argument syntax. +/// /// [`io::stderr`]: crate::io::stderr /// [`io::stdout`]: crate::io::stdout /// [`println!`]: crate::println From 2ec8b6b50fddf481f3ed11201a142f09481a81c6 Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Thu, 28 Apr 2022 14:29:07 +0100 Subject: [PATCH 3/5] panic macro: Link directly to format syntax, not to format! --- library/core/src/macros/panic.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/core/src/macros/panic.md b/library/core/src/macros/panic.md index e303893b391..e883273d1c8 100644 --- a/library/core/src/macros/panic.md +++ b/library/core/src/macros/panic.md @@ -9,7 +9,7 @@ tests. `panic!` is closely tied with the `unwrap` method of both `panic!` when they are set to [`None`] or [`Err`] variants. When using `panic!()` you can specify a string payload, that is built using -the [`format!`] syntax. That payload is used when injecting the panic into +the [`format!` syntax]. That payload is used when injecting the panic into the calling Rust thread, causing the thread to panic entirely. The behavior of the default `std` hook, i.e. the code that runs directly @@ -55,7 +55,7 @@ For more detailed information about error handling check out the [book] or the [`panic_any`]: ../std/panic/fn.panic_any.html [`Box`]: ../std/boxed/struct.Box.html [`Any`]: crate::any::Any -[`format!`]: ../std/macro.format.html +[`format!` syntax]: ../std/fmt/index.html [book]: ../book/ch09-00-error-handling.html [`std::result`]: ../std/result/index.html From 39c642e3d2c5f5d5e6e6b65ccd01439ef736c277 Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Thu, 28 Apr 2022 14:27:57 +0100 Subject: [PATCH 4/5] format, format_args: Make xref to std::fmt much more prominent That xref contains the actual documentation for what format! does. It should be very prominent - particularly, more so than the other links. --- library/alloc/src/macros.rs | 7 ++++--- library/core/src/macros/mod.rs | 3 ++- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/library/alloc/src/macros.rs b/library/alloc/src/macros.rs index 4c6ae8f2579..3f19561e1ac 100644 --- a/library/alloc/src/macros.rs +++ b/library/alloc/src/macros.rs @@ -79,10 +79,12 @@ macro_rules! vec { /// /// The first argument `format!` receives is a format string. This must be a string /// literal. The power of the formatting string is in the `{}`s contained. -/// /// Additional parameters passed to `format!` replace the `{}`s within the /// formatting string in the order given unless named or positional parameters -/// are used; see [`std::fmt`] for more information. +/// are used. +/// +/// See [the formatting syntax documentation in `std::fmt`](../std/fmt/index.html) +/// for details. /// /// A common use for `format!` is concatenation and interpolation of strings. /// The same convention is used with [`print!`] and [`write!`] macros, @@ -91,7 +93,6 @@ macro_rules! vec { /// To convert a single value to a string, use the [`to_string`] method. This /// will use the [`Display`] formatting trait. /// -/// [`std::fmt`]: ../std/fmt/index.html /// [`print!`]: ../std/macro.print.html /// [`write!`]: core::write /// [`to_string`]: crate::string::ToString diff --git a/library/core/src/macros/mod.rs b/library/core/src/macros/mod.rs index 14cc523b0c1..46628bcea00 100644 --- a/library/core/src/macros/mod.rs +++ b/library/core/src/macros/mod.rs @@ -849,7 +849,8 @@ pub(crate) mod builtin { /// assert_eq!(display, debug); /// ``` /// - /// For more information, see the documentation in [`std::fmt`]. + /// See [the formatting documentation in `std::fmt`](../std/fmt/index.html) + /// for details of the macro argument syntax, and further information. /// /// [`Display`]: crate::fmt::Display /// [`Debug`]: crate::fmt::Debug From 5016695357b37d56e68212b42baf97cc151d9b0a Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 28 Aug 2023 11:54:20 +0200 Subject: [PATCH 5/5] improve panic.md edition disucssion, and nits --- library/core/src/macros/panic.md | 33 ++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/library/core/src/macros/panic.md b/library/core/src/macros/panic.md index e883273d1c8..60100c2655a 100644 --- a/library/core/src/macros/panic.md +++ b/library/core/src/macros/panic.md @@ -8,8 +8,8 @@ tests. `panic!` is closely tied with the `unwrap` method of both [`Option`][ounwrap] and [`Result`][runwrap] enums. Both implementations call `panic!` when they are set to [`None`] or [`Err`] variants. -When using `panic!()` you can specify a string payload, that is built using -the [`format!` syntax]. That payload is used when injecting the panic into +When using `panic!()` you can specify a string payload that is built using +[formatting syntax]. That payload is used when injecting the panic into the calling Rust thread, causing the thread to panic entirely. The behavior of the default `std` hook, i.e. the code that runs directly @@ -18,6 +18,7 @@ after the panic is invoked, is to print the message payload to call. You can override the panic hook using [`std::panic::set_hook()`]. Inside the hook a panic can be accessed as a `&dyn Any + Send`, which contains either a `&str` or `String` for regular `panic!()` invocations. +(Whether a particular invocation contains the payload at type `&str` or `String` is unspecified and can change.) To panic with a value of another other type, [`panic_any`] can be used. See also the macro [`compile_error!`], for raising errors during compilation. @@ -66,22 +67,26 @@ program with code `101`. # Editions -In Rust Editions prior to 2021, `std::panic!(x)` with a single -argument is equivalent to -[`std::panic::panic_any(x)`](../std/panic/fn.panic_any.html). -This is true even if the argument is a string literal. +Behavior of the panic macros changed over editions. -For example, in Rust 2015 `panic!("problem: {reason}")` panics with a -payload of literally `"problem: {reason}"` (a `&'static str`), which -is probably not what was intended. In current Rust this usage -captures and formats a variable `reason` from the surrounding scope. - -In Rust editions prior to 2021, `core::panic!(x)` requires that -`x` be `&str`, but does not require it to be a literal. In Rust 2021, -these cases must be written `panic!("{}", x)`. +## 2021 and later In Rust 2021 and later, `panic!` always requires a format string and the applicable format arguments, and is the same in `core` and `std`. +Use [`std::panic::panic_any(x)`](../std/panic/fn.panic_any.html) to +panic with an arbitrary payload. + +## 2018 and 2015 + +In Rust Editions prior to 2021, `std::panic!(x)` with a single +argument directly uses that argument as a payload. +This is true even if the argument is a string literal. +For example, `panic!("problem: {reason}")` panics with a +payload of literally `"problem: {reason}"` (a `&'static str`). + +`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. # Examples