Rust enum-match code generation

Understand the generated assembly code for enum discriminated unions

EventHelix
Software Design
2 min readMay 30, 2022

--

Matching an enum and associated fields

Enums in Rust are discriminated unions that can save one of the multiple variants. The enum discriminator identifies the current interpretation of the discriminated union.

The following code shows a simple enum in Rust that represents a generalized Number that can be an Integer, a Float or Complex. Here Number is a container that can store a 64-bit integer ( i64), a 64-bit floating-point number ( f64) or a complex number (stored in a struct with two f64 fields).

The code following the enum declaration declares a function double that takes a Number parameter and return a Number that doubles the fields of whatever type of Number is found in the enum. The match statement in Rust is used to pattern match the contents and return the appropriate variant.

Memory layout of a Rust enum

Before we proceed any further, let’s look at the enum organization in memory. The size of the enum depends upon the largest variant. This example a Number::Complex requires two 64-bit floats. The total memory needed for the variant is 16 bytes. The size of the enum is 24 bytes. The extra 8 bytes are used to store a 64-bit discriminator that is used to identify the variant currently saved in the enum.

Note: A 64-bit discriminator might seem wasteful here. Due to padding rules, a smaller discriminator would not have saved any memory. Rust does switch to a smaller discriminator when reducing the size permits addition of smaller fields.

Deep dive into the generated code

The following graph shows the overall structure of the generated assembly. The top box and middle-right boxes check the discriminator and then invoke the appropriate variant handling code (the three leaf boxes).

We have annotated the assembly code to aid in the understanding of the code. The generated code looks at the discriminator and then accesses the fields corresponding to selected variants. The code then doubles the individual fields associated with the variant. The enum with doubled values is returned from the function. The function also copies the discriminator field to the enum that is being returned.

Explore more

Visit the Rust enum-match code generation post on EventHelix.com to learn more. Examine the Rust to assembly mapping presented here in the Compiler Explorer.

--

--