# Declare union fields as safe to access

**URL:** <https://internals.rust-lang.org/t/declare-union-fields-as-safe-to-access/21216>\
**Category:** Unsafe Code Guidelines\
**Created:** [July 21, 2024, 10:05pm UTC](https://internals.rust-lang.org/t/declare-union-fields-as-safe-to-access/21216 "2024-07-21T22:05:07Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![ds84182](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/ds84182/32/12379_2.png) [@ds84182](https://internals.rust-lang.org/u/ds84182)\
**Post date:** [July 21, 2024, 10:05pm UTC](https://internals.rust-lang.org/t/declare-union-fields-as-safe-to-access/21216/1 "2024-07-21T22:05:08Z")

</div>

In some (albeit small) cases it would be useful to declare an union's fields as "safe" to access.

One motivating example: Ergonomic bitfields

> **[Rust Playground](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=f5af46dec85bfcf8296348b1eeeacc22)**
>
> A browser interface to the Rust compiler to experiment with the language

---

<div class="post-metadata">

**Author:** ![CAD97](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/cad97/32/3460_2.png) [@CAD97](https://internals.rust-lang.org/u/CAD97)\
**Post date:** [July 21, 2024, 10:37pm UTC](https://internals.rust-lang.org/t/declare-union-fields-as-safe-to-access/21216/2 "2024-07-21T22:37:09Z")

</div>

Note that the example is _not_ sound as written, because `#[repr(Rust)] union` do not guarantee that all fields are placed at offset zero. If you want that, you (currently\[1\]) need to use `#[repr(C)]`.

At a minimum, doing something like this is probably blocked on project safe transmute, as union field access is only possibly sound if arbitrary transmutes between the field types are sound.

* * *

1. While the guarantee is not currently provided, there's very little benefit available from not providing it. It's possible that union layout will guarantee this in the future, but currently, **they do not**.

---

<div class="post-metadata">

**Author:** ![RalfJung](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/ralfjung/32/2415_2.png) [@RalfJung](https://internals.rust-lang.org/u/RalfJung)\
**Post date:** [July 22, 2024, 6:00am UTC](https://internals.rust-lang.org/t/declare-union-fields-as-safe-to-access/21216/3 "2024-07-22T06:00:45Z")

</div>

When you say `enum` I assume you mean `union`?

---

<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:** [July 22, 2024, 6:11am UTC](https://internals.rust-lang.org/t/declare-union-fields-as-safe-to-access/21216/4 "2024-07-22T06:11:22Z")

</div>

> [@CAD97](#):
>
> At a minimum, doing something like this is probably blocked on project safe transmute, as union field access is only possibly sound if arbitrary transmutes between the field types are sound.

It could be an [unsafe attribute](https://rust-lang.github.io/rfcs/3325-unsafe-attributes.html) now, and conditionally safe later.

---

<div class="post-metadata">

**Author:** ![ds84182](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/ds84182/32/12379_2.png) [@ds84182](https://internals.rust-lang.org/u/ds84182)\
**Post date:** [July 22, 2024, 6:48pm UTC](https://internals.rust-lang.org/t/declare-union-fields-as-safe-to-access/21216/5 "2024-07-22T18:48:22Z")

</div>

Yep, typo! Fixed.

---

<div class="post-metadata">

**Author:** ![binarycat](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/binarycat/32/12210_2.png) [@binarycat](https://internals.rust-lang.org/u/binarycat)\
**Post date:** [July 23, 2024, 10:47pm UTC](https://internals.rust-lang.org/t/declare-union-fields-as-safe-to-access/21216/6 "2024-07-23T22:47:17Z")

</div>

sidenote, i think rust itself violates the recommentations of that rfc, specifically this one:

> Note that when writing a library crate, it is in general not possible to make claims like “there is no other global function of this name”. This is a fundamental limitation of the global linking namespace, and not something Rust currently is able to overcome. Libraries that make such assumptions should ideally document somewhere publicly that they consider some namespace, i.e. every function starting with `_mycrate__`, to be reserved for their exclusive use.

rust uses `__rust_*` for certain things, like the global allocator.

---

<div class="post-metadata">

**Author:** ![steffahn](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/steffahn/32/13288_2.png) [@steffahn](https://internals.rust-lang.org/u/steffahn)\
**Post date:** [January 14, 2026, 10:47pm UTC](https://internals.rust-lang.org/t/declare-union-fields-as-safe-to-access/21216/7 "2026-01-14T22:47:44Z")

</div>

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