]>
Commit | Line | Data |
---|---|---|
1a4d82fc JJ |
1 | //! Standard library macros |
2 | //! | |
3dfed10e | 3 | //! This module contains a set of macros which are exported from the standard |
1a4d82fc JJ |
4 | //! library. Each macro is available for use when linking against the standard |
5 | //! library. | |
970d7e83 | 6 | |
6a06907d | 7 | #[doc = include_str!("../../core/src/macros/panic.md")] |
5869c6ff | 8 | #[macro_export] |
136023e0 XL |
9 | #[cfg_attr(bootstrap, rustc_builtin_macro = "std_panic")] |
10 | #[cfg_attr(not(bootstrap), rustc_builtin_macro(std_panic))] | |
5869c6ff XL |
11 | #[stable(feature = "rust1", since = "1.0.0")] |
12 | #[allow_internal_unstable(edition_panic)] | |
13 | #[cfg_attr(not(test), rustc_diagnostic_item = "std_panic_macro")] | |
14 | macro_rules! panic { | |
15 | // Expands to either `$crate::panic::panic_2015` or `$crate::panic::panic_2021` | |
16 | // depending on the edition of the caller. | |
17 | ($($arg:tt)*) => { | |
18 | /* compiler built-in */ | |
19 | }; | |
20 | } | |
21 | ||
532ac7d7 | 22 | /// Prints to the standard output. |
c34b1796 | 23 | /// |
ea8adc8c | 24 | /// Equivalent to the [`println!`] macro except that a newline is not printed at |
1a4d82fc | 25 | /// the end of the message. |
c34b1796 AL |
26 | /// |
27 | /// Note that stdout is frequently line-buffered by default so it may be | |
ea8adc8c | 28 | /// necessary to use [`io::stdout().flush()`][flush] to ensure the output is emitted |
c34b1796 | 29 | /// immediately. |
e9174d1e | 30 | /// |
9fa01778 | 31 | /// Use `print!` only for the primary output of your program. Use |
ea8adc8c XL |
32 | /// [`eprint!`] instead to print error and progress messages. |
33 | /// | |
3dfed10e | 34 | /// [flush]: crate::io::Write::flush |
7cac9316 | 35 | /// |
b039eaaf SL |
36 | /// # Panics |
37 | /// | |
38 | /// Panics if writing to `io::stdout()` fails. | |
39 | /// | |
e9174d1e SL |
40 | /// # Examples |
41 | /// | |
42 | /// ``` | |
43 | /// use std::io::{self, Write}; | |
44 | /// | |
45 | /// print!("this "); | |
46 | /// print!("will "); | |
47 | /// print!("be "); | |
48 | /// print!("on "); | |
49 | /// print!("the "); | |
50 | /// print!("same "); | |
51 | /// print!("line "); | |
52 | /// | |
53 | /// io::stdout().flush().unwrap(); | |
54 | /// | |
55 | /// print!("this string has a newline, why not choose println! instead?\n"); | |
56 | /// | |
57 | /// io::stdout().flush().unwrap(); | |
58 | /// ``` | |
1a4d82fc | 59 | #[macro_export] |
85aaf69f | 60 | #[stable(feature = "rust1", since = "1.0.0")] |
532ac7d7 | 61 | #[allow_internal_unstable(print_internals)] |
1a4d82fc | 62 | macro_rules! print { |
e1599b0c | 63 | ($($arg:tt)*) => ($crate::io::_print($crate::format_args!($($arg)*))); |
1a4d82fc | 64 | } |
970d7e83 | 65 | |
532ac7d7 | 66 | /// Prints to the standard output, with a newline. |
ea8adc8c XL |
67 | /// |
68 | /// On all platforms, the newline is the LINE FEED character (`\n`/`U+000A`) alone | |
416331ca | 69 | /// (no additional CARRIAGE RETURN (`\r`/`U+000D`)). |
1a4d82fc | 70 | /// |
ea8adc8c XL |
71 | /// Use the [`format!`] syntax to write data to the standard output. |
72 | /// See [`std::fmt`] for more information. | |
1a4d82fc | 73 | /// |
9fa01778 | 74 | /// Use `println!` only for the primary output of your program. Use |
ea8adc8c | 75 | /// [`eprintln!`] instead to print error and progress messages. |
7cac9316 | 76 | /// |
3dfed10e XL |
77 | /// [`std::fmt`]: crate::fmt |
78 | /// | |
b039eaaf SL |
79 | /// # Panics |
80 | /// | |
3dfed10e XL |
81 | /// Panics if writing to [`io::stdout`] fails. |
82 | /// | |
83 | /// [`io::stdout`]: crate::io::stdout | |
b039eaaf | 84 | /// |
c34b1796 | 85 | /// # Examples |
1a4d82fc JJ |
86 | /// |
87 | /// ``` | |
32a655c1 | 88 | /// println!(); // prints just a newline |
1a4d82fc JJ |
89 | /// println!("hello there!"); |
90 | /// println!("format {} arguments", "some"); | |
91 | /// ``` | |
92 | #[macro_export] | |
85aaf69f | 93 | #[stable(feature = "rust1", since = "1.0.0")] |
532ac7d7 | 94 | #[allow_internal_unstable(print_internals, format_args_nl)] |
1a4d82fc | 95 | macro_rules! println { |
48663c56 | 96 | () => ($crate::print!("\n")); |
8faf50e0 | 97 | ($($arg:tt)*) => ({ |
e1599b0c | 98 | $crate::io::_print($crate::format_args_nl!($($arg)*)); |
8faf50e0 | 99 | }) |
1a4d82fc JJ |
100 | } |
101 | ||
532ac7d7 | 102 | /// Prints to the standard error. |
7cac9316 | 103 | /// |
ea8adc8c | 104 | /// Equivalent to the [`print!`] macro, except that output goes to |
3dfed10e | 105 | /// [`io::stderr`] instead of [`io::stdout`]. See [`print!`] for |
7cac9316 XL |
106 | /// example usage. |
107 | /// | |
9fa01778 | 108 | /// Use `eprint!` only for error and progress messages. Use `print!` |
7cac9316 XL |
109 | /// instead for the primary output of your program. |
110 | /// | |
3dfed10e XL |
111 | /// [`io::stderr`]: crate::io::stderr |
112 | /// [`io::stdout`]: crate::io::stdout | |
ea8adc8c | 113 | /// |
7cac9316 XL |
114 | /// # Panics |
115 | /// | |
116 | /// Panics if writing to `io::stderr` fails. | |
ea8adc8c XL |
117 | /// |
118 | /// # Examples | |
119 | /// | |
120 | /// ``` | |
121 | /// eprint!("Error: Could not complete task"); | |
122 | /// ``` | |
7cac9316 XL |
123 | #[macro_export] |
124 | #[stable(feature = "eprint", since = "1.19.0")] | |
532ac7d7 | 125 | #[allow_internal_unstable(print_internals)] |
7cac9316 | 126 | macro_rules! eprint { |
e1599b0c | 127 | ($($arg:tt)*) => ($crate::io::_eprint($crate::format_args!($($arg)*))); |
7cac9316 XL |
128 | } |
129 | ||
532ac7d7 | 130 | /// Prints to the standard error, with a newline. |
7cac9316 | 131 | /// |
ea8adc8c | 132 | /// Equivalent to the [`println!`] macro, except that output goes to |
3dfed10e | 133 | /// [`io::stderr`] instead of [`io::stdout`]. See [`println!`] for |
7cac9316 XL |
134 | /// example usage. |
135 | /// | |
9fa01778 | 136 | /// Use `eprintln!` only for error and progress messages. Use `println!` |
7cac9316 XL |
137 | /// instead for the primary output of your program. |
138 | /// | |
3dfed10e XL |
139 | /// [`io::stderr`]: crate::io::stderr |
140 | /// [`io::stdout`]: crate::io::stdout | |
ea8adc8c | 141 | /// |
7cac9316 XL |
142 | /// # Panics |
143 | /// | |
144 | /// Panics if writing to `io::stderr` fails. | |
ea8adc8c XL |
145 | /// |
146 | /// # Examples | |
147 | /// | |
148 | /// ``` | |
149 | /// eprintln!("Error: Could not complete task"); | |
150 | /// ``` | |
7cac9316 XL |
151 | #[macro_export] |
152 | #[stable(feature = "eprint", since = "1.19.0")] | |
532ac7d7 | 153 | #[allow_internal_unstable(print_internals, format_args_nl)] |
7cac9316 | 154 | macro_rules! eprintln { |
48663c56 | 155 | () => ($crate::eprint!("\n")); |
8faf50e0 | 156 | ($($arg:tt)*) => ({ |
e1599b0c | 157 | $crate::io::_eprint($crate::format_args_nl!($($arg)*)); |
8faf50e0 XL |
158 | }) |
159 | } | |
160 | ||
532ac7d7 XL |
161 | /// Prints and returns the value of a given expression for quick and dirty |
162 | /// debugging. | |
163 | /// | |
164 | /// An example: | |
0bf4aa26 XL |
165 | /// |
166 | /// ```rust | |
0bf4aa26 XL |
167 | /// let a = 2; |
168 | /// let b = dbg!(a * 2) + 1; | |
a1dfa0c6 | 169 | /// // ^-- prints: [src/main.rs:2] a * 2 = 4 |
0bf4aa26 XL |
170 | /// assert_eq!(b, 5); |
171 | /// ``` | |
172 | /// | |
173 | /// The macro works by using the `Debug` implementation of the type of | |
174 | /// the given expression to print the value to [stderr] along with the | |
175 | /// source location of the macro invocation as well as the source code | |
176 | /// of the expression. | |
177 | /// | |
178 | /// Invoking the macro on an expression moves and takes ownership of it | |
179 | /// before returning the evaluated expression unchanged. If the type | |
180 | /// of the expression does not implement `Copy` and you don't want | |
181 | /// to give up ownership, you can instead borrow with `dbg!(&expr)` | |
182 | /// for some expression `expr`. | |
183 | /// | |
532ac7d7 XL |
184 | /// The `dbg!` macro works exactly the same in release builds. |
185 | /// This is useful when debugging issues that only occur in release | |
186 | /// builds or when debugging in release mode is significantly faster. | |
187 | /// | |
0bf4aa26 | 188 | /// Note that the macro is intended as a debugging tool and therefore you |
17df50a5 XL |
189 | /// should avoid having uses of it in version control for long periods |
190 | /// (other than in tests and similar). | |
191 | /// Debug output from production code is better done with other facilities | |
192 | /// such as the [`debug!`] macro from the [`log`] crate. | |
0bf4aa26 XL |
193 | /// |
194 | /// # Stability | |
195 | /// | |
196 | /// The exact output printed by this macro should not be relied upon | |
197 | /// and is subject to future changes. | |
198 | /// | |
199 | /// # Panics | |
200 | /// | |
201 | /// Panics if writing to `io::stderr` fails. | |
202 | /// | |
203 | /// # Further examples | |
204 | /// | |
205 | /// With a method call: | |
206 | /// | |
207 | /// ```rust | |
0bf4aa26 XL |
208 | /// fn foo(n: usize) { |
209 | /// if let Some(_) = dbg!(n.checked_sub(4)) { | |
210 | /// // ... | |
211 | /// } | |
212 | /// } | |
213 | /// | |
214 | /// foo(3) | |
215 | /// ``` | |
216 | /// | |
217 | /// This prints to [stderr]: | |
218 | /// | |
219 | /// ```text,ignore | |
220 | /// [src/main.rs:4] n.checked_sub(4) = None | |
221 | /// ``` | |
222 | /// | |
223 | /// Naive factorial implementation: | |
224 | /// | |
225 | /// ```rust | |
0bf4aa26 XL |
226 | /// fn factorial(n: u32) -> u32 { |
227 | /// if dbg!(n <= 1) { | |
228 | /// dbg!(1) | |
229 | /// } else { | |
230 | /// dbg!(n * factorial(n - 1)) | |
231 | /// } | |
232 | /// } | |
233 | /// | |
234 | /// dbg!(factorial(4)); | |
235 | /// ``` | |
236 | /// | |
237 | /// This prints to [stderr]: | |
238 | /// | |
239 | /// ```text,ignore | |
240 | /// [src/main.rs:3] n <= 1 = false | |
241 | /// [src/main.rs:3] n <= 1 = false | |
242 | /// [src/main.rs:3] n <= 1 = false | |
243 | /// [src/main.rs:3] n <= 1 = true | |
244 | /// [src/main.rs:4] 1 = 1 | |
245 | /// [src/main.rs:5] n * factorial(n - 1) = 2 | |
246 | /// [src/main.rs:5] n * factorial(n - 1) = 6 | |
247 | /// [src/main.rs:5] n * factorial(n - 1) = 24 | |
248 | /// [src/main.rs:11] factorial(4) = 24 | |
249 | /// ``` | |
250 | /// | |
251 | /// The `dbg!(..)` macro moves the input: | |
252 | /// | |
253 | /// ```compile_fail | |
0bf4aa26 XL |
254 | /// /// A wrapper around `usize` which importantly is not Copyable. |
255 | /// #[derive(Debug)] | |
256 | /// struct NoCopy(usize); | |
257 | /// | |
258 | /// let a = NoCopy(42); | |
259 | /// let _ = dbg!(a); // <-- `a` is moved here. | |
260 | /// let _ = dbg!(a); // <-- `a` is moved again; error! | |
261 | /// ``` | |
262 | /// | |
532ac7d7 XL |
263 | /// You can also use `dbg!()` without a value to just print the |
264 | /// file and line whenever it's reached. | |
265 | /// | |
48663c56 XL |
266 | /// Finally, if you want to `dbg!(..)` multiple values, it will treat them as |
267 | /// a tuple (and return it, too): | |
268 | /// | |
269 | /// ``` | |
270 | /// assert_eq!(dbg!(1usize, 2u32), (1, 2)); | |
271 | /// ``` | |
272 | /// | |
273 | /// However, a single argument with a trailing comma will still not be treated | |
274 | /// as a tuple, following the convention of ignoring trailing commas in macro | |
275 | /// invocations. You can use a 1-tuple directly if you need one: | |
276 | /// | |
277 | /// ``` | |
278 | /// assert_eq!(1, dbg!(1u32,)); // trailing comma ignored | |
279 | /// assert_eq!((1,), dbg!((1u32,))); // 1-tuple | |
280 | /// ``` | |
281 | /// | |
0bf4aa26 | 282 | /// [stderr]: https://en.wikipedia.org/wiki/Standard_streams#Standard_error_(stderr) |
532ac7d7 XL |
283 | /// [`debug!`]: https://docs.rs/log/*/log/macro.debug.html |
284 | /// [`log`]: https://crates.io/crates/log | |
0bf4aa26 | 285 | #[macro_export] |
a1dfa0c6 | 286 | #[stable(feature = "dbg_macro", since = "1.32.0")] |
0bf4aa26 | 287 | macro_rules! dbg { |
5869c6ff XL |
288 | // NOTE: We cannot use `concat!` to make a static string as a format argument |
289 | // of `eprintln!` because `file!` could contain a `{` or | |
290 | // `$val` expression could be a block (`{ .. }`), in which case the `eprintln!` | |
291 | // will be malformed. | |
532ac7d7 | 292 | () => { |
e1599b0c | 293 | $crate::eprintln!("[{}:{}]", $crate::file!(), $crate::line!()); |
532ac7d7 | 294 | }; |
29967ef6 | 295 | ($val:expr $(,)?) => { |
0bf4aa26 XL |
296 | // Use of `match` here is intentional because it affects the lifetimes |
297 | // of temporaries - https://stackoverflow.com/a/48732525/1063961 | |
298 | match $val { | |
299 | tmp => { | |
48663c56 | 300 | $crate::eprintln!("[{}:{}] {} = {:#?}", |
e1599b0c | 301 | $crate::file!(), $crate::line!(), $crate::stringify!($val), &tmp); |
0bf4aa26 XL |
302 | tmp |
303 | } | |
304 | } | |
48663c56 | 305 | }; |
48663c56 XL |
306 | ($($val:expr),+ $(,)?) => { |
307 | ($($crate::dbg!($val)),+,) | |
308 | }; | |
1a4d82fc JJ |
309 | } |
310 | ||
e9174d1e SL |
311 | #[cfg(test)] |
312 | macro_rules! assert_approx_eq { | |
60c5eb7d | 313 | ($a:expr, $b:expr) => {{ |
e9174d1e | 314 | let (a, b) = (&$a, &$b); |
60c5eb7d XL |
315 | assert!((*a - *b).abs() < 1.0e-6, "{} is not approximately equal to {}", *a, *b); |
316 | }}; | |
e9174d1e | 317 | } |