Skip to main content

std/
macros.rs

1//! Standard library macros
2//!
3//! This module contains a set of macros which are exported from the standard
4//! library. Each macro is available for use when linking against the standard
5//! library.
6// ignore-tidy-dbg
7
8#[cfg(test)]
9mod tests;
10
11#[doc = "Panics the current thread.\n\nThis allows a program to terminate immediately and provide feedback\nto the caller of the program.\n\nThis macro is the perfect way to assert conditions in example code and in\ntests. `panic!` is closely tied with the `unwrap` method of both\n[`Option`][ounwrap] and [`Result`][runwrap] enums. Both implementations call\n`panic!` when they are set to [`None`] or [`Err`] variants.\n\nWhen using `panic!()` you can specify a string payload that is built using\n[formatting syntax]. That payload is used when injecting the panic into\nthe calling Rust thread, causing the thread to panic entirely.\n\nThe behavior of the default `std` hook, i.e. the code that runs directly\nafter the panic is invoked, is to print the message payload to\n`stderr` along with the file/line/column information of the `panic!()`\ncall. You can override the panic hook using [`std::panic::set_hook()`].\nInside the hook a panic can be accessed as a `&dyn Any + Send`,\nwhich contains either a `&str` or `String` for regular `panic!()` invocations.\n(Whether a particular invocation contains the payload at type `&str` or `String` is unspecified and can change.)\nTo panic with a value of another other type, [`panic_any`] can be used.\n\nSee also the macro [`compile_error!`], for raising errors during compilation.\n\n# When to use `panic!` vs `Result`\n\nThe Rust language provides two complementary systems for constructing /\nrepresenting, reporting, propagating, reacting to, and discarding errors. These\nresponsibilities are collectively known as \"error handling.\" `panic!` and\n`Result` are similar in that they are each the primary interface of their\nrespective error handling systems; however, the meaning these interfaces attach\nto their errors and the responsibilities they fulfill within their respective\nerror handling systems differ.\n\nThe `panic!` macro is used to construct errors that represent a bug that has\nbeen detected in your program. With `panic!` you provide a message that\ndescribes the bug and the language then constructs an error with that message,\nreports it, and propagates it for you.\n\n`Result` on the other hand is used to wrap other types that represent either\nthe successful result of some computation, `Ok(T)`, or error types that\nrepresent an anticipated runtime failure mode of that computation, `Err(E)`.\n`Result` is used alongside user defined types which represent the various\nanticipated runtime failure modes that the associated computation could\nencounter. `Result` must be propagated manually, often with the help of the\n`?` operator and `Try` trait, and they must be reported manually, often with\nthe help of the `Error` trait.\n\nFor more detailed information about error handling check out the [book] or the\n[`std::result`] module docs.\n\n[ounwrap]: Option::unwrap\n[runwrap]: Result::unwrap\n[`std::panic::set_hook()`]: ../std/panic/fn.set_hook.html\n[`panic_any`]: ../std/panic/fn.panic_any.html\n[`Box`]: ../std/boxed/struct.Box.html\n[`Any`]: crate::any::Any\n[formatting syntax]: ../std/fmt/index.html\n[book]: ../book/ch09-00-error-handling.html\n[`std::result`]: ../std/result/index.html\n\n# Current implementation\n\nIf the main thread panics it will terminate all your threads and end your\nprogram with code `101`.\n\n# Editions\n\nBehavior of the panic macros changed over editions.\n\n## 2021 and later\n\nIn Rust 2021 and later, `panic!` always requires a format string and\nthe applicable format arguments, and is the same in `core` and `std`.\nUse [`std::panic::panic_any(x)`](../std/panic/fn.panic_any.html) to\npanic with an arbitrary payload.\n\n## 2018 and 2015\n\nIn Rust Editions prior to 2021, `std::panic!(x)` with a single\nargument directly uses that argument as a payload.\nThis is true even if the argument is a string literal.\nFor example, `panic!(\"problem: {reason}\")` panics with a\npayload of literally `\"problem: {reason}\"` (a `&\'static str`).\n\n`core::panic!(x)` with a single argument requires that `x` be `&str`,\nbut otherwise behaves like `std::panic!`. In particular, the string\nneed not be a literal, and is not interpreted as a format string.\n\n# Examples\n\n```should_panic\n# #![allow(unreachable_code)]\npanic!();\npanic!(\"this is a terrible mistake!\");\npanic!(\"this is a {} {message}\", \"fancy\", message = \"message\");\nstd::panic::panic_any(4); // panic with the value of 4 to be collected elsewhere\n```\n"include_str!("../../core/src/macros/panic.md")]
12#[macro_export]
13#[rustc_builtin_macro(std_panic)]
14#[stable(feature = "rust1", since = "1.0.0")]
15#[allow_internal_unstable(edition_panic)]
16#[cfg_attr(not(test), rustc_diagnostic_item = "std_panic_macro")]
17macro_rules! panic {
18    // Expands to either `$crate::panic::panic_2015` or `$crate::panic::panic_2021`
19    // depending on the edition of the caller.
20    ($($arg:tt)*) => {
21        /* compiler built-in */
22    };
23}
24
25/// Prints to the standard output.
26///
27/// Equivalent to the [`println!`] macro except that a newline is not printed at
28/// the end of the message.
29///
30/// Note that stdout is frequently line-buffered by default so it may be
31/// necessary to use [`io::stdout().flush()`][flush] to ensure the output is emitted
32/// immediately.
33///
34/// The `print!` macro will lock the standard output on each call. If you call
35/// `print!` within a hot loop, this behavior may be the bottleneck of the loop.
36/// To avoid this, lock stdout with [`io::stdout().lock()`][lock]:
37/// ```
38/// use std::io::{stdout, Write};
39///
40/// let mut lock = stdout().lock();
41/// write!(lock, "hello world").unwrap();
42/// ```
43///
44/// Use `print!` only for the primary output of your program. Use
45/// [`eprint!`] instead to print error and progress messages.
46///
47/// See the formatting documentation in [`std::fmt`](crate::fmt)
48/// for details of the macro argument syntax.
49///
50/// [flush]: crate::io::Write::flush
51/// [`println!`]: crate::println
52/// [`eprint!`]: crate::eprint
53/// [lock]: crate::io::Stdout
54///
55/// # Panics
56///
57/// Panics if writing to `io::stdout()` fails.
58///
59/// Writing to non-blocking stdout can cause an error, which will lead
60/// this macro to panic.
61///
62/// # Examples
63///
64/// ```
65/// use std::io::{self, Write};
66///
67/// print!("this ");
68/// print!("will ");
69/// print!("be ");
70/// print!("on ");
71/// print!("the ");
72/// print!("same ");
73/// print!("line ");
74///
75/// io::stdout().flush().unwrap();
76///
77/// print!("this string has a newline, why not choose println! instead?\n");
78///
79/// io::stdout().flush().unwrap();
80/// ```
81#[macro_export]
82#[stable(feature = "rust1", since = "1.0.0")]
83#[cfg_attr(not(test), rustc_diagnostic_item = "print_macro")]
84#[allow_internal_unstable(print_internals)]
85macro_rules! print {
86    ($($arg:tt)*) => {{
87        $crate::io::_print($crate::format_args!($($arg)*));
88    }};
89}
90
91/// Prints to the standard output, with a newline.
92///
93/// On all platforms, the newline is the LINE FEED character (`\n`/`U+000A`) alone
94/// (no additional CARRIAGE RETURN (`\r`/`U+000D`)).
95///
96/// This macro uses the same syntax as [`format!`], but writes to the standard output instead.
97/// See [`std::fmt`] for more information.
98///
99/// The `println!` macro will lock the standard output on each call. If you call
100/// `println!` within a hot loop, this behavior may be the bottleneck of the loop.
101/// To avoid this, lock stdout with [`io::stdout().lock()`][lock]:
102/// ```
103/// use std::io::{stdout, Write};
104///
105/// let mut lock = stdout().lock();
106/// writeln!(lock, "hello world").unwrap();
107/// ```
108///
109/// Use `println!` only for the primary output of your program. Use
110/// [`eprintln!`] instead to print error and progress messages.
111///
112/// See the formatting documentation in [`std::fmt`](crate::fmt)
113/// for details of the macro argument syntax.
114///
115/// [`std::fmt`]: crate::fmt
116/// [`eprintln!`]: crate::eprintln
117/// [lock]: crate::io::Stdout
118///
119/// # Panics
120///
121/// Panics if writing to [`io::stdout`] fails.
122///
123/// Writing to non-blocking stdout can cause an error, which will lead
124/// this macro to panic.
125///
126/// [`io::stdout`]: crate::io::stdout
127///
128/// # Examples
129///
130/// ```
131/// println!(); // prints just a newline
132/// println!("hello there!");
133/// println!("format {} arguments", "some");
134/// let local_variable = "some";
135/// println!("format {local_variable} arguments");
136/// ```
137#[macro_export]
138#[stable(feature = "rust1", since = "1.0.0")]
139#[cfg_attr(not(test), rustc_diagnostic_item = "println_macro")]
140#[allow_internal_unstable(print_internals, format_args_nl)]
141macro_rules! println {
142    () => {
143        $crate::print!("\n")
144    };
145    ($($arg:tt)*) => {{
146        $crate::io::_print($crate::format_args_nl!($($arg)*));
147    }};
148}
149
150/// Prints to the standard error.
151///
152/// Equivalent to the [`print!`] macro, except that output goes to
153/// [`io::stderr`] instead of [`io::stdout`]. See [`print!`] for
154/// example usage.
155///
156/// Use `eprint!` only for error and progress messages. Use `print!`
157/// instead for the primary output of your program.
158///
159/// [`io::stderr`]: crate::io::stderr
160/// [`io::stdout`]: crate::io::stdout
161///
162/// See the formatting documentation in [`std::fmt`](crate::fmt)
163/// for details of the macro argument syntax.
164///
165/// # Panics
166///
167/// Panics if writing to `io::stderr` fails.
168///
169/// Writing to non-blocking stderr can cause an error, which will lead
170/// this macro to panic.
171///
172/// # Examples
173///
174/// ```
175/// eprint!("Error: Could not complete task");
176/// ```
177#[macro_export]
178#[stable(feature = "eprint", since = "1.19.0")]
179#[cfg_attr(not(test), rustc_diagnostic_item = "eprint_macro")]
180#[allow_internal_unstable(print_internals)]
181macro_rules! eprint {
182    ($($arg:tt)*) => {{
183        $crate::io::_eprint($crate::format_args!($($arg)*));
184    }};
185}
186
187/// Prints to the standard error, with a newline.
188///
189/// Equivalent to the [`println!`] macro, except that output goes to
190/// [`io::stderr`] instead of [`io::stdout`]. See [`println!`] for
191/// example usage.
192///
193/// Use `eprintln!` only for error and progress messages. Use `println!`
194/// instead for the primary output of your program.
195///
196/// See the formatting documentation in [`std::fmt`](crate::fmt)
197/// for details of the macro argument syntax.
198///
199/// [`io::stderr`]: crate::io::stderr
200/// [`io::stdout`]: crate::io::stdout
201/// [`println!`]: crate::println
202///
203/// # Panics
204///
205/// Panics if writing to `io::stderr` fails.
206///
207/// Writing to non-blocking stderr can cause an error, which will lead
208/// this macro to panic.
209///
210/// # Examples
211///
212/// ```
213/// eprintln!("Error: Could not complete task");
214/// ```
215#[macro_export]
216#[stable(feature = "eprint", since = "1.19.0")]
217#[cfg_attr(not(test), rustc_diagnostic_item = "eprintln_macro")]
218#[allow_internal_unstable(print_internals, format_args_nl)]
219macro_rules! eprintln {
220    () => {
221        $crate::eprint!("\n")
222    };
223    ($($arg:tt)*) => {{
224        $crate::io::_eprint($crate::format_args_nl!($($arg)*));
225    }};
226}
227
228/// Prints and returns the value of a given expression for quick and dirty
229/// debugging.
230///
231/// An example:
232///
233/// ```rust
234/// let a = 2;
235/// let b = dbg!(a * 2) + 1;
236/// //      ^-- prints: [src/main.rs:2:9] a * 2 = 4
237/// assert_eq!(b, 5);
238/// ```
239///
240/// The macro works by using the `Debug` implementation of the type of
241/// the given expression to print the value to [stderr] along with the
242/// source location of the macro invocation as well as the source code
243/// of the expression.
244///
245/// Invoking the macro on an expression moves and takes ownership of it
246/// before returning the evaluated expression unchanged. If the type
247/// of the expression does not implement `Copy` and you don't want
248/// to give up ownership, you can instead borrow with `dbg!(&expr)`
249/// for some expression `expr`.
250///
251/// The `dbg!` macro works exactly the same in release builds.
252/// This is useful when debugging issues that only occur in release
253/// builds or when debugging in release mode is significantly faster.
254///
255/// Note that the macro is intended as a debugging tool and therefore you
256/// should avoid having uses of it in version control for long periods
257/// (other than in tests and similar).
258/// Debug output from production code is better done with other facilities
259/// such as the [`debug!`] macro from the [`log`] crate.
260///
261/// # Stability
262///
263/// The exact output printed by this macro should not be relied upon
264/// and is subject to future changes.
265///
266/// # Panics
267///
268/// Panics if writing to `io::stderr` fails.
269///
270/// # Further examples
271///
272/// With a method call:
273///
274/// ```rust
275/// fn foo(n: usize) {
276///     if let Some(_) = dbg!(n.checked_sub(4)) {
277///         // ...
278///     }
279/// }
280///
281/// foo(3)
282/// ```
283///
284/// This prints to [stderr]:
285///
286/// ```text,ignore
287/// [src/main.rs:2:22] n.checked_sub(4) = None
288/// ```
289///
290/// Naive factorial implementation:
291///
292/// ```rust
293/// fn factorial(n: u32) -> u32 {
294///     if dbg!(n <= 1) {
295///         dbg!(1)
296///     } else {
297///         dbg!(n * factorial(n - 1))
298///     }
299/// }
300///
301/// dbg!(factorial(4));
302/// ```
303///
304/// This prints to [stderr]:
305///
306/// ```text,ignore
307/// [src/main.rs:2:8] n <= 1 = false
308/// [src/main.rs:2:8] n <= 1 = false
309/// [src/main.rs:2:8] n <= 1 = false
310/// [src/main.rs:2:8] n <= 1 = true
311/// [src/main.rs:3:9] 1 = 1
312/// [src/main.rs:7:9] n * factorial(n - 1) = 2
313/// [src/main.rs:7:9] n * factorial(n - 1) = 6
314/// [src/main.rs:7:9] n * factorial(n - 1) = 24
315/// [src/main.rs:9:1] factorial(4) = 24
316/// ```
317///
318/// The `dbg!(..)` macro moves the input:
319///
320/// ```compile_fail
321/// /// A wrapper around `usize` which importantly is not Copyable.
322/// #[derive(Debug)]
323/// struct NoCopy(usize);
324///
325/// let a = NoCopy(42);
326/// let _ = dbg!(a); // <-- `a` is moved here.
327/// let _ = dbg!(a); // <-- `a` is moved again; error!
328/// ```
329///
330/// You can also use `dbg!()` without a value to just print the
331/// file and line whenever it's reached.
332///
333/// Finally, if you want to `dbg!(..)` multiple values, it will treat them as
334/// a tuple (and return it, too):
335///
336/// ```
337/// assert_eq!(dbg!(1usize, 2u32), (1, 2));
338/// ```
339///
340/// However, a single argument with a trailing comma will still not be treated
341/// as a tuple, following the convention of ignoring trailing commas in macro
342/// invocations. You can use a 1-tuple directly if you need one:
343///
344/// ```
345/// assert_eq!(1, dbg!(1u32,)); // trailing comma ignored
346/// assert_eq!((1,), dbg!((1u32,))); // 1-tuple
347/// ```
348///
349/// [stderr]: https://en.wikipedia.org/wiki/Standard_streams#Standard_error_(stderr)
350/// [`debug!`]: https://docs.rs/log/*/log/macro.debug.html
351/// [`log`]: https://crates.io/crates/log
352#[macro_export]
353#[allow_internal_unstable(std_internals)]
354#[cfg_attr(not(test), rustc_diagnostic_item = "dbg_macro")]
355#[stable(feature = "dbg_macro", since = "1.32.0")]
356macro_rules! dbg {
357    () => {
358        $crate::eprintln!("[{}:{}:{}]", $crate::file!(), $crate::line!(), $crate::column!())
359    };
360    ($($val:expr),+ $(,)?) => {
361        $crate::macros::dbg_internal!(() () ($($val),+))
362    };
363}
364
365/// Internal macro that processes a list of expressions, binds their results
366/// with `match`, calls `eprint!` with the collected information, and returns
367/// all the evaluated expressions in a tuple.
368///
369/// E.g. `dbg_internal!(() () (1, 2))` expands into
370/// ```rust, ignore
371/// match (1, 2) {
372///     args => {
373///         let (tmp_1, tmp_2) = args;
374///         eprint!("...", &tmp_1, &tmp_2, /* some other arguments */);
375///         (tmp_1, tmp_2)
376///     }
377/// }
378/// ```
379///
380/// This is necessary so that `dbg!` outputs don't get torn, see #136703.
381#[doc(hidden)]
382#[rustc_macro_transparency = "semiopaque"]
383pub macro dbg_internal {
384    (($($piece:literal),+) ($($processed:expr => $bound:ident),+) ()) => {
385        // Use of `match` here is intentional because it affects the lifetimes
386        // of temporaries - https://stackoverflow.com/a/48732525/1063961
387        // Always put the arguments in a tuple to avoid an unused parens lint on the pattern.
388        match ($($processed,)+) {
389            // Move the entire tuple so it doesn't stick around as a temporary (#154988).
390            args => {
391                let ($($bound,)+) = args;
392                $crate::eprint!(
393                    $crate::concat!($($piece),+),
394                    $(
395                        $crate::stringify!($processed),
396                        // The `&T: Debug` check happens here (not in the format literal desugaring)
397                        // to avoid format literal related messages and suggestions.
398                        &&$bound as &dyn $crate::fmt::Debug
399                    ),+,
400                    // The location returned here is that of the macro invocation, so
401                    // it will be the same for all expressions. Thus, label these
402                    // arguments so that they can be reused in every piece of the
403                    // formatting template.
404                    file=$crate::file!(),
405                    line=$crate::line!(),
406                    column=$crate::column!()
407                );
408                // Comma separate the variables only when necessary so that this will
409                // not yield a tuple for a single expression, but rather just parenthesize
410                // the expression.
411                ($($bound),+)
412
413            }
414        }
415    },
416    (($($piece:literal),*) ($($processed:expr => $bound:ident),*) ($val:expr $(,$rest:expr)*)) => {
417        $crate::macros::dbg_internal!(
418            ($($piece,)* "[{file}:{line}:{column}] {} = {:#?}\n")
419            ($($processed => $bound,)* $val => tmp)
420            ($($rest),*)
421        )
422    },
423}
424
425#[doc(hidden)]
426#[macro_export]
427#[allow_internal_unstable(hash_map_internals)]
428#[unstable(feature = "hash_map_internals", issue = "none")]
429macro_rules! repetition_utils {
430    (@count $($tokens:tt),*) => {{
431        [$($crate::repetition_utils!(@replace $tokens => ())),*].len()
432    }};
433
434    (@replace $x:tt => $y:tt) => { $y }
435}
436
437/// Creates a [`HashMap`] containing the arguments.
438///
439/// `hash_map!` allows specifying the entries that make
440/// up the [`HashMap`] where the key and value are separated by a `=>`.
441///
442/// The entries are separated by commas with a trailing comma being allowed.
443///
444/// It is semantically equivalent to using repeated [`HashMap::insert`]
445/// on a newly created hashmap.
446///
447/// `hash_map!` will attempt to avoid repeated reallocations by
448/// using [`HashMap::with_capacity`].
449///
450/// # Examples
451///
452/// ```rust
453/// #![feature(hash_map_macro)]
454/// use std::hash_map;
455///
456/// let map = hash_map! {
457///     "key" => "value",
458///     "key1" => "value1"
459/// };
460///
461/// assert_eq!(map.get("key"), Some(&"value"));
462/// assert_eq!(map.get("key1"), Some(&"value1"));
463/// assert!(map.get("brrrrrrooooommm").is_none());
464/// ```
465///
466/// And with a trailing comma
467///
468///```rust
469/// #![feature(hash_map_macro)]
470/// use std::hash_map;
471///
472/// let map = hash_map! {
473///     "key" => "value", // notice the ,
474/// };
475///
476/// assert_eq!(map.get("key"), Some(&"value"));
477/// ```
478///
479/// The key and value are moved into the HashMap.
480///
481/// [`HashMap`]: crate::collections::HashMap
482/// [`HashMap::insert`]: crate::collections::HashMap::insert
483/// [`HashMap::with_capacity`]: crate::collections::HashMap::with_capacity
484#[macro_export]
485#[allow_internal_unstable(hash_map_internals)]
486#[unstable(feature = "hash_map_macro", issue = "144032")]
487macro_rules! hash_map {
488    () => {{
489        $crate::collections::HashMap::new()
490    }};
491
492    ( $( $key:expr => $value:expr ),* $(,)? ) => {{
493        let mut map = $crate::collections::HashMap::with_capacity(
494            const { $crate::repetition_utils!(@count $($key),*) }
495        );
496        $( map.insert($key, $value); )*
497        map
498    }}
499}