Skip to content

Commit 000be8f

Browse files
committed
dbg!(expr) implementation.
1 parent f7f4c50 commit 000be8f

File tree

1 file changed

+118
-0
lines changed

1 file changed

+118
-0
lines changed

src/libstd/macros.rs

100644100755
+118
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,124 @@ macro_rules! eprintln {
220220
})
221221
}
222222

223+
/// A macro for quick and dirty debugging with which you can inspect
224+
/// the value of a given expression. An example:
225+
///
226+
/// ```rust
227+
/// #![feature(dbg_macro)]
228+
///
229+
/// let a = 2;
230+
/// let b = dbg!(a * 2) + 1;
231+
/// // ^-- prints: [src/main.rs:4] a * 2 = 4
232+
/// assert_eq!(b, 5);
233+
/// ```
234+
///
235+
/// The macro works by using the `Debug` implementation of the type of
236+
/// the given expression to print the value to [stderr] along with the
237+
/// source location of the macro invocation as well as the source code
238+
/// of the expression.
239+
///
240+
/// Invoking the macro on an expression moves and takes ownership of it
241+
/// before returning the evaluated expression unchanged. If the type
242+
/// of the expression does not implement `Copy` and you don't want
243+
/// to give up ownership, you can instead borrow with `dbg!(&expr)`
244+
/// for some expression `expr`.
245+
///
246+
/// and should be avoided
247+
/// for longer periods in version control
248+
///
249+
/// # Stability
250+
///
251+
/// The exact output printed by this macro should not be relied upon
252+
/// and is subject to future changes.
253+
///
254+
/// # Panics
255+
///
256+
/// Panics if writing to `io::stderr` fails.
257+
///
258+
/// # Further examples
259+
///
260+
/// With a method call:
261+
///
262+
/// ```rust
263+
/// #![feature(dbg_macro)]
264+
///
265+
/// fn foo(n: usize) {
266+
/// if let Some(_) = dbg!(n.checked_sub(4)) {
267+
/// // ...
268+
/// }
269+
/// }
270+
///
271+
/// foo(3)
272+
/// ```
273+
///
274+
/// This prints to [stderr]:
275+
///
276+
/// ```text,ignore
277+
/// [src/main.rs:4] n.checked_sub(4) = None
278+
/// ```
279+
///
280+
/// Naive factorial implementation:
281+
///
282+
/// ```rust
283+
/// #![feature(dbg_macro)]
284+
///
285+
/// fn factorial(n: u32) -> u32 {
286+
/// if dbg!(n <= 1) {
287+
/// dbg!(1)
288+
/// } else {
289+
/// dbg!(n * factorial(n - 1))
290+
/// }
291+
/// }
292+
///
293+
/// dbg!(factorial(4));
294+
/// ```
295+
///
296+
/// This prints to [stderr]:
297+
///
298+
/// ```text,ignore
299+
/// [src/main.rs:3] n <= 1 = false
300+
/// [src/main.rs:3] n <= 1 = false
301+
/// [src/main.rs:3] n <= 1 = false
302+
/// [src/main.rs:3] n <= 1 = true
303+
/// [src/main.rs:4] 1 = 1
304+
/// [src/main.rs:5] n * factorial(n - 1) = 2
305+
/// [src/main.rs:5] n * factorial(n - 1) = 6
306+
/// [src/main.rs:5] n * factorial(n - 1) = 24
307+
/// [src/main.rs:11] factorial(4) = 24
308+
/// ```
309+
///
310+
/// The `dbg!(..)` macro moves the input:
311+
///
312+
/// ```compile_fail
313+
/// #![feature(dbg_macro)]
314+
///
315+
/// /// A wrapper around `usize` which importantly is not Copyable.
316+
/// #[derive(Debug)]
317+
/// struct NoCopy(usize);
318+
///
319+
/// let a = NoCopy(42);
320+
/// let _ = dbg!(a); // <-- `a` is moved here.
321+
/// let _ = dbg!(a); // <-- `a` is moved again; error!
322+
/// ```
323+
///
324+
/// [stderr]: https://en.wikipedia.org/wiki/Standard_streams#Standard_error_(stderr)
325+
#[macro_export]
326+
#[unstable(feature = "dbg_macro", issue = "54306")]
327+
macro_rules! dbg {
328+
($val:expr) => {
329+
// Use of `match` here is intentional because it affects the lifetimes
330+
// of temporaries - https://stackoverflow.com/a/48732525/1063961
331+
match $val {
332+
tmp => {
333+
eprintln!("[{}:{}] {} = {:#?}",
334+
file!(), line!(), stringify!($val), &tmp);
335+
tmp
336+
}
337+
}
338+
}
339+
}
340+
223341
#[macro_export]
224342
#[unstable(feature = "await_macro", issue = "50547")]
225343
#[allow_internal_unstable]

0 commit comments

Comments
 (0)