Status: Accepted
Date: October 13, 2026
Answers: whether a value of an enum that has exactly one variant has to
name the variant, at the value and in a pattern
Related:
ADR-345 D2, D3 (process::Exit, the arm that names it);
ADR-291 D10 (the shapes of a pattern);
Part I 3.4, 4.4, 7.1; Part III 17.1, C.3
When an enum has one variant, is Type::Variant(x) the only way to write
it? Part I 3.4 says a path with :: names a variant and a bare name binds;
a variant is never written on its own. With one variant the variant’s name
says nothing the type’s name did not: process::Exit::Code(c) names Code
only because the rule wants a variant.
At the value and in a pattern, whatever the variant holds:
| the variant | long form | short form |
|---|---|---|
| positional | Exit::Code(c) |
Exit(c) |
| named fields | Pos::At { x, y } |
Pos { x, y } |
| nothing | Unit::Only |
Unit (at the value) |
The short form is the long form: the same value, the same pattern, the same lowering. The long form stays valid.
Why. With one variant nothing is ambiguous, and the variant’s name is
noise at every use. Rust’s tuple struct and newtype, and Haskell’s newtype,
write such a value by the type’s name.
Exit(c) is a call when Exit names a function, a value when
it names a one-variant enum. A name means one thing in a package: a
function and a type of one name are already refused (NK1148), so the
name decides and nothing is left to choose.Pos { x, y } builds a struct when Pos is a
struct; a type name is a struct or an enum, never both, so the braces are
read by what the name declares.else,
which matches the only value there is. A short form with parentheses or
braces, or with :: before the type (process::Exit(c)), is never a
binding, so it is the variant.NK1252.The message names the variants and offers the long form
(Shape::Circle(r)). This is what a short form becomes when its enum gains a
second variant: adding a variant is already a breaking change (Part I 7.1),
and the refusal says at each site which variant was meant.
process::exit(code) throws process::Exit(code).ADR-345 D3 is unchanged in meaning; its example is written short.
Exit as a struct with { code }. Fixes one type; every other
one-variant enum keeps the noise, and catch arms would read
process::Exit { code }.