Reference page
`#[track_caller]` in miniextendr
The #[miniextendr] macro automatically adds #[track_caller] to Rust functions for better panic location reporting.
The #[miniextendr] macro automatically adds #[track_caller] to Rust functions for better panic location reporting.
๐What it does
When a panic occurs (e.g., from .unwrap(), .expect(), or assert!()), Rust reports the source location. With #[track_caller], the location propagates through the call chain, showing where the panicking function was called from rather than where the panic originated.
๐Example
#[miniextendr]
pub fn process_data(x: i32) {
let result: Option<i32> = None;
result.unwrap(); // panics here
}
Without #[track_caller]: Panic reports the location inside Option::unwrap() in the standard library.
With #[track_caller] (automatic): Panic reports lib.rs:4 - the line where .unwrap() was called in your code.
๐When it helps
The automatic #[track_caller] is most useful for panics from:
.unwrap()and.expect()onOptionandResultassert!(),assert_eq!(),assert_ne!()- Any function that uses
std::panic::Location::caller()
๐When it doesnโt help
#[track_caller] does NOT affect:
- Direct
panic!()calls - these always report their own location - Argument conversion errors in the generated wrapper - these report the
#[miniextendr]line extern "C-unwind"functions - these donโt support#[track_caller]
๐Propagation through call chains
For #[track_caller] to propagate through multiple function calls, ALL functions in the chain need the attribute:
#[track_caller]
fn helper() {
let x: Option<i32> = None;
x.unwrap();
}
#[miniextendr] // automatically adds #[track_caller]
pub fn my_function() {
helper(); // panic location will be here if helper has #[track_caller]
}
Without #[track_caller] on helper(), the panic location shows inside helper() where unwrap() was called.
๐Skipped cases
The macro does NOT add #[track_caller] when:
- The function already has
#[track_caller] - The function has an explicit ABI (e.g.,
extern "C-unwind")