Enum
Overview
Enumerations define a set of named integer constants. Backed by int64 at the ABI level.
Plain enums (no payload variants) map to a single i64 discriminant.
Tagged enums (one or more payload variants) map to { i64, [N × i8] } — a discriminant
plus a payload slot.
Since v0.2.39. Tagged enums and derive(Display/Eq) added in v0.36.x.
Declaration
enum:Color = { RED, GREEN, BLUE }; // auto-numbered: 0, 1, 2
enum:HttpStatus = { OK = 200, NOT_FOUND = 404, ERROR = 500 }; // explicit values
enum:Mixed = { A, B = 10, C }; // C = 11 (continues from last)
Tagged Variants (Payload Enums)
Variants may carry a payload of any type (including another enum):
enum:Status = { OK, FAIL };
enum:Event = {
None, // plain variant (no payload)
WithStatus(Status) // tagged variant: payload is Status enum
};
Event:e = Event.WithStatus(Status.OK);
Destructuring with pick:
pick (e) {
(Event.WithStatus(s)) { // binds s : Status
pick (s) {
(Status.OK) { drop println("ok"); },
(Status.FAIL) { drop println("fail"); },
(*) {},
}
},
(Event.None) {},
(*) {},
}
The payload type can be a primitive, a struct, or another enum.
derive(Display)
#[derive(Display)] synthesises a Display impl whose output is:
- Plain variant: the variant name (e.g. "RED")
- Tagged variant: "VariantName(payload)" (e.g. "Hello(42)")
#[derive(Display)]
enum:Msg = { Hello(int32) };
Msg:m = Msg.Hello(42i32);
string:s = `&{m}`; // "Hello(42)"
derive(Eq)
#[derive(Eq)] synthesises an Eq impl that compares discriminants.
For tagged enums the payload is not compared — only the variant tag.
Use raw e.eq(other) to suppress the implicit Result<bool> wrapping:
#[derive(Eq)]
enum:Season = { Spring, Summer, Autumn, Winter };
Season:a = Season.Summer;
Season:b = Season.Summer;
Season:c = Season.Winter;
bool:same = raw a.eq(b); // true
bool:diff = raw a.eq(c); // false
Usage
Color:my_color = Color.RED;
int64:val = Color.GREEN; // enums convert to int64
pick (my_color) {
(Color.RED) { drop println("Red"); },
(Color.GREEN) { drop println("Green"); },
(Color.BLUE) { drop println("Blue"); },
(*) {}
}
Enum comparison:
Color:a = Color.RED;
Color:b = Color.BLUE;
if (a != b) {
drop println("Different colors");
}
Rules
- Variant names must be unique within the enum
- Values must be valid
int64 - Convention: variant names in UPPER_CASE
- Declared at top level (not inside functions)
- Supports
==and!=comparison (discriminant only for tagged enums) - Enum-typed variables enforce same-enum assignment
- Integrates with
pickstatement exhaustiveness checking - Tagged variant payload types are resolved as enum → struct → primitive (lookup order matters)
Related
- struct.md — composite types
- control_flow/pick.md — switch/case with exhaustiveness