Language Design: Rust’s Almost-Rules
Published on 2024-08-05. Last updated on 2026-06-02
(Inspired by Almost Rules.)
Syntax
: is followed by a type
- except inside struct initializers, where it is followed by a value
- except function result types, which are preceded by
->
generics use <>
- except in expression contexts, which uses
::<>
invocations use ()
- except where
{}or[]is used, because “they convey important information”- except for macro invocations, where
(),{},[]are equivalent and interchangeable
- except for macro invocations, where
T {} initializes a struct
- except inside an
if, where{starts a branch (see Rust’s Struct Initializer Syntax Was a Mistake)
types are uppercase
- except “primitive” types
- except the primitive types array, slice, tuple and unit
Rust has no varargs
- except for
externfunctions - except for macros
patterns introduce bindings
- except in macro pattern matching, where the same syntax matches identifiers verbatim
Semantics
types with a total order implement Eq and Ord
- except
f64andf32, which do not
struct initializers use temporary lifetime extension
- except tuple structs
- except when using curly braces to initialize tuple structs