-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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
Implement Error for &(impl Error) #75180
Conversation
r? @sfackler (rust_highfive has picked a reviewer for you, use r? to override) |
@bors try |
⌛ Trying commit 39466bc with merge 353a0a223066e9f46a1d935f2271a26c3c5002bb... |
☀️ Try build successful - checks-actions, checks-azure |
@craterbot check |
👌 Experiment ℹ️ Crater is a tool to run experiments across parts of the Rust ecosystem. Learn more |
With this trait impl, the following code would begin to compile: use std::{fmt, error::Error};
#[derive(Debug)]
pub struct MyError;
impl fmt::Display for MyError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "my error")
}
}
impl Error for MyError {}
fn is_err<T: Error>() {}
fn main() {
is_err::<&MyError>();
is_err::<&dyn Error>();
is_err::<&(dyn Error + 'static)>();
} This is an example of code that no longer compiles with this change: use std::{fmt, error::Error};
#[derive(Debug)]
pub struct MyError;
impl fmt::Display for MyError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "my error")
}
}
impl Error for MyError {}
impl<'a> Error for &'a MyError {} It fails with:
Looks like
which can be fixed by: - let errors = iter::successors(Some(error), |error| error.source());
+ let errors = iter::successors(Some(error), |error| (*error).source()); cc @yaahc So far I haven't found breakage in the test suites of We could try and come up with some object-safe adapter to implement |
@KodrAus what's the goal of this change? |
@yaahc Sorry to drop you into a random PR like that! The goal is to try make
all don’t implement the We have coherence issues with |
aah yea, I've wanted a way to abstract over types that deref to error like Last time I tried implementing a trait for this I think the problem was that I'd need higher kinded types to express it. |
Hmm, so I think // in core
impl<T> From<T> for T;
// in std
impl<'a, E: Error + 'a> From<E> for Box<dyn Error + 'a>; which I think specialization doesn't quite cover so we might need a sprinkling of compiler magic to work around it 🤔 The // in alloc
impl<T, U: ?Sized> From<T> for Box<U> where T: Unsize<U>; That still conflicts with On top of this PR, there is also the conservative method-based approach to look at for converting impl dyn Error {
pub fn as_error(self: &Box<Self>) -> Compat<&Self>;
pub fn into_error(self: Box<Self>) -> Compat<Box<Self>>;
}
pub struct Compat<T>(T);
impl<'a, T: ?Sized + Error> Error for Compat<&'a T>;
impl<T: ?Sized + Error> Error for Compat<Box<T>>; I guess this is all stuff to track in the Error Handling Group once it's bootstrapped? 🙂 |
would you mind elaborating on this one? I had thought that the second impl would work if we marked the first one as |
I'd thought so too... but it didn't work out when I tried it. I had a browse back through the RFC and I think my understanding of specialization is just wrong. I've been thinking of it a bit like the CSS The limitations section of the RFC talks a bit about this, but it's hard to understand specialization casually so I might still be misunderstanding things. |
hmm, im in a similar boat of not being sure how close to reality my understanding of specialization is. I know there's some edge cases about lifetimes wrt specialization, so the If we cant find a way to impl Error for |
🚧 Experiment ℹ️ Crater is a tool to run experiments across parts of the Rust ecosystem. Learn more |
🎉 Experiment
|
So the results of the crater run are finally in! We have a few regressions: We now need to manually deref Some crates now have unnecessary implementations of Some that can no longer use I’d like to work through the implications for What do you think @yaahc @rust-lang/libs? |
@KodrAus I think my initial reaction here is that since there is breakage, it might be better if a change like this were considered by the error handling working group. Mostly just so that it's considered in the context of other changes we might like to make. |
@BurntSushi still waiting on that last vote to establish the project group :( |
The project group has been established. I'll mark this PR as S-blocked on that project group's decisions. |
@bors r+ |
📌 Commit bbf5001 has been approved by |
…as-schievink Rollup of 14 pull requests Successful merges: - rust-lang#75180 (Implement Error for &(impl Error)) - rust-lang#78578 (Permit mutable references in all const contexts) - rust-lang#79174 (Make std::future a re-export of core::future) - rust-lang#79884 (Replace magic numbers with existing constants) - rust-lang#80855 (Expand assert!(expr, args..) to include $crate for hygiene on 2021.) - rust-lang#80933 (Fix sysroot option not being honored across rustc) - rust-lang#81259 (Replace version_check dependency with own version parsing code) - rust-lang#81264 (Add unstable option to control doctest run directory) - rust-lang#81279 (Small refactor in typeck) - rust-lang#81297 (Don't provide backend_optimization_level query for extern crates) - rust-lang#81302 (Fix rendering of stabilization version for trait implementors) - rust-lang#81310 (Do not mark unit variants as used when in path pattern) - rust-lang#81320 (Make bad shlex parsing a pretty error) - rust-lang#81338 (Clean up `dominators_given_rpo`) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
See rust-lang/rust#75180. ``` error[E0119]: conflicting implementations of trait `std::error::Error` for type `&(dyn error::RubyException + 'static)`: --> artichoke-backend/src/error.rs:128:1 | 128 | impl error::Error for &dyn RubyException {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: conflicting implementation in crate `std`: - impl<'a, T> std::error::Error for &'a T where T: std::error::Error, T: ?Sized; error[E0119]: conflicting implementations of trait `std::error::Error` for type `&(dyn error::RubyException + 'static)`: --> artichoke-backend/src/error.rs:128:1 | 128 | impl error::Error for &dyn RubyException {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: conflicting implementation in crate `std`: - impl<'a, T> std::error::Error for &'a T where T: std::error::Error, T: ?Sized; error: aborting due to previous error For more information about this error, try `rustc --explain E0119`. error: could not document `artichoke-backend` ```
Hi folks, the Crater docs mention that it discovers and tests Rust codebases on GitHub. Is this still true? This PR broke an unpublished project of mine, see artichoke/artichoke#1069. Should I have expected a ticket or to be listed as a regression in this ticket?
I turned out to not need this impl for Artichoke to compile, but if I did, i'd be in a tricky spot in CI which must pass on both stable and nightly (for building rustdoc).
|
to my knowledge it does still lookup git repos. I am not super familiar with the crater UI so I might be misinterpreting this but I think what happened is that your crate was failing to compile on with both versions of Here are the errors it ran into:
I don't really know what this means though, it seems like they discard the root cause error. :/ |
that's not your repo fault but the way crater is configured sometimes it has issues with some of the repositories since crater is sand-boxed and other stuff |
@yaahc @Dylan-DPC I pulled the Given that crater's intent is to build projects with specific versions of |
@lopopolo I went ahead and opened an issue on |
@yaahc thank you! |
@yaahc for future reference, the "errors" section means an internal Crater error. If the crate failed to build both before and after the change it will be marked as "build-fail". |
Pkgsrc changes: * Remove one SunOS patch, apparently no longer needed. * Adapt one patch for Darwin, adjust cargo checksum accordingly. * Adjust bootstraps to version 1.50.0. Version 1.51.0 (2021-03-25) ============================ Language -------- - [You can now parameterize items such as functions, traits, and `struct`s by constant values in addition to by types and lifetimes.][79135] Also known as "const generics" E.g. you can now write the following. Note: Only values of primitive integers, `bool`, or `char` types are currently permitted. ```rust struct GenericArray<T, const LENGTH: usize> { inner: [T; LENGTH] } impl<T, const LENGTH: usize> GenericArray<T, LENGTH> { const fn last(&self) -> Option<&T> { if LENGTH == 0 { None } else { Some(&self.inner[LENGTH - 1]) } } } ``` Compiler -------- - [Added the `-Csplit-debuginfo` codegen option for macOS platforms.][79570] This option controls whether debug information is split across multiple files or packed into a single file. **Note** This option is unstable on other platforms. - [Added tier 3\* support for `aarch64_be-unknown-linux-gnu`, `aarch64-unknown-linux-gnu_ilp32`, and `aarch64_be-unknown-linux-gnu_ilp32` targets.][81455] - [Added tier 3 support for `i386-unknown-linux-gnu` and `i486-unknown-linux-gnu` targets.][80662] - [The `target-cpu=native` option will now detect individual features of CPUs.][80749] - [Rust now uses `inline-asm` for stack probes when used with LLVM 11.0.1+][77885] \* Refer to Rust's [platform support page][forge-platform-support] for more information on Rust's tiered platform support. Libraries --------- - [`Box::downcast` is now also implemented for any `dyn Any + Send + Sync` object.][80945] - [`str` now implements `AsMut<str>`.][80279] - [`u64` and `u128` now implement `From<char>`.][79502] - [`Error` is now implemented for `&T` where `T` implements `Error`.][75180] - [`Poll::{map_ok, map_err}` are now implemented for `Poll<Option<Result<T, E>>>`.][80968] - [`unsigned_abs` is now implemented for all signed integer types.][80959] - [`io::Empty` now implements `io::Seek`.][78044] - [`rc::Weak<T>` and `sync::Weak<T>`'s methods such as `as_ptr` are now implemented for `T: ?Sized` types.][80764] Stabilized APIs --------------- - [`Arc::decrement_strong_count`] - [`Arc::increment_strong_count`] - [`Once::call_once_force`] - [`Peekable::next_if_eq`] - [`Peekable::next_if`] - [`Seek::stream_position`] - [`array::IntoIter`] - [`panic::panic_any`] - [`ptr::addr_of!`] - [`ptr::addr_of_mut!`] - [`slice::fill_with`] - [`slice::split_inclusive_mut`] - [`slice::split_inclusive`] - [`slice::strip_prefix`] - [`slice::strip_suffix`] - [`str::split_inclusive`] - [`sync::OnceState`] - [`task::Wake`] Cargo ----- - [Added the `split-debuginfo` profile option to control the -Csplit-debuginfo codegen option.][cargo/9112] - [Added the `resolver` field to `Cargo.toml` to enable the new feature resolver and CLI option behavior.][cargo/8997] Version 2 of the feature resolver will try to avoid unifying features of dependencies where that unification could be unwanted. Such as using the same dependency with a `std` feature in a build scripts and proc-macros, while using the `no-std` feature in the final binary. See the [Cargo book documentation][feature-resolver@2.0] for more information on the feature. Rustdoc ------- - [Rustdoc will now include documentation for methods available from `Deref` traits.][80653] - [You can now provide a `--default-theme` flag which sets the default theme to use for documentation.][79642] Various improvements to intra-doc links: - [You can link to non-path primitives such as `slice`.][80181] - [You can link to associated items.][74489] - [You can now include generic parameters when linking to items, like `Vec<T>`.][76934] Misc ---- - [You can now pass `--include-ignored` to tests (e.g. with `cargo test -- --include-ignored`) to include testing tests marked `#[ignore]`.][80053] Compatibility Notes ------------------- - [WASI platforms no longer use the `wasm-bindgen` ABI, and instead use the wasm32 ABI.][79998] - [`rustc` no longer promotes division, modulo and indexing operations to `const` that could fail.][80579] - [The minimum version of glibc for the following platforms has been bumped to version 2.31 for the distributed artifacts.][81521] - `armv5te-unknown-linux-gnueabi` - `sparc64-unknown-linux-gnu` - `thumbv7neon-unknown-linux-gnueabihf` - `armv7-unknown-linux-gnueabi` - `x86_64-unknown-linux-gnux32` Internal Only ------------- - [Consistently avoid constructing optimized MIR when not doing codegen][80718] [79135]: rust-lang/rust#79135 [74489]: rust-lang/rust#74489 [76934]: rust-lang/rust#76934 [79570]: rust-lang/rust#79570 [80181]: rust-lang/rust#80181 [79642]: rust-lang/rust#79642 [80945]: rust-lang/rust#80945 [80279]: rust-lang/rust#80279 [80053]: rust-lang/rust#80053 [79502]: rust-lang/rust#79502 [75180]: rust-lang/rust#75180 [79135]: rust-lang/rust#79135 [81521]: rust-lang/rust#81521 [80968]: rust-lang/rust#80968 [80959]: rust-lang/rust#80959 [80718]: rust-lang/rust#80718 [80653]: rust-lang/rust#80653 [80579]: rust-lang/rust#80579 [79998]: rust-lang/rust#79998 [78044]: rust-lang/rust#78044 [81455]: rust-lang/rust#81455 [80764]: rust-lang/rust#80764 [80749]: rust-lang/rust#80749 [80662]: rust-lang/rust#80662 [77885]: rust-lang/rust#77885 [cargo/8997]: rust-lang/cargo#8997 [cargo/9112]: rust-lang/cargo#9112 [feature-resolver@2.0]: https://doc.rust-lang.org/nightly/cargo/reference/features.html#feature-resolver-version-2 [`Once::call_once_force`]: https://doc.rust-lang.org/stable/std/sync/struct.Once.html#method.call_once_force [`sync::OnceState`]: https://doc.rust-lang.org/stable/std/sync/struct.OnceState.html [`panic::panic_any`]: https://doc.rust-lang.org/stable/std/panic/fn.panic_any.html [`slice::strip_prefix`]: https://doc.rust-lang.org/stable/std/primitive.slice.html#method.strip_prefix [`slice::strip_suffix`]: https://doc.rust-lang.org/stable/std/primitive.slice.html#method.strip_prefix [`Arc::increment_strong_count`]: https://doc.rust-lang.org/nightly/std/sync/struct.Arc.html#method.increment_strong_count [`Arc::decrement_strong_count`]: https://doc.rust-lang.org/nightly/std/sync/struct.Arc.html#method.decrement_strong_count [`slice::fill_with`]: https://doc.rust-lang.org/nightly/std/primitive.slice.html#method.fill_with [`ptr::addr_of!`]: https://doc.rust-lang.org/nightly/std/ptr/macro.addr_of.html [`ptr::addr_of_mut!`]: https://doc.rust-lang.org/nightly/std/ptr/macro.addr_of_mut.html [`array::IntoIter`]: https://doc.rust-lang.org/nightly/std/array/struct.IntoIter.html [`slice::split_inclusive`]: https://doc.rust-lang.org/nightly/std/primitive.slice.html#method.split_inclusive [`slice::split_inclusive_mut`]: https://doc.rust-lang.org/nightly/std/primitive.slice.html#method.split_inclusive_mut [`str::split_inclusive`]: https://doc.rust-lang.org/nightly/std/primitive.str.html#method.split_inclusive [`task::Wake`]: https://doc.rust-lang.org/nightly/std/task/trait.Wake.html [`Seek::stream_position`]: https://doc.rust-lang.org/nightly/std/io/trait.Seek.html#method.stream_position [`Peekable::next_if`]: https://doc.rust-lang.org/nightly/std/iter/struct.Peekable.html#method.next_if [`Peekable::next_if_eq`]: https://doc.rust-lang.org/nightly/std/iter/struct.Peekable.html#method.next_if_eq
Pkgsrc changes: * Add support for the big-endian arm64 NetBSD target (aarch64_be). * On NetBSD/i386, use the i586 (pentium) bootstrap kit variant in preference to i686. * Adjust patches, re-compute line offsets, re-compute crate checksums. * Remove a patch which was either integrated upstream and/or no longer applies. * Bump bootstraps to 1.50.0. * Move conditionals until after bsd.prefs.mk so that they work... * Default to "dist" build target if cross-compiling, but allow also to override via rust.BUILD_TARGET. * Allow overriding MAKE_JOBS_SAFE via rust.MAKE_JOBS_SAFE if you want a different trade-off between occasional breakage and performance. * Adjust platform.mk according to work already done in wip/rust/ * Add a patch to optimize the install.sh script used to install binary bootstraps to not do so many forks; use case/esac and parameter expansion instead of grep, sed and cut. * Drop building documentation for the binary bootstrap kits. This will also impact the lang/rust-bin package. For full documentation, build or install lang/rust as a package. Upstream changes: Version 1.51.0 (2021-03-25) ============================ Language -------- - [You can now parameterize items such as functions, traits, and `struct`s by constant values in addition to by types and lifetimes.][79135] Also known as "const generics" E.g. you can now write the following. Note: Only values of primitive integers, `bool`, or `char` types are currently permitted. ```rust struct GenericArray<T, const LENGTH: usize> { inner: [T; LENGTH] } impl<T, const LENGTH: usize> GenericArray<T, LENGTH> { const fn last(&self) -> Option<&T> { if LENGTH == 0 { None } else { Some(&self.inner[LENGTH - 1]) } } } ``` Compiler -------- - [Added the `-Csplit-debuginfo` codegen option for macOS platforms.][79570] This option controls whether debug information is split across multiple files or packed into a single file. **Note** This option is unstable on other platforms. - [Added tier 3\* support for `aarch64_be-unknown-linux-gnu`, `aarch64-unknown-linux-gnu_ilp32`, and `aarch64_be-unknown-linux-gnu_ilp32` targets.][81455] - [Added tier 3 support for `i386-unknown-linux-gnu` and `i486-unknown-linux-gnu` targets.][80662] - [The `target-cpu=native` option will now detect individual features of CPUs.][80749] \* Refer to Rust's [platform support page][platform-support-doc] for more information on Rust's tiered platform support. Libraries --------- - [`Box::downcast` is now also implemented for any `dyn Any + Send + Sync` object.][80945] - [`str` now implements `AsMut<str>`.][80279] - [`u64` and `u128` now implement `From<char>`.][79502] - [`Error` is now implemented for `&T` where `T` implements `Error`.][75180] - [`Poll::{map_ok, map_err}` are now implemented for `Poll<Option<Result<T,E>>>`.][80968] - [`unsigned_abs` is now implemented for all signed integer types.][80959] - [`io::Empty` now implements `io::Seek`.][78044] - [`rc::Weak<T>` and `sync::Weak<T>`'s methods such as `as_ptr` are now implemented for `T: ?Sized` types.][80764] - [`Div` and `Rem` by their `NonZero` variant is now implemented for all unsigned integers.][79134] Stabilized APIs --------------- - [`Arc::decrement_strong_count`] - [`Arc::increment_strong_count`] - [`Once::call_once_force`] - [`Peekable::next_if_eq`] - [`Peekable::next_if`] - [`Seek::stream_position`] - [`array::IntoIter`] - [`panic::panic_any`] - [`ptr::addr_of!`] - [`ptr::addr_of_mut!`] - [`slice::fill_with`] - [`slice::split_inclusive_mut`] - [`slice::split_inclusive`] - [`slice::strip_prefix`] - [`slice::strip_suffix`] - [`str::split_inclusive`] - [`sync::OnceState`] - [`task::Wake`] - [`VecDeque::range`] - [`VecDeque::range_mut`] Cargo ----- - [Added the `split-debuginfo` profile option to control the -Csplit-debuginfo codegen option.][cargo/9112] - [Added the `resolver` field to `Cargo.toml` to enable the new feature resolver and CLI option behavior.][cargo/8997] Version 2 of the feature resolver will try to avoid unifying features of dependencies where that unification could be unwanted. Such as using the same dependency with a `std` feature in a build scripts and proc-macros, while using the `no-std` feature in the final binary. See the [Cargo book documentation][feature-resolver@2.0] for more information on the feature. Rustdoc ------- - [Rustdoc will now include documentation for methods available from _nested_ `Deref` traits.][80653] - [You can now provide a `--default-theme` flag which sets the default theme to use for documentation.][79642] Various improvements to intra-doc links: - [You can link to non-path primitives such as `slice`.][80181] - [You can link to associated items.][74489] - [You can now include generic parameters when linking to items, like `Vec<T>`.][76934] Misc ---- - [You can now pass `--include-ignored` to tests (e.g. with `cargo test -- --include-ignored`) to include testing tests marked `#[ignore]`.][80053] Compatibility Notes ------------------- - [WASI platforms no longer use the `wasm-bindgen` ABI, and instead use the wasm32 ABI.][79998] - [`rustc` no longer promotes division, modulo and indexing operations to `const` that could fail.][80579] - [The minimum version of glibc for the following platforms has been bumped to version 2.31 for the distributed artifacts.][81521] - `armv5te-unknown-linux-gnueabi` - `sparc64-unknown-linux-gnu` - `thumbv7neon-unknown-linux-gnueabihf` - `armv7-unknown-linux-gnueabi` - `x86_64-unknown-linux-gnux32` - [`atomic::spin_loop_hint` has been deprecated.][80966] It's recommended to use `hint::spin_loop` instead. Internal Only ------------- - [Consistently avoid constructing optimized MIR when not doing codegen][80718] [79135]: rust-lang/rust#79135 [74489]: rust-lang/rust#74489 [76934]: rust-lang/rust#76934 [79570]: rust-lang/rust#79570 [80181]: rust-lang/rust#80181 [79642]: rust-lang/rust#79642 [80945]: rust-lang/rust#80945 [80279]: rust-lang/rust#80279 [80053]: rust-lang/rust#80053 [79502]: rust-lang/rust#79502 [75180]: rust-lang/rust#75180 [79135]: rust-lang/rust#79135 [81521]: rust-lang/rust#81521 [80968]: rust-lang/rust#80968 [80959]: rust-lang/rust#80959 [80718]: rust-lang/rust#80718 [80653]: rust-lang/rust#80653 [80579]: rust-lang/rust#80579 [79998]: rust-lang/rust#79998 [78044]: rust-lang/rust#78044 [81455]: rust-lang/rust#81455 [80764]: rust-lang/rust#80764 [80749]: rust-lang/rust#80749 [80662]: rust-lang/rust#80662 [79134]: rust-lang/rust#79134 [80966]: rust-lang/rust#80966 [cargo/8997]: rust-lang/cargo#8997 [cargo/9112]: rust-lang/cargo#9112 [feature-resolver@2.0]: https://doc.rust-lang.org/nightly/cargo/reference/features.html#feature-resolver-version-2 [`Once::call_once_force`]: https://doc.rust-lang.org/stable/std/sync/struct.Once.html#method.call_once_force [`sync::OnceState`]: https://doc.rust-lang.org/stable/std/sync/struct.OnceState.html [`panic::panic_any`]: https://doc.rust-lang.org/stable/std/panic/fn.panic_any.html [`slice::strip_prefix`]: https://doc.rust-lang.org/stable/std/primitive.slice.html#method.strip_prefix [`slice::strip_suffix`]: https://doc.rust-lang.org/stable/std/primitive.slice.html#method.strip_prefix [`Arc::increment_strong_count`]: https://doc.rust-lang.org/nightly/std/sync/struct.Arc.html#method.increment_strong_count [`Arc::decrement_strong_count`]: https://doc.rust-lang.org/nightly/std/sync/struct.Arc.html#method.decrement_strong_count [`slice::fill_with`]: https://doc.rust-lang.org/nightly/std/primitive.slice.html#method.fill_with [`ptr::addr_of!`]: https://doc.rust-lang.org/nightly/std/ptr/macro.addr_of.html [`ptr::addr_of_mut!`]: https://doc.rust-lang.org/nightly/std/ptr/macro.addr_of_mut.html [`array::IntoIter`]: https://doc.rust-lang.org/nightly/std/array/struct.IntoIter.html [`slice::split_inclusive`]: https://doc.rust-lang.org/nightly/std/primitive.slice.html#method.split_inclusive [`slice::split_inclusive_mut`]: https://doc.rust-lang.org/nightly/std/primitive.slice.html#method.split_inclusive_mut [`str::split_inclusive`]: https://doc.rust-lang.org/nightly/std/primitive.str.html#method.split_inclusive [`task::Wake`]: https://doc.rust-lang.org/nightly/std/task/trait.Wake.html [`Seek::stream_position`]: https://doc.rust-lang.org/nightly/std/io/trait.Seek.html#method.stream_position [`Peekable::next_if`]: https://doc.rust-lang.org/nightly/std/iter/struct.Peekable.html#method.next_if [`Peekable::next_if_eq`]: https://doc.rust-lang.org/nightly/std/iter/struct.Peekable.html#method.next_if_eq [`VecDeque::range`]: https://doc.rust-lang.org/nightly/std/collections/struct.VecDeque.html#method.range [`VecDeque::range_mut`]: https://doc.rust-lang.org/nightly/std/collections/struct.VecDeque.html#method.range_mut
Opening this up just to see what it breaks. It's unfortunate that
&(impl Error)
doesn't actually implementError
. If this direct approach doesn't work out then I'll try something different, like anError::by_ref
method.EDIT: This is a super low-priority experiment so feel free to cancel it for more important crater runs! 🙂
Stabilization Report
Why?
We've been working for the last few years to try "fix" the
Error
trait, which is probably one of the most fundamental in the whole standard library. One of its issues is that we commonly expect you to work with abstract errors throughdyn Trait
, but references and smart pointers overdyn Trait
don't actually implement theError
trait. If you have a&dyn Error
or aBox<dyn Error>
you simply can't pass it to a method that wants aimpl Error
.What does this do?
This stabilizes the following trait impl:
This means that
&dyn Error
will now satisfy aimpl Error
bound.It doesn't do anything with
Box<dyn Error>
directly. We discussed how we could doBox<dyn Error>
in the thread here (and elsewhere in the past), but it seems like we need something like lattice-based specialization or a sprinkling of snowflake compiler magic to make that work. Having said that, with this new impl you can now get aimpl Error
from aBox<dyn Error>
by dereferencing it.What breaks?
A crater run revealed a few crates broke with something like the following:
previously we'd auto-deref that
&'short &'long dyn Error
to return aOption<&'long dyn Error>
fromsource
, but now will call directly on&'short impl Error
, so will return aOption<&'short dyn Error>
. The fix is to manually deref:In the recent Libs meeting we considered this acceptable breakage.