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
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),
}
}
}