# Idea: #\[zst\] on enums with no-data variants?

**URL:** <https://internals.rust-lang.org/t/idea-zst-on-enums-with-no-data-variants/22802>\
**Category:** language design\
**Created:** [April 23, 2025, 1:27pm UTC](https://internals.rust-lang.org/t/idea-zst-on-enums-with-no-data-variants/22802 "2025-04-23T13:27:30Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![SciMind2460](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/scimind2460/32/13125_2.png) [@SciMind2460](https://internals.rust-lang.org/u/SciMind2460)\
**Post date:** [April 23, 2025, 1:27pm UTC](https://internals.rust-lang.org/t/idea-zst-on-enums-with-no-data-variants/22802/1 "2025-04-23T13:27:30Z")

</div>

For example:

```rust
enum Variants {
    One(u8),
    #[zst]
    Zero,
}

```

and if there is a value on the `#[zst]` variant or more than 1 `#[zst]` variant then the compiler panics?

For example, if there is 1 `#[zst]` in a enum of 3,

```rust
enum Status {
   #[zst]
   InProgress,
   Ready(Fix),
   ToDo(Issued),
}

```

then that will be represented as zero-sized and untagged. The others will have tags.

---

<div class="post-metadata">

**Author:** ![jrose](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/jrose/32/9591_2.png) [@jrose](https://internals.rust-lang.org/u/jrose)\
**Post date:** [April 23, 2025, 1:42pm UTC](https://internals.rust-lang.org/t/idea-zst-on-enums-with-no-data-variants/22802/2 "2025-04-23T13:42:54Z")

</div>

Enums always take the same amount of space in memory; they do not change size based on what case is currently active (some of the bytes just get treated as padding instead). So saying “this case should be zero bytes and untagged” (a) means you can’t look at an enum value and tell if it’s in that case (since you said “untagged”), and (b) does absolutely nothing to change the overall size of an enum value.

You could have a different hypothetical language feature with “unsized enums” represented with fat pointers, where the metadata part of the pointer stored the tag. But even then it would be a tag and not a size, because otherwise you wouldn’t be able to differentiate between two cases whose payloads have the same size.

---

<div class="post-metadata">

**Author:** ![SciMind2460](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/scimind2460/32/13125_2.png) [@SciMind2460](https://internals.rust-lang.org/u/SciMind2460)\
**Post date:** [April 23, 2025, 1:46pm UTC](https://internals.rust-lang.org/t/idea-zst-on-enums-with-no-data-variants/22802/3 "2025-04-23T13:46:33Z")

</div>

I agree, differentiation would be required. Perhaps it would work only for enums with sizes below 3? As `Option<T>` can be treated simply as a `T`. Perhaps we could have that for other enums?

---

<div class="post-metadata">

**Author:** ![kpreid](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/kpreid/32/8484_2.png) [@kpreid](https://internals.rust-lang.org/u/kpreid)\
**Post date:** [April 23, 2025, 3:55pm UTC](https://internals.rust-lang.org/t/idea-zst-on-enums-with-no-data-variants/22802/4 "2025-04-23T15:55:00Z")

</div>

> [@SciMind2460](#):
>
> As `Option<T>` can be treated simply as a `T`.

This is only true for particular types, not all types `T`. In general, `Option<T>` may have to have a tag and therefore be bigger than `T`.

> Perhaps we could have that for other enums?

_As an optimization_, other enums do get exactly the same treatment as `Option`.

---

<div class="post-metadata">

**Author:** ![system](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/system/32/14092_2.png) [@system](https://internals.rust-lang.org/u/system)\
**Post date:** [October 15, 2026, 3:55pm UTC](https://internals.rust-lang.org/t/idea-zst-on-enums-with-no-data-variants/22802/5 "2026-10-15T15:55:35Z")

</div>

This topic was automatically closed 540 days after the last reply. New replies are no longer allowed.
