Skip to content

Implement AsMut<T> and AsRef<T> for !. - #161253

Open
kpreid wants to merge 1 commit into
rust-lang:mainfrom
kpreid:neverref
Open

Implement AsMut<T> and AsRef<T> for !.#161253
kpreid wants to merge 1 commit into
rust-lang:mainfrom
kpreid:neverref

Conversation

@kpreid

@kpreid kpreid commented Aug 17, 2026

Copy link
Copy Markdown
Contributor

View all comments

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

A class of use case for these impls is:

  • some code is generic over T: AsRef<SomeOtherType>,
  • and is still useful in the case where there are no Ts, because it takes Option<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 any Ts, even if the specific code that cares about whether there are any Ts doesn’t get inlined into the call site that doesn’t provide any Ts.


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.

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

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-libs Relevant to the library team, which will review and decide on the PR/issue. F-never_type `#![feature(never_type)]` T-libs-api [DEPRECATED; DO NOT USE] and removed T-libs Relevant to the library team, which will review and decide on the PR/issue. labels Aug 17, 2026
@QuineDot

Copy link
Copy Markdown

As Infallible will become !, this conflicts with implementations that can exist today.

use std::convert::Infallible;
struct S;
impl AsRef<S> for Infallible {
    fn as_ref(&self) -> &S {
        match *self {}
    }
}

@kpreid

kpreid commented Aug 20, 2026

Copy link
Copy Markdown
Contributor Author

@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

@theemathas theemathas added needs-fcp This change is insta-stable, or significant enough to need a team FCP to proceed. needs-crater This change needs a crater run to check for possible breakage in the ecosystem. labels Aug 24, 2026
@theemathas

Copy link
Copy Markdown
Contributor

Not sure how to run crater on this one. Do we wait until after the never type stabilization PR is merged?

@JonathanBrouwer

JonathanBrouwer commented Aug 24, 2026

Copy link
Copy Markdown
Member

You could run a crater with a AsRef<Infallible> and AsMut<Infallible> implementation, that should be representative.
That said, the stabilization PR looks likely to merge in the next few days so you could also just have some patience

@clarfonthey clarfonthey added T-libs Relevant to the library team, which will review and decide on the PR/issue. and removed T-libs-api [DEPRECATED; DO NOT USE] labels Aug 24, 2026
@clarfonthey

Copy link
Copy Markdown
Contributor

@kpreid FYI, libs-api isn't a thing any more, so, please r? libs in the future

ditto for the T-libs-api tag

@rustbot rustbot assigned JohnTitor and unassigned BurntSushi Aug 24, 2026
@steffahn

Copy link
Copy Markdown
Member

You could run a crater with a AsRef<Infallible> and AsMut<Infallible> implementation, that should be representative.

That would be AsRef<T> for Infallible / AsMut<T> for Infallible (clarifying just to avoid confusion).

@kpreid

kpreid commented Aug 24, 2026

Copy link
Copy Markdown
Contributor Author

I’ll rebase this PR after the stabilization PR merges.

@JonathanBrouwer

Copy link
Copy Markdown
Member

(oops, thanks)

@rustbot

This comment has been minimized.

@kpreid

kpreid commented Aug 25, 2026

Copy link
Copy Markdown
Contributor Author

Rebased, and the implementations are now marked #[stable].

@theemathas

Copy link
Copy Markdown
Contributor

Preparing for crater run
@bors try

@rust-bors

This comment has been minimized.

rust-bors Bot pushed a commit that referenced this pull request Aug 25, 2026
Implement `AsMut<T>` and `AsRef<T>` for `!`.
@rust-log-analyzer

This comment has been minimized.

@rust-bors

rust-bors Bot commented Aug 25, 2026

Copy link
Copy Markdown
Contributor

☀️ Try build successful (CI)
Build commit: 65c7d39 (65c7d39f9c2b9d5c316725cb48fa3d360c64c663)
Base parent: e776960 (e7769602aca3770e8d8ea55716becb22e839a579)

@craterbot craterbot added S-waiting-on-crater Status: Waiting on a crater run to be completed. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Aug 25, 2026
@JohnTitor

Copy link
Copy Markdown
Member

r? libs

@rustbot rustbot assigned nia-e and unassigned JohnTitor Aug 30, 2026
@theemathas theemathas mentioned this pull request Sep 3, 2026
@theemathas

Copy link
Copy Markdown
Contributor

@craterbot cancel

See #162233

@craterbot

Copy link
Copy Markdown
Collaborator

🗑️ Experiment pr-161253 deleted!

ℹ️ Crater is a tool to run experiments across parts of the Rust ecosystem. Learn more

@craterbot craterbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-crater Status: Waiting on a crater run to be completed. labels Sep 3, 2026
@theemathas

Copy link
Copy Markdown
Contributor

@craterbot

Copy link
Copy Markdown
Collaborator

👌 Experiment pr-161253 created and queued.
🤖 Automatically detected try build 65c7d39
⚠️ Try build based on commit e7ce9a3, but latest commit is e028a86. Did you forget to make a new try build?
🔍 You can check out the queue and this experiment's details.

ℹ️ Crater is a tool to run experiments across parts of the Rust ecosystem. Learn more

@craterbot craterbot added S-waiting-on-crater Status: Waiting on a crater run to be completed. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Sep 6, 2026
@craterbot

Copy link
Copy Markdown
Collaborator

🚧 Experiment pr-161253 is now running

ℹ️ Crater is a tool to run experiments across parts of the Rust ecosystem. Learn more

@craterbot

Copy link
Copy Markdown
Collaborator

🎉 Experiment pr-161253 is completed!
📊 0 regressed and 0 fixed (7794 total)
📊 831 spurious results on the retry-regressed-list.txt, consider a retry1 if this is a significant amount.
📰 Open the summary report.

⚠️ If you notice any spurious failure please add them to the denylist!
ℹ️ Crater is a tool to run experiments across parts of the Rust ecosystem. Learn more

Footnotes

  1. re-run the experiment with crates=https://crater-reports.s3.amazonaws.com/pr-161253/retry-regressed-list.txt

@craterbot craterbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-crater Status: Waiting on a crater run to be completed. labels Sep 8, 2026
Comment thread library/core/src/convert/mod.rs Outdated
#[stable(feature = "never_type", since = "CURRENT_RUSTC_VERSION")]
impl<T: ?Sized> AsMut<T> for ! {
fn as_mut(&mut self) -> &mut T {
match *self {}

@WaffleLapkin WaffleLapkin Sep 8, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: the match is unnecessary

View changes since the review

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. Thanks for the catch — I’m used to working with empty enums but not true !.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Clippy had a false positive on this code, which I have filed: rust-lang/rust-clippy#17713

@rustbot

rustbot commented Sep 9, 2026

Copy link
Copy Markdown
Collaborator

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.

@rust-log-analyzer

This comment has been minimized.

@rust-log-analyzer

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.
@clarfonthey

clarfonthey commented Sep 9, 2026

Copy link
Copy Markdown
Contributor

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.

@WaffleLapkin

Copy link
Copy Markdown
Member

When writing your own traits, ! should have an impl whenever there is an obvious impl which doesn’t panic!.

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.

@kpreid

kpreid commented Sep 9, 2026

Copy link
Copy Markdown
Contributor Author

@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:

  • some code is generic over T: AsRef<SomeOtherType>,
  • and is still useful in the case where there are no Ts, because it takes Option<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 any Ts, even if the specific code that cares about whether there are any Ts doesn’t get inlined into the call site that doesn’t provide any Ts.

@kpreid

kpreid commented Sep 9, 2026

Copy link
Copy Markdown
Contributor Author

I’ve expanded the PR description to include the abstract use case from my previous commit.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

F-never_type `#![feature(never_type)]` needs-crater This change needs a crater run to check for possible breakage in the ecosystem. needs-fcp This change is insta-stable, or significant enough to need a team FCP to proceed. S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-libs Relevant to the library team, which will review and decide on the PR/issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.