-
Notifications
You must be signed in to change notification settings - Fork 13.4k
std: implement Error
for Box<dyn Error>
#58974
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
std: implement Error
for Box<dyn Error>
#58974
Conversation
r? @bluss (rust_highfive has picked a reviewer for you, use r? to override) |
This comment has been minimized.
This comment has been minimized.
By using an internal auto trait, we can implement `Error` for `Box<dyn Error>` without causing conflicts for the existing `From` implementations.
0562b85
to
79ee19b
Compare
As I mentioned in the previous PR, I'd normally add "bounds asserts" so that any future edits don't accidentally break impls. Is there a preferred pattern or place to do that in libstd? |
/// it, we cannot pass `Box<dyn Error>` to anything asking for `E: Error`. | ||
/// | ||
/// To get around the conflict, an auto trait is used, since we can have | ||
/// negative imlementations. Then, the `From<E: Error>` implementation above |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Randomly found a minor spelling error: imlementations.
Ping? |
@seanmonstar Are there any similar uses of auto traits in stable Rust at the moment such that we do not add anything fundamentally new to the language? If not this will require sign-off from the language team and deeper consideration wrt. implications re. the type system. |
@Centril I'm not aware of anything else in libstd using this kind of trick. If this were merged, and something about how the trick (like auto traits) needed to be changed that would make this no longer work, it would likely require specialization to have progressed enough to allow these overlapping implementations instead. There is desire by the libs team to have (And personally, having just moved several tower middlewares to return a |
OK, then I'm generally disinclined to allow this special case on stable until such time that we are 100% certain that it can be soundly generalized. |
If neither of those could no longer satisfy this requirement, then the compiler could add custom support. That |
I'm not OK with adding ad-hoc custom support for just this. Such treatment of the type system is not something I'm in favor of.
Maddening as it may be, we should live with the mistake until such time it can be fixed by a general mechanism. |
Seems we don't agree there. That's OK! Still, I'd welcome hearing from others that would need to comment due to the |
Is there a way I can ping the related teams? Or should I just ping individuals? |
You cannot ping teams unless you are member of |
Very well. @alexcrichton @SimonSapin @withoutboats I've seen you all to comment before about improvements to |
This auto trait is not really internal - it appears in the public API. I want to see this impl exist, but I don't think it is a good idea to add these kinds of coherence hacks to std. Specialization would allow adding this impl without any hacks, but needs more energy behind it for the feature to get implemented soundly. And FWIW, in my opinion the mistake we made was in making |
I would personally agree with @withoutboats that this is not internal due to the exact motivation of the PR, enabling something that's been long desired. Building something so fundamental on unstable features that have a questionable stabilization path and deep implications in the compiler make me pretty uneasy. I think that we'll want to hold off on this until more around specialization develops to see if that's a viable strategy, as well as more developments on the failure-in-libstd story |
Based on #58974 (comment), #58974 (comment), #58974 (comment), and #58974 (comment): @rfcbot close |
Team member @Centril has proposed to close this. The next step is review by the rest of the tagged team members:
No concerns currently listed. Once a majority of reviewers approve (and at most 2 approvals are outstanding), this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up! See this document for info about what commands tagged team members can give me. |
I can put these pieces in an internal module so that they are truly private, if that's the concern. Or did you mean as Alex did, that this is using an auto trait to allow an addition to the "public" API?
I can appreciate that, I was torn on whether to open this PR or not. However, I'd like to be absolutely certain as to the reason for closing this: is it specifically because this uses an unstable feature (auto traits) to allow constructing an There are several "stable", "public" APIs in libstd that were built off unstable features:
I'm sure there are others, and while some are less relevant, I'd prefer to identify what exactly is different. I feel like this mechanism is quite self-contained, and likely any other method of providing this |
For at least some of those, what’s different is that the unstable features are used in implementation details and are not "visible" in the public API surface. |
In principle I wouldn't mind landing an implementation like this using an auto trait. I consider it more valuable to have the desired impl work than to attempt to keep the long list of impls under As specialization matures, would it be backward compatible to transition the implementation to use that instead while maintaining the same set of impls as in this PR? |
Be aware that this PR as written is a breaking change: use std::error::Error;
// used to work
fn f<E: Error + 'static>(e: E) -> Box<dyn Error> {
e.into()
} error[E0277]: the trait bound `E: std::error::NotBoxDynError` is not satisfied in `std::error::IsBoxDynError<E>`
--> src/main.rs:5:7
|
5 | e.into()
| ^^^^ within `std::error::IsBoxDynError<E>`, the trait `std::error::NotBoxDynError` is not implemented for `E`
|
= help: consider adding a `where E: std::error::NotBoxDynError` bound
= note: required because it appears within the type `std::error::IsBoxDynError<E>`
= note: required because of the requirements on the impl of `std::convert::From<E>` for `std::boxed::Box<dyn std::error::Error>`
= note: required because of the requirements on the impl of `std::convert::Into<std::boxed::Box<dyn std::error::Error>>` for `E` |
Wow, excellent catch! I'd been working with this playground, and the compiler was fine with I'll be jumping back into the playground trying some more things, but it might be impossible with just an auto trait. An alternative is if we could add an attribute or something to the |
Others might have thoughts, but so long as specializing that impl was restricted to the standard library, I'd feel a lot more comfortable with that then the current PR, as it lines up more closely with things that we'd like to have be possible using specialization. It also has other uses such as |
I'm not inclined to support the implementation here by anything other than a stable and general mechanism. In particular, I'm not at all comfortable with the assumption that "specialization will remove the hack later when it gets stable". It feels like a high risk proposition to me. |
🔔 This is now entering its final comment period, as per the review above. 🔔 |
Well, it was worth a shot. Unfortunately, as an update to my previous comment, I've been convinced to not care about otherwise improving the situation. |
One for the edition wishlist? |
@derekdreery see |
By using an internal auto trait, we can implement
Error
forBox<dyn Error>
without causing conflicts for the existing
From
implementations.Found a way to get passed the previous problem.