summaryrefslogtreecommitdiffstats
path: root/library/core/src/macros
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-30 18:31:44 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-30 18:31:44 +0000
commitc23a457e72abe608715ac76f076f47dc42af07a5 (patch)
tree2772049aaf84b5c9d0ed12ec8d86812f7a7904b6 /library/core/src/macros
parentReleasing progress-linux version 1.73.0+dfsg1-1~progress7.99u1. (diff)
downloadrustc-c23a457e72abe608715ac76f076f47dc42af07a5.tar.xz
rustc-c23a457e72abe608715ac76f076f47dc42af07a5.zip
Merging upstream version 1.74.1+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'library/core/src/macros')
-rw-r--r--library/core/src/macros/mod.rs93
-rw-r--r--library/core/src/macros/panic.md30
2 files changed, 118 insertions, 5 deletions
diff --git a/library/core/src/macros/mod.rs b/library/core/src/macros/mod.rs
index 14cc523b0..123661b35 100644
--- a/library/core/src/macros/mod.rs
+++ b/library/core/src/macros/mod.rs
@@ -168,6 +168,94 @@ pub macro assert_matches {
},
}
+/// A macro for defining `#[cfg]` match-like statements.
+///
+/// It is similar to the `if/elif` C preprocessor macro by allowing definition of a cascade of
+/// `#[cfg]` cases, emitting the implementation which matches first.
+///
+/// This allows you to conveniently provide a long list `#[cfg]`'d blocks of code
+/// without having to rewrite each clause multiple times.
+///
+/// Trailing `_` wildcard match arms are **optional** and they indicate a fallback branch when
+/// all previous declarations do not evaluate to true.
+///
+/// # Example
+///
+/// ```
+/// #![feature(cfg_match)]
+///
+/// cfg_match! {
+/// cfg(unix) => {
+/// fn foo() { /* unix specific functionality */ }
+/// }
+/// cfg(target_pointer_width = "32") => {
+/// fn foo() { /* non-unix, 32-bit functionality */ }
+/// }
+/// _ => {
+/// fn foo() { /* fallback implementation */ }
+/// }
+/// }
+/// ```
+#[unstable(feature = "cfg_match", issue = "115585")]
+#[rustc_diagnostic_item = "cfg_match"]
+pub macro cfg_match {
+ // with a final wildcard
+ (
+ $(cfg($initial_meta:meta) => { $($initial_tokens:item)* })+
+ _ => { $($extra_tokens:item)* }
+ ) => {
+ cfg_match! {
+ @__items ();
+ $((($initial_meta) ($($initial_tokens)*)),)+
+ (() ($($extra_tokens)*)),
+ }
+ },
+
+ // without a final wildcard
+ (
+ $(cfg($extra_meta:meta) => { $($extra_tokens:item)* })*
+ ) => {
+ cfg_match! {
+ @__items ();
+ $((($extra_meta) ($($extra_tokens)*)),)*
+ }
+ },
+
+ // Internal and recursive macro to emit all the items
+ //
+ // Collects all the previous cfgs in a list at the beginning, so they can be
+ // negated. After the semicolon is all the remaining items.
+ (@__items ($($_:meta,)*);) => {},
+ (
+ @__items ($($no:meta,)*);
+ (($($yes:meta)?) ($($tokens:item)*)),
+ $($rest:tt,)*
+ ) => {
+ // Emit all items within one block, applying an appropriate #[cfg]. The
+ // #[cfg] will require all `$yes` matchers specified and must also negate
+ // all previous matchers.
+ #[cfg(all(
+ $($yes,)?
+ not(any($($no),*))
+ ))]
+ cfg_match! { @__identity $($tokens)* }
+
+ // Recurse to emit all other items in `$rest`, and when we do so add all
+ // our `$yes` matchers to the list of `$no` matchers as future emissions
+ // will have to negate everything we just matched as well.
+ cfg_match! {
+ @__items ($($no,)* $($yes,)?);
+ $($rest,)*
+ }
+ },
+
+ // Internal macro to make __apply work out right for different match types,
+ // because of how macros match/expand stuff.
+ (@__identity $($tokens:item)*) => {
+ $($tokens)*
+ }
+}
+
/// Asserts that a boolean expression is `true` at runtime.
///
/// This will invoke the [`panic!`] macro if the provided expression cannot be
@@ -849,7 +937,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
@@ -1043,7 +1132,7 @@ pub(crate) mod builtin {
/// expression of type `&'static str` which represents all of the literals
/// concatenated left-to-right.
///
- /// Integer and floating point literals are stringified in order to be
+ /// Integer and floating point literals are [stringified](core::stringify) in order to be
/// concatenated.
///
/// # Examples
diff --git a/library/core/src/macros/panic.md b/library/core/src/macros/panic.md
index 8b549e187..60100c265 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.
@@ -55,7 +56,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
@@ -64,6 +65,29 @@ 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
+
+Behavior of the panic macros changed over editions.
+
+## 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
```should_panic