Skip to content

Should Result::from_residual() be #[track_caller]? #89261

Closed
@mcy

Description

@mcy

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!

Metadata

Metadata

Assignees

No one assigned

    Labels

    F-track_caller`#![feature(track_caller)]`T-libsRelevant to the library team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions