Implement AsMut<T> and AsRef<T> for !. - #161253
Conversation
|
As use std::convert::Infallible;
struct S;
impl AsRef<S> for Infallible {
fn as_ref(&self) -> &S {
match *self {}
}
} |
|
@QuineDot Thanks for pointing that out. That means this PR must either be rejected or get a crater run. I think the possible benefit is significant, so I won’t just close it immediately. …unrelatedly, I just noticed that rustbot hasn’t assigned a reviewer at all. r? libs-api |
|
Not sure how to run crater on this one. Do we wait until after the never type stabilization PR is merged? |
|
You could run a crater with a |
|
@kpreid FYI, libs-api isn't a thing any more, so, please r? libs in the future ditto for the T-libs-api tag |
That would be |
|
I’ll rebase this PR after the stabilization PR merges. |
|
(oops, thanks) |
This comment has been minimized.
This comment has been minimized.
|
Rebased, and the implementations are now marked |
|
Preparing for crater run |
This comment has been minimized.
This comment has been minimized.
Implement `AsMut<T>` and `AsRef<T>` for `!`.
This comment has been minimized.
This comment has been minimized.
|
r? libs |
|
@craterbot cancel See #162233 |
|
🗑️ Experiment ℹ️ Crater is a tool to run experiments across parts of the Rust ecosystem. Learn more |
|
👌 Experiment ℹ️ Crater is a tool to run experiments across parts of the Rust ecosystem. Learn more |
|
🚧 Experiment ℹ️ Crater is a tool to run experiments across parts of the Rust ecosystem. Learn more |
|
🎉 Experiment
Footnotes
|
| #[stable(feature = "never_type", since = "CURRENT_RUSTC_VERSION")] | ||
| impl<T: ?Sized> AsMut<T> for ! { | ||
| fn as_mut(&mut self) -> &mut T { | ||
| match *self {} |
There was a problem hiding this comment.
nit: the match is unnecessary
There was a problem hiding this comment.
Done. Thanks for the catch — I’m used to working with empty enums but not true !.
There was a problem hiding this comment.
Clippy had a false positive on this code, which I have filed: rust-lang/rust-clippy#17713
|
This PR was rebased onto a different main commit. Here's a range-diff highlighting what actually changed. Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers. |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This will allow e.g. `&[!]` to satisfy `&[T] where T: AsRef<str>`. It follows the recommendation from the never documentation: > When writing your own traits, `!` should have an `impl` whenever > there is an obvious `impl` which doesn’t `panic!`. -- <https://doc.rust-lang.org/1.97.1/std/primitive.never.html#-and-traits> The test tests/ui/impl-trait/generic-with-implicit-hrtb-without-dyn.rs had to be updated because it depended on this impl not existing. I’ve confirmed that the modified test still functions as a regression test by compiling it in nightly-2022-08-28 and seeing it ICE.
|
I assume we should FCP this even if there are no regressions, since it's instantly stable? And never stability passed, so, this is an extra ask. |
For the record, this is a somewhat weak recommendation. As in, you should generally have these imps if they are useful, but they are not always useful. I don't have anything against these impls, but I'm also not sure how useful they are. |
|
@WaffleLapkin I don’t have a concrete use case, but as I see it, because these impls can conflict with user-written impls (that must do the same thing), we should add them before that conflict arises, even if we can’t think of a use case yet. And I do think that these will come up eventually. The abstract use case is:
in which case providing |
|
I’ve expanded the PR description to include the abstract use case from my previous commit. |
View all comments
This will allow e.g.
&[!]to satisfy&[T] where T: AsRef<str>. It follows the recommendation from the never documentation:— https://doc.rust-lang.org/1.97.1/std/primitive.never.html#-and-traits
A class of use case for these impls is:
T: AsRef<SomeOtherType>,Ts, because it takesOption<T>or&[T]or any other input that can be empty or never-called, yet still do things with other inputs,in which case providing
T = !is slightly better than the alternative of providing an inhabited placeholder type, because it ensures that the generic code is compiled with knowledge of the fact that that there will never be anyTs, even if the specific code that cares about whether there are anyTs doesn’t get inlined into the call site that doesn’t provide anyTs.The test
tests/ui/impl-trait/generic-with-implicit-hrtb-without-dyn.rshad to be updated because it depended on this impl not existing. I’ve confirmed that the modified test still functions as a regression test by compiling it in nightly-2022-08-28 and seeing it ICE.Tracking issue for never: #35121
(This change has no ACP or tracking issue of its own; I assume it is simple enough that T-libs-api can just accept or reject this PR, and the implementation will be stable when
!is stable.)@rustbot label -T-libs +T-libs-api +F-never_type