Control Flow
Conditions and loops
let label = if value > 0 { 1 } elif value < 0 { -1 } else { 0 }
let mut index: usize = 0
while index < len(values) {
index = index + 1
}
for item in values {
consume_copy(item)
}
if is an expression. while and for support break and continue.
for over ranges, arrays, and slices lowers to a direct allocation-free
index/length loop. Move-only elements require explicit indexing and ownership
handling.
Match and ADTs
type response {
ok(i64)
error(str)
}
fn status(value: response) -> i64 {
match value {
ok(code) => code
error(message) => -1
}
}
Match arms have no commas and must be exhaustive unless remaining flow is unreachable. Patterns support literals, tuples, structs, variants, bindings, discard, and guards. Move-only payloads transfer only when an arm is selected; a failed pattern or guard preserves the owner for later arms.
Options, results, and ?
fn find(enabled: bool) -> ?i64 {
if enabled { some(42) } else { none }
}
fn forward(enabled: bool) -> ?i64 {
let value = find(enabled)?
some(value)
}
? yields the present/success payload or returns the corresponding failure.
Result propagation may change success type but preserves error type. No
implicit allocation or clone occurs. ? cannot cross a spawn boundary.
Cleanup on flow edges
Fallthrough, ret, break, and continue execute the verified cleanup plan
for live owners. Panic/trap/abort edges never unwind and run no cleanup.