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-file-dbg
7
8#[cfg(test)]
9mod tests;
10
11#[doc = 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)]
85#[rustc_diagnostic_opaque]
86macro_rules! print {
87    ($($arg:tt)*) => {{
88        $crate::io::_print($crate::format_args!($($arg)*));
89    }};
90}
91
92/// Prints to the standard output, with a newline.
93///
94/// On all platforms, the newline is the LINE FEED character (`\n`/`U+000A`) alone
95/// (no additional CARRIAGE RETURN (`\r`/`U+000D`)).
96///
97/// This macro uses the same syntax as [`format!`], but writes to the standard output instead.
98/// See [`std::fmt`] for more information.
99///
100/// The `println!` macro will lock the standard output on each call. If you call
101/// `println!` within a hot loop, this behavior may be the bottleneck of the loop.
102/// To avoid this, lock stdout with [`io::stdout().lock()`][lock]:
103/// ```
104/// use std::io::{stdout, Write};
105///
106/// let mut lock = stdout().lock();
107/// writeln!(lock, "hello world").unwrap();
108/// ```
109///
110/// Use `println!` only for the primary output of your program. Use
111/// [`eprintln!`] instead to print error and progress messages.
112///
113/// See the formatting documentation in [`std::fmt`](crate::fmt)
114/// for details of the macro argument syntax.
115///
116/// [`std::fmt`]: crate::fmt
117/// [`eprintln!`]: crate::eprintln
118/// [lock]: crate::io::Stdout
119///
120/// # Panics
121///
122/// Panics if writing to [`io::stdout`] fails.
123///
124/// Writing to non-blocking stdout can cause an error, which will lead
125/// this macro to panic.
126///
127/// [`io::stdout`]: crate::io::stdout
128///
129/// # Examples
130///
131/// ```
132/// println!(); // prints just a newline
133/// println!("hello there!");
134/// println!("format {} arguments", "some");
135/// let local_variable = "some";
136/// println!("format {local_variable} arguments");
137/// ```
138#[macro_export]
139#[stable(feature = "rust1", since = "1.0.0")]
140#[cfg_attr(not(test), rustc_diagnostic_item = "println_macro")]
141#[allow_internal_unstable(print_internals, format_args_nl)]
142#[rustc_diagnostic_opaque]
143macro_rules! println {
144    () => {
145        $crate::print!("\n")
146    };
147    ($($arg:tt)*) => {{
148        $crate::io::_print($crate::format_args_nl!($($arg)*));
149    }};
150}
151
152/// Prints to the standard error.
153///
154/// Equivalent to the [`print!`] macro, except that output goes to
155/// [`io::stderr`] instead of [`io::stdout`]. See [`print!`] for
156/// example usage.
157///
158/// Use `eprint!` only for error and progress messages. Use `print!`
159/// instead for the primary output of your program.
160///
161/// [`io::stderr`]: crate::io::stderr
162/// [`io::stdout`]: crate::io::stdout
163///
164/// See the formatting documentation in [`std::fmt`](crate::fmt)
165/// for details of the macro argument syntax.
166///
167/// # Panics
168///
169/// Panics if writing to `io::stderr` fails.
170///
171/// Writing to non-blocking stderr can cause an error, which will lead
172/// this macro to panic.
173///
174/// # Examples
175///
176/// ```
177/// eprint!("Error: Could not complete task");
178/// ```
179#[macro_export]
180#[stable(feature = "eprint", since = "1.19.0")]
181#[cfg_attr(not(test), rustc_diagnostic_item = "eprint_macro")]
182#[allow_internal_unstable(print_internals)]
183macro_rules! eprint {
184    ($($arg:tt)*) => {{
185        $crate::io::_eprint($crate::format_args!($($arg)*));
186    }};
187}
188
189/// Prints to the standard error, with a newline.
190///
191/// Equivalent to the [`println!`] macro, except that output goes to
192/// [`io::stderr`] instead of [`io::stdout`]. See [`println!`] for
193/// example usage.
194///
195/// Use `eprintln!` only for error and progress messages. Use `println!`
196/// instead for the primary output of your program.
197///
198/// See the formatting documentation in [`std::fmt`](crate::fmt)
199/// for details of the macro argument syntax.
200///
201/// [`io::stderr`]: crate::io::stderr
202/// [`io::stdout`]: crate::io::stdout
203/// [`println!`]: crate::println
204///
205/// # Panics
206///
207/// Panics if writing to `io::stderr` fails.
208///
209/// Writing to non-blocking stderr can cause an error, which will lead
210/// this macro to panic.
211///
212/// # Examples
213///
214/// ```
215/// eprintln!("Error: Could not complete task");
216/// ```
217#[macro_export]
218#[stable(feature = "eprint", since = "1.19.0")]
219#[cfg_attr(not(test), rustc_diagnostic_item = "eprintln_macro")]
220#[allow_internal_unstable(print_internals, format_args_nl)]
221macro_rules! eprintln {
222    () => {
223        $crate::eprint!("\n")
224    };
225    ($($arg:tt)*) => {{
226        $crate::io::_eprint($crate::format_args_nl!($($arg)*));
227    }};
228}
229
230/// Prints and returns the value of a given expression for quick and dirty
231/// debugging.
232///
233/// An example:
234///
235/// ```rust
236/// let a = 2;
237/// let b = dbg!(a * 2) + 1;
238/// //      ^-- prints: [src/main.rs:2:9] a * 2 = 4
239/// assert_eq!(b, 5);
240/// ```
241///
242/// The macro works by using the `Debug` implementation of the type of
243/// the given expression to print the value to [stderr] along with the
244/// source location of the macro invocation as well as the source code
245/// of the expression.
246///
247/// Invoking the macro on an expression moves and takes ownership of it
248/// before returning the evaluated expression unchanged. If the type
249/// of the expression does not implement `Copy` and you don't want
250/// to give up ownership, you can instead borrow with `dbg!(&expr)`
251/// for some expression `expr`.
252///
253/// The `dbg!` macro works exactly the same in release builds.
254/// This is useful when debugging issues that only occur in release
255/// builds or when debugging in release mode is significantly faster.
256///
257/// Note that the macro is intended as a debugging tool and therefore you
258/// should avoid having uses of it in version control for long periods
259/// (other than in tests and similar).
260/// Debug output from production code is better done with other facilities
261/// such as the [`debug!`] macro from the [`log`] crate.
262///
263/// # Stability
264///
265/// The exact output printed by this macro should not be relied upon
266/// and is subject to future changes.
267///
268/// # Panics
269///
270/// Panics if writing to `io::stderr` fails.
271///
272/// # Further examples
273///
274/// With a method call:
275///
276/// ```rust
277/// fn foo(n: usize) {
278///     if let Some(_) = dbg!(n.checked_sub(4)) {
279///         // ...
280///     }
281/// }
282///
283/// foo(3)
284/// ```
285///
286/// This prints to [stderr]:
287///
288/// ```text,ignore
289/// [src/main.rs:2:22] n.checked_sub(4) = None
290/// ```
291///
292/// Naive factorial implementation:
293///
294/// ```rust
295/// fn factorial(n: u32) -> u32 {
296///     if dbg!(n <= 1) {
297///         dbg!(1)
298///     } else {
299///         dbg!(n * factorial(n - 1))
300///     }
301/// }
302///
303/// dbg!(factorial(4));
304/// ```
305///
306/// This prints to [stderr]:
307///
308/// ```text,ignore
309/// [src/main.rs:2:8] n <= 1 = false
310/// [src/main.rs:2:8] n <= 1 = false
311/// [src/main.rs:2:8] n <= 1 = false
312/// [src/main.rs:2:8] n <= 1 = true
313/// [src/main.rs:3:9] 1 = 1
314/// [src/main.rs:7:9] n * factorial(n - 1) = 2
315/// [src/main.rs:7:9] n * factorial(n - 1) = 6
316/// [src/main.rs:7:9] n * factorial(n - 1) = 24
317/// [src/main.rs:9:1] factorial(4) = 24
318/// ```
319///
320/// The `dbg!(..)` macro moves the input:
321///
322/// ```compile_fail
323/// /// A wrapper around `usize` which importantly is not Copyable.
324/// #[derive(Debug)]
325/// struct NoCopy(usize);
326///
327/// let a = NoCopy(42);
328/// let _ = dbg!(a); // <-- `a` is moved here.
329/// let _ = dbg!(a); // <-- `a` is moved again; error!
330/// ```
331///
332/// You can also use `dbg!()` without a value to just print the
333/// file and line whenever it's reached.
334///
335/// Finally, if you want to `dbg!(..)` multiple values, it will treat them as
336/// a tuple (and return it, too):
337///
338/// ```
339/// assert_eq!(dbg!(1usize, 2u32), (1, 2));
340/// ```
341///
342/// However, a single argument with a trailing comma will still not be treated
343/// as a tuple, following the convention of ignoring trailing commas in macro
344/// invocations. You can use a 1-tuple directly if you need one:
345///
346/// ```
347/// assert_eq!(1, dbg!(1u32,)); // trailing comma ignored
348/// assert_eq!((1,), dbg!((1u32,))); // 1-tuple
349/// ```
350///
351/// [stderr]: https://en.wikipedia.org/wiki/Standard_streams#Standard_error_(stderr)
352/// [`debug!`]: https://docs.rs/log/*/log/macro.debug.html
353/// [`log`]: https://crates.io/crates/log
354#[macro_export]
355#[cfg_attr(not(test), rustc_diagnostic_item = "dbg_macro")]
356#[stable(feature = "dbg_macro", since = "1.32.0")]
357#[rustc_diagnostic_opaque]
358macro_rules! dbg {
359    // NOTE: We cannot use `concat!` to make a static string as a format argument
360    // of `eprintln!` because `file!` could contain a `{` or
361    // `$val` expression could be a block (`{ .. }`), in which case the `eprintln!`
362    // will be malformed.
363    () => {
364        $crate::eprintln!("[{}:{}:{}]", $crate::file!(), $crate::line!(), $crate::column!())
365    };
366    ($val:expr $(,)?) => {
367        // Use of `match` here is intentional because it affects the lifetimes
368        // of temporaries - https://stackoverflow.com/a/48732525/1063961
369        match $val {
370            tmp => {
371                $crate::eprintln!("[{}:{}:{}] {} = {:#?}",
372                    $crate::file!(),
373                    $crate::line!(),
374                    $crate::column!(),
375                    $crate::stringify!($val),
376                    // The `&T: Debug` check happens here (not in the format literal desugaring)
377                    // to avoid format literal related messages and suggestions.
378                    &&tmp as &dyn $crate::fmt::Debug,
379                );
380                tmp
381            }
382        }
383    };
384    ($($val:expr),+ $(,)?) => {
385        ($($crate::dbg!($val)),+,)
386    };
387}
388
389#[doc(hidden)]
390#[macro_export]
391#[allow_internal_unstable(hash_map_internals)]
392#[unstable(feature = "hash_map_internals", issue = "none")]
393macro_rules! repetition_utils {
394    (@count $($tokens:tt),*) => {{
395        [$($crate::repetition_utils!(@replace $tokens => ())),*].len()
396    }};
397
398    (@replace $x:tt => $y:tt) => { $y }
399}
400
401/// Creates a [`HashMap`] containing the arguments.
402///
403/// `hash_map!` allows specifying the entries that make
404/// up the [`HashMap`] where the key and value are separated by a `=>`.
405///
406/// The entries are separated by commas with a trailing comma being allowed.
407///
408/// It is semantically equivalent to using repeated [`HashMap::insert`]
409/// on a newly created hashmap.
410///
411/// `hash_map!` will attempt to avoid repeated reallocations by
412/// using [`HashMap::with_capacity`].
413///
414/// # Examples
415///
416/// ```rust
417/// #![feature(hash_map_macro)]
418/// use std::hash_map;
419///
420/// let map = hash_map! {
421///     "key" => "value",
422///     "key1" => "value1"
423/// };
424///
425/// assert_eq!(map.get("key"), Some(&"value"));
426/// assert_eq!(map.get("key1"), Some(&"value1"));
427/// assert!(map.get("brrrrrrooooommm").is_none());
428/// ```
429///
430/// And with a trailing comma
431///
432///```rust
433/// #![feature(hash_map_macro)]
434/// use std::hash_map;
435///
436/// let map = hash_map! {
437///     "key" => "value", // notice the ,
438/// };
439///
440/// assert_eq!(map.get("key"), Some(&"value"));
441/// ```
442///
443/// The key and value are moved into the HashMap.
444///
445/// [`HashMap`]: crate::collections::HashMap
446/// [`HashMap::insert`]: crate::collections::HashMap::insert
447/// [`HashMap::with_capacity`]: crate::collections::HashMap::with_capacity
448#[macro_export]
449#[allow_internal_unstable(hash_map_internals)]
450#[unstable(feature = "hash_map_macro", issue = "144032")]
451macro_rules! hash_map {
452    () => {{
453        $crate::collections::HashMap::new()
454    }};
455
456    ( $( $key:expr => $value:expr ),* $(,)? ) => {{
457        let mut map = $crate::collections::HashMap::with_capacity(
458            const { $crate::repetition_utils!(@count $($key),*) }
459        );
460        $( map.insert($key, $value); )*
461        map
462    }}
463}