#[track_caller] seems not to change anything, turns out to only work with Location::caller not with file!()/line!() macro

Hi all,

I solved this on my own while writing this question, but I'll share it to let others who might have the same problem know:

Consider this code:

use anyhow::format_err;

fn main() {
    let res: anyhow::Result<()> = Err(format_err!("Error"));
    res.log();
}

pub(crate) trait LogExt<T> {
    #[track_caller]
    fn log(self) -> Option<T>; // line 5
}

impl<T> LogExt<T> for anyhow::Result<T> {
    #[track_caller]
    fn log(self) -> Option<T> {
        match self {
            Err(e) => {
                println!("{}:{}: {}", file!(), line!(), e); // line 18
                None
            }
            Ok(v) => Some(v),
        }
    }
}

Expected output: src/main.rs:5: Error
Actual output: src/main.rs:18: Error

playground

The problem is: You have to use Location::caller() instead. This code works fine:

use anyhow::format_err;
use std::panic::Location;

fn main() {
    let res: anyhow::Result<()> = Err(format_err!("Error"));
    res.log();
}

pub(crate) trait LogExt<T> {
    #[track_caller]
    fn log(self) -> Option<T>;
}

impl<T> LogExt<T> for anyhow::Result<T> {
    #[track_caller]
    fn log(self) -> Option<T> {
        match self {
            Err(e) => {
                let l = Location::caller();
                println!("{}:{}: {}", l.file(), l.line(), e);
                None
            }
            Ok(v) => Some(v),
        }
    }
}

playground

1 Like