Skip to content

Document repr(uN) enum representation more concretely than just size and alignment #1947

@kpreid

Description

@kpreid

The reference currently says about the layout of repr(uN) enums:

Primitive Representation of Field-less Enums

For field-less enums, primitive representations set the size and alignment to be the same as the primitive type of the same name. For example, a field-less enum with a u8 representation can only have discriminants between 0 and 255 inclusive.

This specifies that the enum is no larger than the chosen primitive integer, but it doesn't actually specify what the contents of the bytes within that size are. We can then consult the page for enums to find that:

If the enumeration specifies a primitive representation, then the discriminant may be reliably accessed via unsafe pointer casting:

This combined with Rust's overall approach to types then leaves no room for there to be any other option (such as, say, the discriminant gratuitously being stored bit-inverted) — if reading in this way is OK, then it must be the case that writing in this way is also OK. However, this is an unnecessarily roundabout way to reach this conclusion, and in general, the Reference seems to sort of assume but not state that the discriminant at the surface-syntax level equals the integer stored in the representation. I think that the Reference should directly state the following facts:

  • For a repr([ui]N) enum without fields:
    • The bytes of that enum store the discriminant
      • as an integer of the chosen type,
      • with the same numerical value as the discriminant value that is specified in the enum declaration and that is readable via casting the enum to integer.
    • A valid value of this enum type may be written by writing the discriminant value.
  • For a repr([ui]N) enum with fields:
    • A valid value of this enum type may be written by writing the discriminant as for a fieldless version, and writing a valid value of each field of that variant at the appropriate offsets.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions