Common Standard Macros
file!, line!, and column!
The file!, line!, column!, and module_path! macros expand at compile time to literals describing the exact source location where they are invoked.
Source-Location Macros Reference
| Macro | Return Type | Expands To | Example Value |
|---|---|---|---|
file!() |
&'static str |
Source file path where file!() was invoked |
"src/main.rs" |
line!() |
u32 |
1-indexed line number where line!() was invoked |
14 |
column!() |
u32 |
1-indexed UTF-8 character column where column!() was invoked |
20 |
module_path!() |
&'static str |
Module path of the enclosing module | "my_crate::net::http" |
How file!() and line!() Behave Inside macro_rules!
Because file!(), line!(), and column!() use call-site span hygiene, placing file!() and line!() inside a macro_rules! definition expands to the caller's source file and line number, not the line where the macro itself was defined!
macro_rules! trace_here {
($msg:expr) => {
println!(
"[{}:{}:{} in {}] {}",
file!(),
line!(),
column!(),
module_path!(),
$msg
);
};
}
mod worker {
pub fn run() {
trace_here!("starting worker loop");
}
}
fn main() {
trace_here!("application initialized");
worker::run();
}
[src/main.rs:21:5 in main] application initialized
[src/main.rs:16:9 in main::worker] starting worker loop
Comparing file!() / line!() in Macros vs. #[track_caller] on Functions
In regular functions (without a macro wrapper), calling file!() and line!() inside the function body always reports the line inside that function. To obtain the caller's file, line, and column inside a normal Rust function, annotate the function with #[track_caller] and call std::panic::Location::caller():
use std::panic::Location;
#[track_caller]
fn log_caller(message: &str) {
let loc = Location::caller();
println!("[{}:{}:{}] {message}", loc.file(), loc.line(), loc.column());
}
fn main() {
log_caller("called from line 10");
log_caller("called from line 11");
}
[src/main.rs:10:5] called from line 10
[src/main.rs:11:5] called from line 11