Skip to content

Integrate Error trait with panic interfaces #124

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
yaahc opened this issue Oct 17, 2022 · 1 comment
Open

Integrate Error trait with panic interfaces #124

yaahc opened this issue Oct 17, 2022 · 1 comment
Labels
api-change-proposal A proposal to add or alter unstable APIs in the standard libraries S-blocked Status: Blocked on another feature T-libs-api

Comments

@yaahc
Copy link
Member

yaahc commented Oct 17, 2022

Proposal

Problem statement

This is a follow up of the problems documented in https://blog.rust-lang.org/inside-rust/2021/07/01/What-the-error-handling-project-group-is-working-towards.html#1-error-trait--panic-runtime-integration

Motivation, use-cases

Right now the standard library includes multiple interfaces to "promote" an error from an anticipated runtime failure mode to a panic, unwrap and expect. These interfaces are currently lossy, since they Debug format the error and discard the Error trait interface which is meant to provide structured access to contextual pieces of an error for the purpose of reporting. This PR seeks to allow panic handlers to access the richer Error trait interface when reporting panics that have a runtime error as their source.

Solution sketches

At a minimum I believe we should add an fn source to PanicInfo:

impl PanicInfo<'_> {
    pub fn source(&self) -> Option<&(dyn Error + 'static)>;
}

Then, we will need to add interfaces for constructing panics with an additional source error. As a starting point the initial impl PR (linked below) adds the following method

pub const fn panic_source(msg: fmt::Arguments<'_>, source: &(dyn Error + 'static)) -> !;

I don't have strong opinions about exactly what this API should look like, or what the name of the method should be.

  • I've also considered naming it panic_with_source.
  • I've considered modifications to the panic! macro
    • panic!(source = &my_source, "my panic message");

I'm sure there are other approaches as well, very open to suggestions for the best way to structure this.

Finally I think we will need to find some way to integrate these APIs with Result, either so that unwrap and expect will use them internally (not currently possible without making a breaking change or adding new language features) or so that users are steered towards an alternative method when their E type implements the Error trait (the problem here is that there's not a good name to use, given that unwrap_err already exists and means something else1). This is something of an unsolved problem

The best solutions I can think of atm are either (A) to somehow magically solve all the issues with specialization or (B) to change the meaning of unwrap and expect across an edition boundary by introducing something like edition dependent function aliases.

The idea with option (B) is:

  • rename unwrap to unwrap_ok to match unwrap_err, they both require E: Debug still
  • do the same for expect to expect_ok
  • introduce new versions of these that require E: Error, potentially named unwrap_source/expect_source.
  • Change unwrap and expect into edition dependent function aliases where in editions 2021 and earlier they resolve to unwrap_ok/expect_ok and in editions 2024 and beyond they resolve to unwrap_source/expect_source.

Extremely interested in other ideas, but this is the best I could come up with.

Links and related work

What happens now?

This issue is part of the libs-api team API change proposal process. Once this issue is filed the libs-api team will review open proposals in its weekly meeting. You should receive feedback within a week or two.

Footnotes

  1. Previous discussion about alternative names: https://rust-lang.zulipchat.com/#narrow/stream/257204-project-error-handling/topic/naming.20bikeshed.20for.20.60expect.60.20with.20Error.20trait

@yaahc yaahc added T-libs-api api-change-proposal A proposal to add or alter unstable APIs in the standard libraries labels Oct 17, 2022
@Amanieu Amanieu added the S-blocked Status: Blocked on another feature label Jun 3, 2025
@Amanieu
Copy link
Member

Amanieu commented Jun 3, 2025

We discussed this in the @rust-lang/libs-api meeting. We believe that without some form of Result integration, this feature will see little use in practice, so we are unwilling to accept it as it is. Specialization is unlikely to work due to fundamental issues related to lifetime-dependent trait impls.

The only path that we potentially see for this moving forward is via edition-dependent name resolution which would allow us to change the trait bounds on unwrap without breaking code in older editions. However this is still a massive change in the ecosystem. We would be happy to revisit this question once we have support for edition-dependent name resolution in the compiler.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
api-change-proposal A proposal to add or alter unstable APIs in the standard libraries S-blocked Status: Blocked on another feature T-libs-api
Projects
None yet
Development

No branches or pull requests

2 participants