-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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::error::Error: change the error iterator producer #81705
Conversation
r? @KodrAus (rust-highfive has picked a reviewer for you, use r? to override) |
The job Click to see the possible cause of the failure (guessed by this bot)
|
f9ef61a
to
5374179
Compare
To produce an error iterator `std::error::Chain` one had to call `<dyn Error>::chain()`, which was not very ergonomic, because you have to manually cast to a trait object, if you didn't already have one with the type erased. ``` let mut iter = (&my_error as &(dyn Error)).chain(); // or let mut iter = <dyn Error>::chain(&my_error); // or let mut iter = Error::chain(&my_error); ``` The `chain()` method can't be implemented on the Error trait, because of rust-lang#69161 `Chain::new()` replaces `<dyn Error>::chain()` as a good alternative without confusing users, why they can't use `my_error.chain()` directly. The `Error::sources()` method doesn't have this problem, so implement it more efficiently, than one could achieve this with `Chain::new().skip(1)`. Related: rust-lang#58520
5374179
to
e2df4da
Compare
Thanks for pushing this forward @haraldh! If the only thing blocking us from an ergonomic |
@KodrAus yeah, a Feel free to close this PR, if it doesn't fit. |
Since this is all unstable I don’t think there’s any harm in at least re-introducing If we didn’t want to do that yet then adding an example on using What do you think? |
TIL about
std::iter::successors::<&(dyn Error), _>(Some(&my_error), |e| e.source())
std::iter::successors::(my_error.source(), |e| e.source()) So, |
I think the subtle difference that makes an example worth adding is that we need to manually dereference the successor error in that closure, otherwise we run afoul of lifetime mismatches. So it looks a bit more like:
|
To produce an error iterator
std::error::Chain
one had to call<dyn Error>::chain()
, which was not very ergonomic, because you have tomanually cast to a trait object, if you didn't already have one with
the type erased.
The
chain()
method can't be implemented on the Error trait, because of#69161
Chain::new()
replaces<dyn Error>::chain()
as a good alternativewithout confusing users, why they can't use
my_error.chain()
directly.The
Error::sources()
method doesn't have this problem, so implementit more efficiently, than one could achieve this with
Chain::new().skip(1)
.Related: #58520