//! Standard library macros //! //! This modules contains a set of macros which are exported from the standard //! library. Each macro is available for use when linking against the standard //! library. /// Panics the current thread. /// /// This allows a program to terminate immediately and provide feedback /// to the caller of the program. `panic!` should be used when a program reaches /// an unrecoverable state. /// /// This macro is the perfect way to assert conditions in example code and in /// tests. `panic!` is closely tied with the `unwrap` method of both [`Option`] /// and [`Result`][runwrap] enums. Both implementations call `panic!` when they are set /// to None or Err variants. /// /// This macro is used to inject panic into a Rust thread, causing the thread to /// panic entirely. Each thread's panic can be reaped as the `Box` type, /// and the single-argument form of the `panic!` macro will be the value which /// is transmitted. /// /// [`Result`] enum is often a better solution for recovering from errors than /// using the `panic!` macro. This macro should be used to avoid proceeding using /// incorrect values, such as from external sources. Detailed information about /// error handling is found in the [book]. /// /// The multi-argument form of this macro panics with a string and has the /// [`format!`] syntax for building a string. /// /// See also the macro [`compile_error!`], for raising errors during compilation. /// /// [runwrap]: ../std/result/enum.Result.html#method.unwrap /// [`Option`]: ../std/option/enum.Option.html#method.unwrap /// [`Result`]: ../std/result/enum.Result.html /// [`format!`]: ../std/macro.format.html /// [`compile_error!`]: ../std/macro.compile_error.html /// [book]: ../book/ch09-00-error-handling.html /// /// # Current implementation /// /// If the main thread panics it will terminate all your threads and end your /// program with code `101`. /// /// # Examples /// /// ```should_panic /// # #![allow(unreachable_code)] /// panic!(); /// panic!("this is a terrible mistake!"); /// panic!(4); // panic with the value of 4 to be collected elsewhere /// panic!("this is a {} {message}", "fancy", message = "message"); /// ``` #[macro_export] #[stable(feature = "rust1", since = "1.0.0")] #[allow_internal_unstable(__rust_unstable_column, libstd_sys_internals)] macro_rules! panic { () => ({ $crate::panic!("explicit panic") }); ($msg:expr) => ({ $crate::rt::begin_panic($msg, &(file!(), line!(), __rust_unstable_column!())) }); ($msg:expr,) => ({ $crate::panic!($msg) }); ($fmt:expr, $($arg:tt)+) => ({ $crate::rt::begin_panic_fmt(&format_args!($fmt, $($arg)+), &(file!(), line!(), __rust_unstable_column!())) }); } /// 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. /// /// [`println!`]: ../std/macro.println.html /// [flush]: ../std/io/trait.Write.html#tymethod.flush /// [`eprint!`]: ../std/macro.eprint.html /// /// # 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")] #[allow_internal_unstable(print_internals)] macro_rules! print { ($($arg:tt)*) => ($crate::io::_print(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. /// /// [`format!`]: ../std/macro.format.html /// [`std::fmt`]: ../std/fmt/index.html /// [`eprintln!`]: ../std/macro.eprintln.html /// # Panics /// /// Panics if writing to `io::stdout` fails. /// /// # Examples /// /// ``` /// println!(); // prints just a newline /// println!("hello there!"); /// println!("format {} arguments", "some"); /// ``` #[macro_export] #[stable(feature = "rust1", since = "1.0.0")] #[allow_internal_unstable(print_internals, format_args_nl)] macro_rules! println { () => ($crate::print!("\n")); ($($arg:tt)*) => ({ $crate::io::_print(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`]: ../std/io/struct.Stderr.html /// [`print!`]: ../std/macro.print.html /// /// # Panics /// /// Panics if writing to `io::stderr` fails. /// /// # Examples /// /// ``` /// eprint!("Error: Could not complete task"); /// ``` #[macro_export] #[stable(feature = "eprint", since = "1.19.0")] #[allow_internal_unstable(print_internals)] macro_rules! eprint { ($($arg:tt)*) => ($crate::io::_eprint(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`]: ../std/io/struct.Stderr.html /// [`println!`]: ../std/macro.println.html /// /// # Panics /// /// Panics if writing to `io::stderr` fails. /// /// # Examples /// /// ``` /// eprintln!("Error: Could not complete task"); /// ``` #[macro_export] #[stable(feature = "eprint", since = "1.19.0")] #[allow_internal_unstable(print_internals, format_args_nl)] macro_rules! eprintln { () => ($crate::eprint!("\n")); ($($arg:tt)*) => ({ $crate::io::_eprint(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 longer periods. /// Use cases involving debug output that should be added to version control /// are better served by macros such as [`debug!`] 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] #[stable(feature = "dbg_macro", since = "1.32.0")] macro_rules! dbg { () => { $crate::eprintln!("[{}:{}]", file!(), 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!("[{}:{}] {} = {:#?}", file!(), line!(), stringify!($val), &tmp); tmp } } }; // Trailing comma with single argument is ignored ($val:expr,) => { $crate::dbg!($val) }; ($($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); }) }