//! 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`)). /// /// This macro uses the same syntax as [`format!`], but writes to the standard output instead. /// 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); }}; }