(All of these are unstable, and thus can only be used from a nightly compiler.)

log_syntax!()

#![feature(log_syntax)]

macro_rules! logged_sum {
    ($base:expr) => { 
        { log_syntax!(base = $base); $base } 
    };
    ($a:expr, $($rest:expr),+) => { 
        { log_syntax!(a = $a, rest = $($rest),+); $a + logged_sum!($($rest),+) } 
    };
}

const V: u32 = logged_sum!(1, 2, 3);

During compilation, it will print the following to stdout:

a = 1 , rest = 2 , 3
a = 2 , rest = 3
base = 3

--pretty expanded

Run the compiler with:

rustc -Z unstable-options --pretty expanded filename.rs

This will expand all macros and then prints the expanded result to stdout, e.g. the above will probably output:

#![feature(prelude_import)]
#![no_std]
#![feature(log_syntax)]
#[prelude_import]
use std::prelude::v1::*;
#[macro_use]
extern crate std as std;


const V: u32 = { false; 1 + { false; 2 + { false; 3 } } };

(This is similar to the -E flag in the C compilers gcc and clang.)