Closed
Description
I tried this code:
use std::panic::Location;
#[derive(Debug)]
pub struct Traced<E> {
inner: E,
location: &'static Location<'static>,
}
impl<E> From<E> for Traced<E> {
#[track_caller]
fn from(inner: E) -> Self {
Self { inner, location: Location::caller(), }
}
}
fn square(x: u16) -> Result<u16, Traced<()>> {
Ok(x.checked_mul(x).ok_or(())?)
}
pub fn main() {
let x = 2000;
println!("{:?}", square(x));
}
I expected to see this happen: Prints Err(..., location: <body of square()>)
.
Instead, this happened: Prints Err(..., location: <the guts of libcore>)
.
Godbolt: https://godbolt.org/z/s5YaT4Kxn
There is a philosophical question about whether this should work at all. After all, people going in via into()
would get a location in the guts of convert.rs. I'm definitely curious about what people think... I feel like I'm abusing #[track_caller]
somewhat here, so maybe we don't want to sanction this usage?
There's definitely a Pandora's box of stuff here if we do want it to work properly: for example, we would want Into
to be #[track_caller]
if the corresponding From
is, too, but not otherwise!