Skip to content

Conversation

@WaffleLapkin
Copy link
Member

@WaffleLapkin WaffleLapkin commented Dec 1, 2025

The lint was introduced as a FCW in #78324 and landed in rust 1.49.0 (5 years ago); see also #74840. I think we can promote this to a hard error ^^'

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Dec 1, 2025
@rustbot
Copy link
Collaborator

rustbot commented Dec 1, 2025

r? @nnethercote

rustbot has assigned @nnethercote.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

@WaffleLapkin WaffleLapkin added A-lints Area: Lints (warnings about flaws in source code) such as unused_mut. T-lang Relevant to the language team I-lang-nominated Nominated for discussion during a lang team meeting. I-lang-easy-decision Issue: The decision needed by the team is conjectured to be easy; this does not imply nomination S-waiting-on-t-lang Status: Awaiting decision from T-lang T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. and removed T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Dec 1, 2025
@WaffleLapkin
Copy link
Member Author

T-lang nomination

This PR promotes the uninhabited_static lint to a hard error. This lint detects statics with types which are uninhibited, e.g.:

enum Void {}
unsafe extern {
    static EXTERN: Void;
}

The lint was reported as FCW for 5 years now.

return;
}
};
if layout.is_uninhabited() {
Copy link
Member

@fmease fmease Dec 1, 2025

Choose a reason for hiding this comment

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

This obviously doesn't account for visibility meaning if upstream makes a public type with private fields uninhabited it could break downstream.

Is that already considered to be a breaking change due to other features? I see a bunch of uses of is_uninhabited in the compiler, so maybe?

Counterexamples: Exhaustiveness checking accounts for visibility at module granularity even, #[repr(transparent)] no longer permits external types with private fields (well, it's still a future-incompat deny-by-default lint, repr_transparent_non_zst_fields).

Edit: This concern probably doesn't really matter actually, it's super theoretical. It's more important that we reject the bad statics.

Copy link
Member Author

Choose a reason for hiding this comment

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

I thought about it a bit and I think for this lint specifically this is fine.

a static implies the existence of the value, so there is either

  • Some library that provides a value of such type (extern static)
  • Some (accessible) function that returns a value of such type (normal static)

In both cases making the value uncostructable would already be a breaking change.


Another way to look at this: having a static of an uninhabited type is unsound and leads to UB on basically any use of such static. We shouldn't compile such programs, period.

Copy link
Member

@fmease fmease Dec 2, 2025

Choose a reason for hiding this comment

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

We shouldn't compile such programs, period.

I do agree.

having a static of an uninhabited type is unsound and leads to UB on basically any use of such static

Re. supposed unsoundness tho, is that really the case? Merely defining such a static isn't insta-UB or is it? And since extern statics are unsafe to reference, no language invariant is broken in safe code, so it's not unsound; sure it is UB but that would be the user's fault.

Copy link
Member Author

Choose a reason for hiding this comment

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

Fair enough, it slipped from my mind that those accesses are unsafe.

Copy link
Contributor

@nnethercote nnethercote left a comment

Choose a reason for hiding this comment

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

r=me for the code changes, just waiting on lang approval.

View changes since this review

@WaffleLapkin WaffleLapkin force-pushed the say-no-to-uninhabited-statics branch from 894c449 to 0a6b3e8 Compare December 2, 2025 10:14
@rustbot
Copy link
Collaborator

rustbot commented Dec 2, 2025

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.

@traviscross traviscross added P-lang-drag-1 Lang team prioritization drag level 1. https://rust-lang.zulipchat.com/#narrow/channel/410516-t-lang and removed I-lang-easy-decision Issue: The decision needed by the team is conjectured to be easy; this does not imply nomination labels Dec 3, 2025
@traviscross
Copy link
Contributor

@bors2 try

@rust-bors

This comment has been minimized.

rust-bors bot added a commit that referenced this pull request Dec 3, 2025
…=<try>

Promote `uninhabited_static` lint to a hard error
@scottmcm
Copy link
Member

scottmcm commented Dec 3, 2025

I was debating how necessary it would be to have this be a hard error, since arguably it's "just" someone lying in their unsafe extern { ... }. But especially given that unsafe extern { safe static FOO: !; } exists now it feels particularly silly since it's clearly not safe, it make sense to treat this kinda like a "well it's a hard error to do UB that we detect".

And most importantly, in any place where this fires it seems clearly like using MaybeUninit<UninhabitedThing> as the type is the only thing that could possibly be meant anyway, so they should just write that.

(The meeting brought up that we should probably crater check this just in case, but I expect that to go through fine.)

@traviscross
Copy link
Contributor

It's worth noting here that, though this has been an FCW for a long time, it's only set to warn and is not set to report in deps. If we were to decide to not make this a hard error immediately, it'd seem that would be the natural next step. In the meeting, we talked about how perhaps if there is no observed breakage in crater that we might be OK with going to a hard error directly regardless.

@rust-bors
Copy link

rust-bors bot commented Dec 3, 2025

☀️ Try build successful (CI)
Build commit: 9b8307b (9b8307bcb9d1de8ffc7e1c81c48efffdb24ee840, parent: 568b11762723b001bfa693d0f21c5dad01d4e813)

@traviscross traviscross added the I-lang-radar Items that are on lang's radar and will need eventual work or consideration. label Dec 3, 2025
@traviscross
Copy link
Contributor

@craterbot check

@craterbot
Copy link
Collaborator

👌 Experiment pr-149518 created and queued.
🤖 Automatically detected try build 9b8307b
🔍 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 removed the S-waiting-on-t-lang Status: Awaiting decision from T-lang label Dec 3, 2025
@craterbot craterbot added the S-waiting-on-crater Status: Waiting on a crater run to be completed. label Dec 3, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-lints Area: Lints (warnings about flaws in source code) such as unused_mut. I-lang-nominated Nominated for discussion during a lang team meeting. I-lang-radar Items that are on lang's radar and will need eventual work or consideration. P-lang-drag-1 Lang team prioritization drag level 1. https://rust-lang.zulipchat.com/#narrow/channel/410516-t-lang S-waiting-on-crater Status: Waiting on a crater run to be completed. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-lang Relevant to the language team

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants