From 000be8fe83a854796e55ed92458a7b70cc17c3a2 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Tue, 18 Sep 2018 02:42:39 +0200 Subject: [PATCH] dbg!(expr) implementation. --- src/libstd/macros.rs | 118 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 118 insertions(+) mode change 100644 => 100755 src/libstd/macros.rs diff --git a/src/libstd/macros.rs b/src/libstd/macros.rs old mode 100644 new mode 100755 index e60ef46e738b4..8344c73c9bea3 --- a/src/libstd/macros.rs +++ b/src/libstd/macros.rs @@ -220,6 +220,124 @@ macro_rules! eprintln { }) } +/// A macro for quick and dirty debugging with which you can inspect +/// the value of a given expression. An example: +/// +/// ```rust +/// #![feature(dbg_macro)] +/// +/// let a = 2; +/// let b = dbg!(a * 2) + 1; +/// // ^-- prints: [src/main.rs:4] 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`. +/// +/// and should be avoided +/// for longer periods in version control +/// +/// # 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 +/// #![feature(dbg_macro)] +/// +/// 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 +/// #![feature(dbg_macro)] +/// +/// 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 +/// #![feature(dbg_macro)] +/// +/// /// 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! +/// ``` +/// +/// [stderr]: https://en.wikipedia.org/wiki/Standard_streams#Standard_error_(stderr) +#[macro_export] +#[unstable(feature = "dbg_macro", issue = "54306")] +macro_rules! dbg { + ($val:expr) => { + // Use of `match` here is intentional because it affects the lifetimes + // of temporaries - https://stackoverflow.com/a/48732525/1063961 + match $val { + tmp => { + eprintln!("[{}:{}] {} = {:#?}", + file!(), line!(), stringify!($val), &tmp); + tmp + } + } + } +} + #[macro_export] #[unstable(feature = "await_macro", issue = "50547")] #[allow_internal_unstable]