# Forbidden/niche values

**URL:** <https://internals.rust-lang.org/t/forbidden-niche-values/14237>\
**Category:** language design\
**Created:** [March 11, 2021, 2:37am UTC](https://internals.rust-lang.org/t/forbidden-niche-values/14237 "2021-03-11T02:37:49Z")\
**Posts on this page:** 5\
**Page:** 2

<div class="post-metadata">

**Author:** ![pickfire](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/pickfire/32/3830_2.png) [@pickfire](https://internals.rust-lang.org/u/pickfire)\
**Post date:** [March 17, 2021, 3:25pm UTC](https://internals.rust-lang.org/t/forbidden-niche-values/14237/21 "2021-03-17T15:25:40Z")

</div>

Don't we have two kinds of niche values? Most of the solution only appears to be able to solve one kind of it.

- niche value that operates on bit level, for example `10000000` where 1 is the niche value no matter what values the `0` have, this is sometimes used as a hack for pointers since the last bit is usable IIRC, see [GitHub - maciejhirsz/beef: Faster, more compact implementation of std: :Cow](https://github.com/maciejhirsz/beef) for an example
- niche value that operates on value level / context, for example number `0` of `u8` (only `00000000` is valid), most of the proposed solution belongs to this category I believe, an example is `Option` and `NonZero*`

While at it we may also need to take care of large niche value space, like having every a niche value for every prime numbers, ideally these would all be compile-time only to avoid foot guns like reflection magic.

---

<div class="post-metadata">

**Author:** ![kornel](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/kornel/32/2711_2.png) [@kornel](https://internals.rust-lang.org/u/kornel)\
**Post date:** [March 18, 2021, 6:56pm UTC](https://internals.rust-lang.org/t/forbidden-niche-values/14237/22 "2021-03-18T18:56:51Z")

</div>

Maybe instead of trying to explain to the compiler where's the niche, there could be a run-time hook for packing/unpacking values from a custom `enum` representation?

I have no idea how it could look like syntax-wise, but the general idea is that you could implement some trait with "set enum to this value" and "get me current value of this enum" methods, and these could perform arbitrary work (maybe `const`) to pack the data however they want.

---

<div class="post-metadata">

**Author:** ![atagunov](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/atagunov/32/5877_2.png) [@atagunov](https://internals.rust-lang.org/u/atagunov)\
**Post date:** [March 19, 2021, 12:19pm UTC](https://internals.rust-lang.org/t/forbidden-niche-values/14237/23 "2021-03-19T12:19:40Z")

</div>

> [@kornel](#):
>
> ou could implement some trait with "set enum to this value" and "get me current value of this enum" methods

Hi, it surely wouldn't be just the enum right? What types is this approach intended to pack together? Niches seem all about making `A * B` type take less than `sizeof(A) + sizeof(B)` bytes, so what are `A` and `B`?

---

<div class="post-metadata">

**Author:** ![kornel](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/kornel/32/2711_2.png) [@kornel](https://internals.rust-lang.org/u/kornel)\
**Post date:** [March 19, 2021, 12:25pm UTC](https://internals.rust-lang.org/t/forbidden-niche-values/14237/24 "2021-03-19T12:25:09Z")

</div>

What I had in mind is a type like `union U {A, B}` plus a function that knows whether it's currently holding A or B, so you can have `fn get_discriminant(&U) -> Discriminant<U>` or maybe `fn get_a(&U) -> Option<&A>`.

---

<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:** [June 17, 2021, 12:25pm UTC](https://internals.rust-lang.org/t/forbidden-niche-values/14237/25 "2021-06-17T12:25:25Z")

</div>

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

[Previous page](https://internals.rust-lang.org/t/forbidden-niche-values/14237.md?page=1)
