Closed lukas-code closed 4 months ago
@rustbot label B-unstable A-error-handling
I'm excited about this feature, so if there's anything I can do to help pushing it over the finish line I'd be happy to help. I'm fairly experienced with programming in Rust and I've been silently following various Rust features from RFC to stabilization, but I haven't myself contributed to the compiler or standard library yet.
I think this feature could turn out to be a considerable improvement to Rust. There are quite a few small-ish crates out there that only perform well-specified pure-function-like operations. I can imagine that many of these crates could trivially be no_std
compatible by default (without even requiring a cargo feature gate) were it not for their error types implementing std::error::Error
.
@robamler that would be lovely, I'm happy to hand off and help coordinate that work. I've been focused on governance work since august and haven't had much time for pushing this across the finish line.
I believe the current blockers for this are resolving issues in the provider / generic member access APIs
This comment by @dtolnay best outlines the issues that still need to be resolved: https://github.com/rust-lang/rust/issues/99301#issuecomment-1237530400
Let me know if you have any further questions. The zulip is probably the best way to reach me quickly. I'm not keeping on top of github notifications right now since I still need to unsubscribe to a bunch of things to turn down the volume of notifications I get daily.
@yaahc Thank you for the references!
Do #![feature(error_in_core)]
and #![feature(error_generic_member_access)]
really have to be stabilized together? Maybe I'm missing something here, but it looks like the most pragmatic way forward would be to
error_in_core
with your implementation in #99917, except that the method core::error::Error::provide
would still be unstable with #![feature(error_generic_member_access)]
, just as std::error::Error::provide
is today; and#![feature(error_generic_member_access)]
from stabilization; once those are resolved, both std::error::Error::provide
and core::error::Error::provide
would become available on stable.(I'll reach out on zulip if I don't get any response here; just wanted to leave this comment here as a kind of documentation in case I can't figure this out and someone else needs to take over.)
I think in theory we could stabilize error-in-core before provider but I'm worried since we removed fn backtrace
on the basis of the provider API, if we lock error into core we can never add fn backtrace
back, and if we end up with some unavoidable blocker to stabilizing provider we may end up in a worse situation than we started.
I see, thanks! So I understand that maybe #99301 should be resolved first. I'm following up with the discussion there.
Hey folks, is it planned to implement Sized
?
It would nice to have it work...
... with Result
:
the size for values of type `(dyn core::error::Error + 'static)` cannot be known at compilation time [E0277] doesn't have a size known at compile-time Help: the trait `core::marker::Sized` is not implemented for `(dyn core::error::Error + 'static)` Note: required by a bound in `core::result::Result`
... with From
:
the size for values of type `(dyn core::error::Error + 'static)` cannot be known at compilation time [E0277] doesn't have a size known at compile-time Help: within `error::Error`, the trait `core::marker::Sized` is not implemented for `(dyn core::error::Error + 'static)` Note: required because it appears within the type `error::Error` Note: required by a bound in `core::convert::From`
Hey folks, is it planned to implement
Sized
?
I'm not positive I'm interpreting "implement Sized
" correctly.
Assuming you mean add Sized
as a supertrait of the Error
trait, the answer is a definite no. Doing so would break the ability to create trait objects and would be backwards incompatible as well as defeating the purpose of the error trait.
error[E0038]: the trait `Error` cannot be made into an object
--> src\main.rs:3:37
|
3 | static_assertions::assert_impl_all!(dyn Error: Error);
| ^^^^^^^^^ `Error` cannot be made into an object
|
note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
--> src\main.rs:1:14
|
1 | trait Error: Sized {}
| ----- ^^^^^ ...because it requires `Self: Sized`
| |
| this trait cannot be made into an object...
And here's the link from the above diagnostic for more info: https://doc.rust-lang.org/reference/items/traits.html#object-safety
If I've misinterpreted your question please let me know.
Is there a FCP on the horizon for this feature? It seems relatively straight-forward insofar as its featureset, and it would be nice to allow thing like anyhow
to take advantage of core::error::Error
on stable
.
https://doc.rust-lang.org/stable/core/error/trait.Error.html does not show that this enum is unstable which can be misleading to the end user (it was to me! Yes, I know core::error
is what's displayed as unstable)
From reading this tracking issue and the two blocking tracking issues, it seems like feature(error_generic_member_access)
continues to be an area of active development and iteration. Is there any way stabilization of core::error::Error
could be decoupled from stabilization of the reflection-powered backtrace access?
There's a comment that removal of Error::backtrace()
was predicated on existence of Provider
(or equivalent), but I don't see why re-creating that API would be a blocker to stabilizing the rest of Error
. Regardless of what the final backtrace-related access methods look like, they will have the following properties:
impl Error
in Stable.core
cannot reference OS-specific types or logic in std::backtrace
, so the universe of possible method signatures added to core::error::Error
is limited to those with some sort of indirection through an opaque type in core
. If that type can't be referenced or constructed in Stable then it can't affect the API.For example, various equivalent-but-alternate designs for stack trace access would be API-compatible with the stable parts of the core::error::Error
API despite looking completely different in the unstable parts:
pub trait Error: Debug + Display {
// stable
fn source(&self) -> Option<&(dyn Error + 'static)> { ... }
// stable + deprecated
fn description(&self) -> &str { ... }
fn cause(&self) -> Option<&dyn Error> { ... }
// from the current definition of core::error::Error
//
// unstable, obvious and trivial default implementation, thus no API risk to Stable
// even if the rest of `core::error::Error` is stabilized as-is.
#[unstable]
fn provide<'a>(&'a self, request: &mut Request<'a>) { }
// returns an optional opaque handle to a separate #[unstable] metadata type,
// sort of like the also-in-development DST metadata.
//
// changing to this approach from `provide()` would not affect stable API
#[unstable]
fn metadata<'a>(&'a self) -> Option<ErrorMetadata<'a>> { None }
// another approach, where the `Error` implementation pokes things into
// a provided opaque metadata structure. New methods and APIs could
// be explored there without touching `Error` at all, stable or unstable.
#[unstable]
fn copy_metadata_to(&self, metadata: &mut dyn ErrorMetadata) { }
}
this really needs to be finished
We discussed this in the libs-api meeting today. We're happy with the current definition of the Error
trait now that backtrace
is removed. Note that once this is stabilized, we will not be able to add any methods in the future that mention types outside core
.
This FCP only stabilize the existing Error
trait in core. It does not stabilize the generic member access API which is tracked separately in #99301.
@rfcbot fcp merge
Team member @Amanieu has proposed to merge 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.
:bell: This is now entering its final comment period, as per the review above. :bell:
The final comment period, with a disposition to merge, as per the review above, is now complete.
As the automated representative of the governance process, I would like to thank the author for their work and everyone else who contributed.
This will be merged soon.
Is this targeted for release for 1.81.0? I see no mention of it in https://releases.rs/docs/1.81.0/
Is this targeted for release for 1.81.0? I see no mention of it in https://releases.rs/docs/1.81.0/
It is. You can see in the docs for the beta that the core::error
module is stable. Compare with docs for stable.
I see no mention of it in https://releases.rs/docs/1.81.0/
it doesn't show up on releases.rs, because the stabiliziation pr #125951 is not marked with the relnotes
label
(This was merged a while ago without a tracking issue, so I'm creating this one here now.)
Feature gate:
#![feature(error_in_core)]
This is a tracking issue for moving the
Error
trait to thecore
library.Public API
Steps / History
error_generic_member_access
: https://github.com/rust-lang/rust/issues/99301Unresolved Questions