Skip to content

Add attribute #[boxing] to allow automatic boxing #419

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

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

daniel-levin
Copy link

Following up on #418, I've got a better strategy and a complete implementation of what it would look like for thiserror to allow you to opt-into generating impl-from-for-box. I have defined a new attribute, #[boxing] which can be used like so:

#[derive(Error, Debug)]
#[error("...")]
pub struct Autoboxed2 {
    #[from]
    #[boxing]
    err: LargeError,
}

pub fn autobox2() -> Result<(), Box<Autoboxed2>> {
    let _ = direct_return_large()?; // no more .map_err(Box::new)!

    Ok(())
}

The PR also includes a number of trybuild-based tests and an example in the RustDoc.

The new attribute is truly opt-in, because it must appear for each field or variant on which it is used. I chose to create a new attribute, rather than to extend the from attribute. My reasoning is based on the "public interest" (#418) in having thiserror automatically box errors. Overriding #[from] with arguments would complicate thiserror. Richer From implementations are already achievable with derive_more.

@dtolnay
Copy link
Owner

dtolnay commented Jun 11, 2025

I chose to create a new attribute, rather than to extend the from attribute. My reasoning is based on the "public interest" (#418) in having thiserror automatically box errors. Overriding #[from] with arguments would complicate thiserror.

Could you spell this out a little more for me? I do not understand what the argument is here or what alternative was ruled out.

@daniel-levin
Copy link
Author

daniel-levin commented Jun 13, 2025

I'm open to the idea of adding the capability to derive a from-for-box using the existing #[from] attribute. What are your thoughts on a preferred approach?

I saw this comment in the source code, which made me wary of accidentally trampling on an overloaded attribute.

One alternative could look like this:

#[derive(Debug, Error)]
#[error("...")]
pub struct MyError(#[from(boxing)] SomeError);

This would be somewhat nicer to read than an additional attribute, as proposed in the PR proper. I want there to only be one kind of smart pointer for which there is an automatic From implementation, to easily avoid passing large structures around on the stack. Box is the most appropriate smart pointer for this purpose. I don't want anyone to get the impression that thiserror is going to parametrize #[from] to allow the implementation of From for Arc, Pin, and others. That is more appropriate for other libraries, such as derive_more. The only reason that Box is different is that it helps users of this library fix a self-inflicted problem - large errors - without needing to bring in another proc macro crate or manually implement From.

@daniel-levin daniel-levin marked this pull request as draft June 14, 2025 06:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants