mirror of
https://github.com/rust-lang/rust.git
synced 2026-02-15 15:43:54 +00:00
rustdoc: Resolve doc links referring to `macro_rules` items cc https://github.com/rust-lang/rust/issues/81633 UPD: the fallback to considering *all* `macro_rules` in the crate for unresolved names is not removed in this PR, it will be removed separately and will be run through crater.
334 lines
9.5 KiB
Rust
334 lines
9.5 KiB
Rust
//! Standard library macros
|
|
//!
|
|
//! This module contains a set of macros which are exported from the standard
|
|
//! library. Each macro is available for use when linking against the standard
|
|
//! library.
|
|
|
|
#[doc = include_str!("../../core/src/macros/panic.md")]
|
|
#[macro_export]
|
|
#[rustc_builtin_macro(std_panic)]
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
#[allow_internal_unstable(edition_panic)]
|
|
#[cfg_attr(not(test), rustc_diagnostic_item = "std_panic_macro")]
|
|
macro_rules! panic {
|
|
// Expands to either `$crate::panic::panic_2015` or `$crate::panic::panic_2021`
|
|
// depending on the edition of the caller.
|
|
($($arg:tt)*) => {
|
|
/* compiler built-in */
|
|
};
|
|
}
|
|
|
|
/// Prints to the standard output.
|
|
///
|
|
/// Equivalent to the [`println!`] macro except that a newline is not printed at
|
|
/// the end of the message.
|
|
///
|
|
/// Note that stdout is frequently line-buffered by default so it may be
|
|
/// necessary to use [`io::stdout().flush()`][flush] to ensure the output is emitted
|
|
/// immediately.
|
|
///
|
|
/// Use `print!` only for the primary output of your program. Use
|
|
/// [`eprint!`] instead to print error and progress messages.
|
|
///
|
|
/// [flush]: crate::io::Write::flush
|
|
/// [`println!`]: crate::println
|
|
/// [`eprint!`]: crate::eprint
|
|
///
|
|
/// # Panics
|
|
///
|
|
/// Panics if writing to `io::stdout()` fails.
|
|
///
|
|
/// # Examples
|
|
///
|
|
/// ```
|
|
/// use std::io::{self, Write};
|
|
///
|
|
/// print!("this ");
|
|
/// print!("will ");
|
|
/// print!("be ");
|
|
/// print!("on ");
|
|
/// print!("the ");
|
|
/// print!("same ");
|
|
/// print!("line ");
|
|
///
|
|
/// io::stdout().flush().unwrap();
|
|
///
|
|
/// print!("this string has a newline, why not choose println! instead?\n");
|
|
///
|
|
/// io::stdout().flush().unwrap();
|
|
/// ```
|
|
#[macro_export]
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
#[cfg_attr(not(test), rustc_diagnostic_item = "print_macro")]
|
|
#[allow_internal_unstable(print_internals)]
|
|
macro_rules! print {
|
|
($($arg:tt)*) => {
|
|
$crate::io::_print($crate::format_args!($($arg)*))
|
|
};
|
|
}
|
|
|
|
/// Prints to the standard output, with a newline.
|
|
///
|
|
/// On all platforms, the newline is the LINE FEED character (`\n`/`U+000A`) alone
|
|
/// (no additional CARRIAGE RETURN (`\r`/`U+000D`)).
|
|
///
|
|
/// Use the [`format!`] syntax to write data to the standard output.
|
|
/// See [`std::fmt`] for more information.
|
|
///
|
|
/// Use `println!` only for the primary output of your program. Use
|
|
/// [`eprintln!`] instead to print error and progress messages.
|
|
///
|
|
/// [`std::fmt`]: crate::fmt
|
|
/// [`eprintln!`]: crate::eprintln
|
|
///
|
|
/// # Panics
|
|
///
|
|
/// Panics if writing to [`io::stdout`] fails.
|
|
///
|
|
/// [`io::stdout`]: crate::io::stdout
|
|
///
|
|
/// # Examples
|
|
///
|
|
/// ```
|
|
/// println!(); // prints just a newline
|
|
/// println!("hello there!");
|
|
/// println!("format {} arguments", "some");
|
|
/// ```
|
|
#[macro_export]
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
#[cfg_attr(not(test), rustc_diagnostic_item = "println_macro")]
|
|
#[allow_internal_unstable(print_internals, format_args_nl)]
|
|
macro_rules! println {
|
|
() => {
|
|
$crate::print!("\n")
|
|
};
|
|
($($arg:tt)*) => {{
|
|
$crate::io::_print($crate::format_args_nl!($($arg)*));
|
|
}};
|
|
}
|
|
|
|
/// Prints to the standard error.
|
|
///
|
|
/// Equivalent to the [`print!`] macro, except that output goes to
|
|
/// [`io::stderr`] instead of [`io::stdout`]. See [`print!`] for
|
|
/// example usage.
|
|
///
|
|
/// Use `eprint!` only for error and progress messages. Use `print!`
|
|
/// instead for the primary output of your program.
|
|
///
|
|
/// [`io::stderr`]: crate::io::stderr
|
|
/// [`io::stdout`]: crate::io::stdout
|
|
///
|
|
/// # Panics
|
|
///
|
|
/// Panics if writing to `io::stderr` fails.
|
|
///
|
|
/// # Examples
|
|
///
|
|
/// ```
|
|
/// eprint!("Error: Could not complete task");
|
|
/// ```
|
|
#[macro_export]
|
|
#[stable(feature = "eprint", since = "1.19.0")]
|
|
#[cfg_attr(not(test), rustc_diagnostic_item = "eprint_macro")]
|
|
#[allow_internal_unstable(print_internals)]
|
|
macro_rules! eprint {
|
|
($($arg:tt)*) => {
|
|
$crate::io::_eprint($crate::format_args!($($arg)*))
|
|
};
|
|
}
|
|
|
|
/// Prints to the standard error, with a newline.
|
|
///
|
|
/// Equivalent to the [`println!`] macro, except that output goes to
|
|
/// [`io::stderr`] instead of [`io::stdout`]. See [`println!`] for
|
|
/// example usage.
|
|
///
|
|
/// Use `eprintln!` only for error and progress messages. Use `println!`
|
|
/// instead for the primary output of your program.
|
|
///
|
|
/// [`io::stderr`]: crate::io::stderr
|
|
/// [`io::stdout`]: crate::io::stdout
|
|
/// [`println!`]: crate::println
|
|
///
|
|
/// # Panics
|
|
///
|
|
/// Panics if writing to `io::stderr` fails.
|
|
///
|
|
/// # Examples
|
|
///
|
|
/// ```
|
|
/// eprintln!("Error: Could not complete task");
|
|
/// ```
|
|
#[macro_export]
|
|
#[stable(feature = "eprint", since = "1.19.0")]
|
|
#[cfg_attr(not(test), rustc_diagnostic_item = "eprintln_macro")]
|
|
#[allow_internal_unstable(print_internals, format_args_nl)]
|
|
macro_rules! eprintln {
|
|
() => {
|
|
$crate::eprint!("\n")
|
|
};
|
|
($($arg:tt)*) => {{
|
|
$crate::io::_eprint($crate::format_args_nl!($($arg)*));
|
|
}};
|
|
}
|
|
|
|
/// Prints and returns the value of a given expression for quick and dirty
|
|
/// debugging.
|
|
///
|
|
/// An example:
|
|
///
|
|
/// ```rust
|
|
/// let a = 2;
|
|
/// let b = dbg!(a * 2) + 1;
|
|
/// // ^-- prints: [src/main.rs:2] a * 2 = 4
|
|
/// assert_eq!(b, 5);
|
|
/// ```
|
|
///
|
|
/// The macro works by using the `Debug` implementation of the type of
|
|
/// the given expression to print the value to [stderr] along with the
|
|
/// source location of the macro invocation as well as the source code
|
|
/// of the expression.
|
|
///
|
|
/// Invoking the macro on an expression moves and takes ownership of it
|
|
/// before returning the evaluated expression unchanged. If the type
|
|
/// of the expression does not implement `Copy` and you don't want
|
|
/// to give up ownership, you can instead borrow with `dbg!(&expr)`
|
|
/// for some expression `expr`.
|
|
///
|
|
/// The `dbg!` macro works exactly the same in release builds.
|
|
/// This is useful when debugging issues that only occur in release
|
|
/// builds or when debugging in release mode is significantly faster.
|
|
///
|
|
/// Note that the macro is intended as a debugging tool and therefore you
|
|
/// should avoid having uses of it in version control for long periods
|
|
/// (other than in tests and similar).
|
|
/// Debug output from production code is better done with other facilities
|
|
/// such as the [`debug!`] macro from the [`log`] crate.
|
|
///
|
|
/// # Stability
|
|
///
|
|
/// The exact output printed by this macro should not be relied upon
|
|
/// and is subject to future changes.
|
|
///
|
|
/// # Panics
|
|
///
|
|
/// Panics if writing to `io::stderr` fails.
|
|
///
|
|
/// # Further examples
|
|
///
|
|
/// With a method call:
|
|
///
|
|
/// ```rust
|
|
/// fn foo(n: usize) {
|
|
/// if let Some(_) = dbg!(n.checked_sub(4)) {
|
|
/// // ...
|
|
/// }
|
|
/// }
|
|
///
|
|
/// foo(3)
|
|
/// ```
|
|
///
|
|
/// This prints to [stderr]:
|
|
///
|
|
/// ```text,ignore
|
|
/// [src/main.rs:4] n.checked_sub(4) = None
|
|
/// ```
|
|
///
|
|
/// Naive factorial implementation:
|
|
///
|
|
/// ```rust
|
|
/// fn factorial(n: u32) -> u32 {
|
|
/// if dbg!(n <= 1) {
|
|
/// dbg!(1)
|
|
/// } else {
|
|
/// dbg!(n * factorial(n - 1))
|
|
/// }
|
|
/// }
|
|
///
|
|
/// dbg!(factorial(4));
|
|
/// ```
|
|
///
|
|
/// This prints to [stderr]:
|
|
///
|
|
/// ```text,ignore
|
|
/// [src/main.rs:3] n <= 1 = false
|
|
/// [src/main.rs:3] n <= 1 = false
|
|
/// [src/main.rs:3] n <= 1 = false
|
|
/// [src/main.rs:3] n <= 1 = true
|
|
/// [src/main.rs:4] 1 = 1
|
|
/// [src/main.rs:5] n * factorial(n - 1) = 2
|
|
/// [src/main.rs:5] n * factorial(n - 1) = 6
|
|
/// [src/main.rs:5] n * factorial(n - 1) = 24
|
|
/// [src/main.rs:11] factorial(4) = 24
|
|
/// ```
|
|
///
|
|
/// The `dbg!(..)` macro moves the input:
|
|
///
|
|
/// ```compile_fail
|
|
/// /// A wrapper around `usize` which importantly is not Copyable.
|
|
/// #[derive(Debug)]
|
|
/// struct NoCopy(usize);
|
|
///
|
|
/// let a = NoCopy(42);
|
|
/// let _ = dbg!(a); // <-- `a` is moved here.
|
|
/// let _ = dbg!(a); // <-- `a` is moved again; error!
|
|
/// ```
|
|
///
|
|
/// You can also use `dbg!()` without a value to just print the
|
|
/// file and line whenever it's reached.
|
|
///
|
|
/// Finally, if you want to `dbg!(..)` multiple values, it will treat them as
|
|
/// a tuple (and return it, too):
|
|
///
|
|
/// ```
|
|
/// assert_eq!(dbg!(1usize, 2u32), (1, 2));
|
|
/// ```
|
|
///
|
|
/// However, a single argument with a trailing comma will still not be treated
|
|
/// as a tuple, following the convention of ignoring trailing commas in macro
|
|
/// invocations. You can use a 1-tuple directly if you need one:
|
|
///
|
|
/// ```
|
|
/// assert_eq!(1, dbg!(1u32,)); // trailing comma ignored
|
|
/// assert_eq!((1,), dbg!((1u32,))); // 1-tuple
|
|
/// ```
|
|
///
|
|
/// [stderr]: https://en.wikipedia.org/wiki/Standard_streams#Standard_error_(stderr)
|
|
/// [`debug!`]: https://docs.rs/log/*/log/macro.debug.html
|
|
/// [`log`]: https://crates.io/crates/log
|
|
#[macro_export]
|
|
#[cfg_attr(not(test), rustc_diagnostic_item = "dbg_macro")]
|
|
#[stable(feature = "dbg_macro", since = "1.32.0")]
|
|
macro_rules! dbg {
|
|
// NOTE: We cannot use `concat!` to make a static string as a format argument
|
|
// of `eprintln!` because `file!` could contain a `{` or
|
|
// `$val` expression could be a block (`{ .. }`), in which case the `eprintln!`
|
|
// will be malformed.
|
|
() => {
|
|
$crate::eprintln!("[{}:{}]", $crate::file!(), $crate::line!())
|
|
};
|
|
($val:expr $(,)?) => {
|
|
// Use of `match` here is intentional because it affects the lifetimes
|
|
// of temporaries - https://stackoverflow.com/a/48732525/1063961
|
|
match $val {
|
|
tmp => {
|
|
$crate::eprintln!("[{}:{}] {} = {:#?}",
|
|
$crate::file!(), $crate::line!(), $crate::stringify!($val), &tmp);
|
|
tmp
|
|
}
|
|
}
|
|
};
|
|
($($val:expr),+ $(,)?) => {
|
|
($($crate::dbg!($val)),+,)
|
|
};
|
|
}
|
|
|
|
#[cfg(test)]
|
|
macro_rules! assert_approx_eq {
|
|
($a:expr, $b:expr) => {{
|
|
let (a, b) = (&$a, &$b);
|
|
assert!((*a - *b).abs() < 1.0e-6, "{} is not approximately equal to {}", *a, *b);
|
|
}};
|
|
}
|