Skip to content
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

RFC: Generic member access for dyn Error trait objects #3461

Open
wants to merge 43 commits into
base: master
Choose a base branch
from
Open
Changes from 1 commit
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
46bb80d
Initial commit for first rfc
yaahc Apr 1, 2020
47cc77d
First wave of edits
yaahc Apr 2, 2020
f638485
more edits
yaahc Apr 2, 2020
7fd3bdb
more edits
yaahc Apr 2, 2020
1027612
maybe time to start showing ppl this
yaahc Apr 2, 2020
3a6a6a9
simplify summary
yaahc Apr 2, 2020
45e4705
oops, didnt realize this was a suggested edit
yaahc Apr 2, 2020
43d659a
post eliza review
yaahc Apr 2, 2020
dd8a63b
Adams comments
yaahc Apr 6, 2020
b31fe0c
rewrite to focus on nika's version
yaahc May 4, 2020
1dd49d9
proof reading
yaahc May 4, 2020
ea945f4
boop
yaahc May 4, 2020
ed38f90
boop
yaahc May 4, 2020
ba0e1bf
boop
yaahc May 4, 2020
6fcc1b1
boop
yaahc May 4, 2020
8968547
boop
yaahc May 4, 2020
d274fd4
boop
yaahc May 4, 2020
af8981e
boop
yaahc May 4, 2020
5a7e47d
boop
yaahc May 4, 2020
41ec1ec
boop
yaahc May 4, 2020
6049030
boop
yaahc May 5, 2020
60b82e8
fix attribution to be less confusing and mention source
yaahc May 5, 2020
b8e5b92
nikanit
yaahc May 5, 2020
9f52696
Update text/0000-dyn-error-generic-member-access.md
yaahc May 5, 2020
c983ddd
rename to provide_context
yaahc May 5, 2020
f2e4f72
Update based on kennys changes
yaahc May 5, 2020
6944d14
Document divergence from object-provider crate
yaahc May 5, 2020
a2cb4b5
Add example to code snippet
yaahc May 5, 2020
a622c30
update to include nikas updates
yaahc May 6, 2020
1768e57
Update text/0000-dyn-error-generic-member-access.md
yaahc May 7, 2020
6ca88bb
Apply suggestions from code review
yaahc May 7, 2020
61259be
reply to adams coments
yaahc May 11, 2020
c650a65
make type_id fn in Request private
yaahc May 11, 2020
c3faa49
remove type_id fn
yaahc May 11, 2020
f556131
update example to use successors
yaahc Jul 28, 2020
f24561f
add back missing write
yaahc Jul 28, 2020
6c313f7
update rfc to include new object provider API
yaahc Dec 4, 2020
2ec0c5c
add examples for by value
yaahc Dec 4, 2020
a59d39c
Apply suggestions from code review
yaahc Feb 26, 2021
7d9692f
update RFC to be based on dyno design
yaahc Apr 12, 2021
5ef13c0
update guide-level example code
waynr Jul 10, 2023
53e35ba
fix typo
waynr Jul 10, 2023
0cffa52
update the guide-level explanation
waynr Jul 10, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
more edits
  • Loading branch information
yaahc authored and waynr committed Jul 20, 2023
commit f6384850c57a60661070ff691b39b93f47ec55c1
63 changes: 36 additions & 27 deletions text/0000-dyn-error-generic-member-access.md
Original file line number Diff line number Diff line change
@@ -30,15 +30,15 @@ used, or forms of context that are defined outside of the standard library.

## Example use cases this enables

* `SpanTrace` a backtrace like type from the `tracing-error` library
* using `backtrace::Backtrace` instead of `std::backtrace::Backtrace`
* zig-like Error Return Traces by extracting `Location` types from errors
gathered via `#[track_caller]`
gathered via `#[track_caller]` or some similar mechanism.
* error source trees instead of chains by accessing the source of an error as a
slice of errors rather than as a single error, such as a set of errors caused
when parsing a file
* `SpanTrace` a backtrace like type from the `tracing-error` library
* Help text such as suggestions or warnings attached to an error report


By adding a generic form of these functions that works around the restriction
on generics in vtables we could support a greater diversity of error handling
needs and make room for experimentation with new forms of context in error
@@ -47,28 +47,26 @@ reports.
# Guide-level explanation
[guide-level-explanation]: #guide-level-explanation

When implementing error handling in rust there are two main aspects that should
be considered, the creation of errors and the reporting of errors.

Error handling in rust consists mainly of two steps, creation/propogation and
reporting. The `std::error::Error` trait exists to bridge this gap. It does so
by acting as a consistent interface that all Error types can implement to allow
Error Reporting types to handle them in a consistent manner when constructing
reports for end users.
reporting. The `std::error::Error` trait exists to bridge the gap between these
two concerns. It does so by acting as a consistent interface that all error
types can implement to allow error reporting types to handle them in a
consistent manner when constructing reports for end users.

The error trait accomplishes this by providing a set of methods for accessing
members of `dyn Error` trait objects. For accessing the message that should be
rendered to the end user the Error trait implements the `Display` trait. For
accessing `dyn Error` members it provides the `source` function, which
conventionally represents the lower level error that caused a subsequent error.
For accessing a `Backtrace` of the state of the stack when an error was created
it provides the `backtrace` function. For all other forms of context relevant
to an Error Report the error trait provides the `context`/`context_any`
functions.

As an example lets explore how one could implement an error reporting type that
retrieves the Location where each error in the chain was created, if it exists,
and renders it as part of the chain of errors.
members of `dyn Error` trait objects. The main member, the error message
itself, is handled by the `Display` trait which is a requirement for
implementing the Error trait. For accessing `dyn Error` members it provides the
`source` function, which conventionally represents the lower level error that
caused the current error. And for accessing a `Backtrace` of the state of the
stack when an error was created it provides the `backtrace` function. For all
other forms of context relevant to an Error Report the error trait provides the
`context`/`context_any` functions.

As an example of how to use these types to construct an error report lets
explore how one could implement an error reporting type that retrieves the
Location where each error in the chain was created, if it exists, and renders
it as part of the chain of errors.

The goal is to implement an Error Report that looks something like this:

@@ -170,11 +168,10 @@ impl fmt::Debug for ErrorReporter {
There are two additions necessary to the standard library to implement this
proposal:


First we need to add a function for dyn Error trait objects that will be used
by error reporters to access members given a generic type. This function
circumvents restrictions on generics in trait functions by being implemented
for trait objects only, rather than as a member of the trait itself.
1.) Add a function for dyn Error trait objects that will be used by error
reporters to access members given a generic type. This function circumvents
restrictions on generics in trait functions by being implemented for trait
objects only, rather than as a member of the trait itself.

```rust
impl dyn Error {
@@ -184,6 +181,18 @@ impl dyn Error {
}
```

With the expected usage:

```rust
// With explicit parameter passing
let spantrace = error.context::<SpanTrace>();

// With a type inference
fn get_spantrace(error: &(dyn Error + 'static)) -> Option<&SpanTrace> {
error.context()
}
```

Second we need to add a member to the `Error` trait to provide the `&dyn Any`
trait objects to the `context` fn for each member based on the type_id.