Skip to content

Add a note about uninhabited-struct layout optimization#346

Open
scottmcm wants to merge 3 commits intorust-lang:masterfrom
scottmcm:scottmcm-patch-1
Open

Add a note about uninhabited-struct layout optimization#346
scottmcm wants to merge 3 commits intorust-lang:masterfrom
scottmcm:scottmcm-patch-1

Conversation

@scottmcm
Copy link
Member

I think this is pretty settled but don't know that we had a good link about it, so figured I'd write this up.

that never reaching the `assume_init` part, it's still unlikely that this occurs frequently.

There *is* still interest in doing optimizations like this on *sum* types, however. There's more
to potentially be gained there since one variant of a `union` or `enum` being uninhabited doesn't
Copy link
Member

Choose a reason for hiding this comment

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

I am very surprised to see union mentioned here. As far as I am concerned those are syntactic sugar for transmutes, and I would be very surprised if we could now start doing such optimizations without breaking tons of code. (I think even the train for "fields not at offset 0" may have sailed, many people forget to set repr(C).)

Copy link
Member Author

Choose a reason for hiding this comment

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

Yeah, I wrote that without thinking about it that hard, and looking again you're right, I don't see this happening on unions.

scottmcm and others added 2 commits August 15, 2025 18:01
Co-authored-by: Jacob Lifshay <programmerjake@gmail.com>

There *is* still interest in maybe doing optimizations like this on *sum* types, however. There's more
to potentially be gained there since one variant of an `enum` being uninhabited doesn't
keep the whole *value* from being uninhabited the way an uninhabited field does in a `struct`.

Choose a reason for hiding this comment

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

I think this might be a typo?

Suggested change
keep the whole *value* from being uninhabited the way an uninhabited field does in a `struct`.
keep the whole *value* from being inhabited, the way an uninhabited field does in a `struct`.

* https://github.com/rust-lang/rust/issues/17027
* https://github.com/rust-lang/unsafe-code-guidelines/issues/176

## Uninhabited `struct`s should all be ZSTs
Copy link

Choose a reason for hiding this comment

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

I think the name “ZST” does not capture the underlying idea very well. The real thing we want is a -∞ sized type, ZST is just one specific way of implementing it. Although I don’t have a better title yet.

Also, do you think it’s a good idea to also add the discussion of Inhabitted trait here? In case someone reading this come up with that idea again.

Copy link
Member

@Nadrieril Nadrieril Feb 13, 2026

Choose a reason for hiding this comment

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

The real thing we want is a -∞ sized type

That's not as clear as you'd think. Rust has unsafe, and types need a layout, so "a ZST with always-false validity invariant" actually has some important benefits. With a -∞ sized/aligned type you can't even start executing a function that has a ! variable in it because its whole stack frame would be uninhabited; yet it's easy to write such a function: just panic!().

Copy link
Member

@RalfJung RalfJung Feb 13, 2026

Choose a reason for hiding this comment

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

Size is a natural number, so a size of -∞ doesn't even make sense. (One could define notions of size where that does make sense, but that's not the discussion we are having here. The notion of size here is the notion currently used in Rust. Given the proposed resolution for this question, it's also not useful to consider these other notions of size.)

Therefore, ZST is exactly the right term here. There's no way a type can be smaller than that.

@traviscross traviscross added P-lang-drag-2 Lang team prioritization drag level 2. and removed P-lang-drag-1 Lang team prioritization drag level 1. labels Feb 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

I-lang-nominated P-lang-drag-2 Lang team prioritization drag level 2.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants