Reef Language Quick Syntax Reference

Ruby/Crystal Style - End-Based Blocks

Last reviewed on version: 0.9.0

This is a quick-reference cheat sheet, not the source of truth. The numbered pages under docs/language/reference/ are verified current and govern in any conflict — where this page would duplicate their depth, it links out instead.


Basic Syntax

Functions

fn name(param: Type): ReturnType
    // body
    return result
end name

Procedures (no return value)

proc name(param: Type)
    // body
end name

Lambda Expressions (Closures)

// Function lambda (returns value)
let double = fn(x: int): int => x * 2
let add = fn(a: int, b: int): int => a + b

// Procedure lambda (no return)
let printer = proc(x: int) => println_int(x)

// Block-body lambda
let complex = fn(x: int): int
    let y = x * 2
    return y + 1
end fn

// Procedure block-body
let logger = proc(msg: string)
    print("LOG: ")
    println(msg)
end proc

Function Types

// Function taking int, returning int
type Mapper = Fn[int, int]

// Function taking two ints, returning int
type Reducer = Fn[int, int, int]

// Procedure taking int (no return)
type Consumer = Fn[int]

Variable Capture

// Immutable capture (copied)
let factor = 10
let scale = fn(x: int): int => x * factor

// Mutable capture (boxed by reference)
mut counter = 0
let inc = fn(): int
    counter = counter + 1
    counter
end fn

Variables (Local Scope)

let x = 42          // Immutable local variable
mut y = "hello"     // Mutable local variable (use 'mut', not 'var')
let z: int = 100    // Explicit type annotation

Module-Level Declarations

module mymodule

// Constants - compile-time evaluated, exportable
const PI: float = 3.14159
const MAX_SIZE: int = 1024

// Module variables - immutable after init, exportable
let version: string = "1.0.0"
let timeout: int = 30

// Module mutable state - persists across calls, NOT exportable
mut counter: int = 0
mut rng_state: int = 2463534242

fn use_values(): int
    counter = counter + 1  // Can modify mut
    return MAX_SIZE        // Can read const/let
end use_values

end module

Control Flow

// If
if condition
    action()
end if

// If-Else
if condition
    action1()
else
    action2()
end if

// If-Elif-Else
if condition1
    action1()
elif condition2
    action2()
else
    action3()
end if

// Unless (negated if)
unless condition
    action()
end unless

Loops

// While
while condition
    action()
end while

// For range (use 'to' keyword)
for i in 1 to 10
    print_int(i)       // 1 to 9 (exclusive end)
end for

// For with .. range syntax
for i in 0..5
    print_int(i)       // 0 to 4
end for

// For with step
for i in 0 to 100 step 10
    print_int(i)       // 0, 10, 20, ..., 90
end for

// For-each over array
for item in arr
    print_int(item)
end for

// For-each with index
for i, item in arr
    print_int(i)       // 0, 1, 2, ...
    print_int(item)    // element value
end for

// Loop (infinite)
loop
    action()
    if done
        break
    end if
end loop

// Do-while (body runs at least once)
do while condition
    action()
end do

// Do-until (body runs at least once, stops when condition is true)
do until condition
    action()
end do

// Break and continue
break       // Exit loop
continue    // Next iteration

Match (Pattern Matching)

// Match statement
match value
    Option_Some(x) =>
        process(x)
    end
    Option_None() =>
        skip()
    end
end match

// Match expression (returns value)
let result = match x
    1 => 100 end
    2 => 200 end
    _ => 0 end
end match

// Patterns supported:
// - Wildcard: _
// - Variable: name
// - Integer: 42
// - Boolean: true, false
// - String: "hello"
// - Constructor: Option_Some(x), Color_Red()

Operators

Arithmetic

+    // Addition
-    // Subtraction
*    // Multiplication
/    // Division
%    // Modulo
**   // Power/exponentiation

Comparison

==   // Equal
!=   // Not equal
<    // Less than
>    // Greater than
<=   // Less or equal
>=   // Greater or equal

Logical

&&   // Logical AND (or: and)
||   // Logical OR  (or: or)
!    // Logical NOT (or: not)

Bitwise

&    // Bitwise AND
|    // Bitwise OR
^    // Bitwise XOR
~    // Bitwise NOT (complement)
<<   // Left shift
>>   // Right shift

Compound Assignment

+=   // Add and assign
-=   // Subtract and assign
*=   // Multiply and assign
/=   // Divide and assign
%=   // Modulo and assign

Set Operations

+    // Union (when operands are sets)
*    // Intersection
-    // Difference
in   // Membership test: if x in set

Types

See 030_TYPES.md for the full picture (struct literal validation, exhaustiveness checking, slicing, subrange bounds checking). Quick syntax:

Primitive Types

bool                    // true, false
char                    // 'a', '\n'
string                  // "hello"
int                     // 32-bit signed (default)
int8, int16, int32, int64    // Signed integers
uint8, uint16, uint32, uint64 // Unsigned integers
byte                    // Alias for uint8 (useful for FFI)
float                   // 64-bit (default)
float32, float64        // Floating point
size_t                  // C size_t
pointer                 // C void*

Integer Literal Suffixes

let a = 127i8        // int8
let b = 255u8        // uint8
let c = 1000i16      // int16
let d = 65535u16     // uint16
let e = 1000000i32   // int32
let f = 1000000u32   // uint32
let g = 123456i64    // int64
let h = 999999u64    // uint64

Struct

type Point = struct
    x: float
    y: float

    fn distance(): float
        return (self.x ** 2 + self.y ** 2) ** 0.5
    end distance
end Point

// Creating instances
let p = new Point()
p.x = 1.0
p.y = 2.0

// Struct literal syntax
let p2 = Point { x: 3.0, y: 4.0 }

Enum (Sum Type)

type Color = enum
    Red
    Green
    Blue
end Color

type Option[T] = enum
    Some(T)
    None
end Option

type Result[T, E] = enum
    Ok(T)
    Err(E)
end Result

// Using constructors (prefixed with type name)
let color: Color = Color_Red()             // No-payload variants still need ()
let value = Option_Some(42)                // Type argument inferred: Option[int]
let none = @Option[int].None()             // No value to infer T from -- type argument required

Option[T]/Result[T, E] here are ordinary user-defined generic enums for illustration. Reef's actual canonical generics live in core.option / core.result (see 035_ERROR_HANDLING.md) — import those instead of redeclaring your own Option/Result in real code.

Arrays

let nums = [1, 2, 3, 4, 5]
let names = ["Alice", "Bob"]
let first = nums[0]          // Read
nums[1] = 100                // Write

// Runtime array allocation
let arr = new [int](size)    // Allocate array of size

// Array methods (return new arrays - immutable style)
mut items = [1, 2, 3]
items = items.append(4)      // [1, 2, 3, 4]
items = items.pop()          // [1, 2, 3]
items = items.remove(1)      // [1, 3]

Sets

let s1: setof[int] = {1, 2, 3}
let s2: setof[int] = {0..9}        // Range notation
let s3: setof[int] = {0, 2, 5..10} // Mixed

if 5 in s1
    println("5 is in set")
end if

Subranges

type Digit = subrange 0 9
type Hour = 0..23              // Alternative syntax

let d: Digit = 5

Passive Objects (0.9)

Heap classes with single inheritance and virtual methods. Not Active Objects (no monitor). Full chapter: 040_OBJECTS.md.

object Widget
    x: int
    init(x: int)
        self.x = x
    end init
    shared fn kind(): string
        return "widget"
    end kind
end Widget

object Button extends Widget
    init(x: int)
        inherited init(x)
    end init
    override shared fn kind(): string
        return "button"
    end kind
end Button

proc main()
    let b = new Button(1)
    let w: Widget = b
    println(w.kind())
    typecase w
        Button x =>
            println("button")
        end
        else =>
            println("other")
        end
    end typecase
end main
  • extends / override are contextual; inherited / typecase are reserved.
  • == is reference identity. Arrays of objects are invariant.
  • impl Trait for Class — see 050_TRAITS.md.
  • reefc --owner-harness — opt-in owner-check probes.

Active Objects (Concurrency)

Basic Active Object

active object Counter
    value: int

    init()
        self.value = 0
    end init

    exclusive proc increment()
        self.value = self.value + 1
    end increment

    exclusive fn get(): int
        return self.value
    end get
end Counter

// Usage
let counter = new Counter()
counter.increment()          // Thread-safe

Active Object with Active Body

active object Worker
    running: bool

    init()
        self.running = true
    end init

    exclusive proc stop()
        self.running = false
    end stop

    run()  // Runs in own thread automatically
        while self.running
            doWork()
        end while
    end run

    finalize()  // Called when GC collects object
        cleanup()
    end finalize
end Worker

Method Modifiers

  • exclusive - Mutual exclusion (only one thread at a time)
  • shared - Concurrent reads allowed (no writes)

Both are compiler-enforced (0.7.7): a shared method assigning to self state is a Type Error ("Cannot assign to Active Object state in a 'shared' method..."), and a shared method calling an exclusive method on self is also a Type Error ("Cannot call exclusive method '...' on 'self' from a shared method... would deadlock") — see 045_ACTIVE_OBJECTS.md and spec §8.3 for the full messages.


Generics

See 055_GENERICS.md for the full picture (type inference, default parameters, monomorphization, same-named generics across modules). Quick syntax:

// Generic function definition
fn identity[T](x: T): T
    return x
end identity

// Call with [:Type] syntax (colon required!)
let n = identity[:int](42)
let s = identity[:string]("hello")

// Generic struct
type Box[T] = struct
    value: T
end Box

let b = new Box[int]()
b.value = 42

// Generic Active Object
active object Container[T]
    item: T

    exclusive proc set(value: T)
        self.item = value
    end set

    shared fn get(): T
        return self.item
    end get
end Container

let c = new Container[string]()

Generic Functions with Type Constraints

// Constrained generic function — can call trait methods on T
proc print_item[T](item: T) where T: Printable
    item.print()  // Dispatches to correct trait impl via monomorphization
end print_item

// Multiple constraints
proc show_info[T](item: T) where T: Printable + Describable
    item.print()
    println(item.describe())
end show_info

// Call with inferred type
let p = Point { x: 1, y: 2 }
print_item(p)    // Monomorphizes to print_item_Point → reef_Point_print()
show_info(p)     // Requires Point to implement both Printable and Describable

Traits

See 050_TRAITS.md for the full picture (dynamic dispatch is still not supported — see its "Current Limitations" section). Quick syntax:

// Trait definition with abstract methods
trait Printable
    proc print();     // Semicolon marks abstract method
end Printable

// Trait with multiple methods
trait Comparable
    fn compare(other: int): int;
    fn equals(other: int): bool;
end Comparable

// The implementing types
type Point = struct
    x: int
    y: int
end Point

type Value = struct
    v: int
end Value

// Implement trait for a type
impl Printable for Point
    proc print()
        println("Point")
    end print
end impl

// Implement multiple traits
impl Comparable for Value
    fn compare(other: int): int
        if self.v < other
            return -1
        elif self.v > other
            return 1
        else
            return 0
        end if
    end compare

    fn equals(other: int): bool
        self.v == other
    end equals
end impl

Trait Method Dispatch (Dot Notation)

// Call trait methods directly on concrete types
let p = Point { x: 5, y: 10 }
p.print()           // Calls impl Printable for Point → reef_Point_print()
let d = p.describe() // Calls impl Describable for Point → reef_Point_describe()

// Also works through generic functions (see Type Constraints above)
print_item(p)        // Generic dispatch via monomorphization

Trait Method Signatures

trait Example
    // Abstract method - must be implemented (ends with semicolon)
    fn required(): int;

    // Procedure (no return) - also abstract
    proc do_something();
end Example

String Interpolation

let name = "Alice"
let age = 30

// Simple variable interpolation
println("Hello ${name}!")
println("Age: ${age}")

// Multiple interpolations
println("${name} is ${age} years old")

// Escaped dollar sign
println("Price: \$100")

// Note: Only simple variables supported, not expressions
// This does NOT work: "Result: ${a + b}"

Unsafe Code

Unsafe blocks suppress array/string bounds checking and allow pointer operations.

unsafe
    // Low-level operations allowed here
    // No bounds checking on array/string access
    let ptr: pointer = calloc(100, 1)
    let buf: [byte] = ptr         // pointer -> array coercion
    buf[0] = 65                   // int -> byte coercion
    some_c_func(buf)              // array -> pointer coercion
end unsafe

Unsafe Modules

// Entire module suppresses bounds checks
unsafe module fast_math
    // All code here runs without bounds checking
end module

Unsafe-Only Type Coercions

// In unsafe blocks only -- implicit, no `as` needed:
pointer <-> [T]        // Pointer to/from array
pointer <-> string     // Pointer to/from string
int <-> uint8, int8, uint16, int16   // Integer narrowing/widening
char <-> int           // Character to/from code point

Raw Address Casts (as, unsafe-only)

A separate, narrower mechanism from the implicit table above: the explicit as cast between an integer and pointer/[T], for the bare-metal/MMIO raw-address idiom. It requires unsafe and the explicit as operator — plain assignment (let p: pointer = some_uint64) is not in the implicit-coercion set above and stays rejected even inside unsafe.

unsafe
    let addr: uint64 = some_array as pointer as uint64
    let p = addr as pointer      // integer -> pointer
    let view = addr as [int]     // integer -> [T]
end unsafe

Use uint64 for the address, not intint is 32-bit by design and truncates a 64-bit host address. Outside unsafe, both directions remain a Type Error ("integer to pointer cast requires unsafe"). See 100_UNSAFE.md and spec §13.3a for the full worked example.


Nil Literal

nil is a null-pointer constant for unsafe/FFI code — it is not how Reef represents "no value" in safe code. For absence, use option.Option[T] (see also 030_TYPES.md); nil cannot be assigned to an Option[T] or any non-pointer type.

// nil can only be used in unsafe blocks, and only with pointer types
proc main()
    unsafe
        let p: pointer = nil    // Null pointer constant
        if p == nil
            println("null pointer")
        end if
    end unsafe
end main

Defer Statement

Defer schedules cleanup code to run at function exit (LIFO order).

proc with_resource()
    let r = acquire_resource()
    defer
        release_resource(r)
    end defer

    // Use resource...
    // Cleanup runs automatically when function exits
end with_resource

// Multiple defers - last registered runs first
proc test()
    defer
        println("First registered, last to run")
    end defer
    defer
        println("Last registered, first to run")
    end defer
end test

Spawn Expression

Spawn creates a fire-and-forget concurrent task.

proc background_task()
    println("Running in background")
end background_task

proc main()
    spawn background_task()  // Runs asynchronously
    println("Main continues immediately")
end main

Limitations: spawn only accepts a plain proc/fn call (a free function) — spawning a call to an Active Object method is rejected at typecheck; call the method directly instead, since AO methods already dispatch to the object's own thread. It's still fire-and-forget: no return value, no cancellation, no error propagation. For those, use Active Objects. See 070_SPAWN.md for the full picture.


Modules

module mymodule

import other.module
import path.to.module as alias

ifarch amd64
    import arch.x86 as arch_impl
end ifarch

export
    fn publicFunc(): int
    proc publicProc()
    type PublicType
end export

fn publicFunc(): int
    return helper()
end publicFunc

fn helper(): int    // Private (not in export)
    return 42
end helper

end module

Qualified Module Access (Required)

All imported symbols must be accessed with their module prefix:

import core.str           // Access as str.function()
import io.file as f       // Access as f.function() (alias)
import time.time          // Access as time.function()
import core.result

proc main()
    // Correct - qualified access
    let len = str.length("hello")
    let now = time.time_now()

    // io/fs operations return Result[T, error.Error] -- check before using
    let outcome = f.readFile("data.txt")
    if result.is_ok(outcome)
        let content = result.unwrap_ok(outcome)
        println(content)
    end if

    // WRONG - unqualified access not allowed
    // let len = length("hello")      // Error!
    // let content = readFile("...")  // Error!
end main

Rules:

  • import foo.bar → access symbols as bar.symbol()
  • import foo.bar as x → access symbols as x.symbol()
  • Types also require qualification: let opt: option.Option[int]

Conditional Imports (ifarch)

Import modules only when compiling for a specific architecture:

ifarch amd64
    import drivers.lapic as lapic
    import drivers.hpet as timer
end ifarch

ifarch riscv64
    import drivers.plic as plic
    import drivers.timer as timer
end ifarch
  • Supported architectures: amd64, arm64, riscv64
  • Use with --target <arch> flag (e.g., reefc --target amd64 kernel.reef)
  • Without --target, all conditional imports are included
  • Non-matching imports are silently skipped (module files are not loaded or parsed)
  • The module name is the last component of the import path

Foreign Function Interface (FFI)

extern "C" fn strlen(s: string): size_t
extern "C" proc printf(format: string)

proc main()
    let len = strlen("hello")
end main

Labeling Rules

Named Constructs (use name):

fn myFunc(): int
    return 42
end myFunc  // Label matches name

type MyType = struct
    field: int
end MyType  // Label matches name

active object Server
    // body
end Server  // Label matches name

Control Flow (use keyword):

if condition
    // body
end if

while condition
    // body
end while

for i in 0 to 10
    // body
end for

loop
    // body
end loop

match value
    pattern =>
        // body
    end
end match

unsafe
    // body
end unsafe

Collections

Array Literals

let nums = [1, 2, 3, 4, 5]
let names = ["Alice", "Bob", "Carol"]
let empty = new [int](0)  // Empty array: `[]` cannot be inferred, construct it

Set Literals

let small_set: setof[int] = {1, 2, 3}
let range_set: setof[int] = {0..9}

Maps (requires stdlib)

import collections.hashmap
import core.option as option

proc main()
    let m = hashmap.create_int_hashmap()
    m.set("key", 42)

    // Lookups return Option[V] -- a missing key is None, not a sentinel
    let v = m.get("key")
    if option.is_some(v)
        print_int(option.unwrap(v))
        println("")
    end if
end main

Comments

// Single-line comment

/*
   Multi-line comment
   /* Nesting is supported */
*/

Key Differences from Other Languages

vs Ruby:

  • Statically typed
  • Compiled to native code
  • Active Objects (not threads)
  • Generics with monomorphization

vs Crystal:

  • Active Objects (unique feature)
  • Different concurrency model
  • End-based blocks similar

vs Go:

  • Active Objects (vs goroutines)
  • Generics (Reef has them)
  • End-based syntax (vs braces)
  • Inline assembly support

vs Rust:

  • Simpler (no borrow checker)
  • GC (easier memory management)
  • End-based syntax
  • Baremetal capable (with inline assembly)

Remember

  1. Indentation is style, not syntax - end closes blocks
  2. Label your ends - makes code self-documenting
  3. Use proc for no-return - not fn without return type
  4. Use self not this - inside Active Objects and methods
  5. Active Objects - the primary concurrency primitive
  6. Generic calls use [:Type] - colon required to disambiguate
  7. No nil for absence - use option.Option[T]; nil is only for unsafe pointer values

Inline Assembly

For OS kernels, embedded systems, and performance-critical code:

// Assembly procedure (no return)
asm proc hlt() for amd64
    HLT
end hlt

// Assembly function (with return)
asm fn inb(port: int): int for amd64
    MOV EDX, port
    XOR EAX, EAX
    IN AL, DX
    MOV result, EAX
end inb

// ARM64 example
asm proc wfi() for arm64
    WFI
end wfi

Baremetal Compilation

reefc kernel.reef --target amd64-baremetal --entry none --emit-c

Supported targets: amd64, arm64, riscv64, amd64-baremetal, arm64-baremetal, riscv64-baremetal


Not Yet Implemented

The following features appear in the language spec but are not yet implemented:

  • Exception handling (try/catch/raise) - Use Result[T,E] instead
  • Variadic parameters (...)
  • dyn Trait / trait objects (traits stay monomorphized)
  • Generic objects (object Stack[T])
  • async task-scheduling pattern (async is not even a reserved word) — but await itself IS implemented, as a monitor-style blocking condition inside Active Object methods, not part of an async/await scheduler; see 045_ACTIVE_OBJECTS.md

✅ Recently Implemented (v1.4-1.7):

  • Traits with full dispatch - trait, impl, where T: Trait, dot notation dispatch, generic dispatch via monomorphization. (Only the trailing where clause spells a constraint — the bracket-inline form fn max[T: Comparable](...) is still not implemented.)

  • defer for cleanup (LIFO execution at function exit)

  • spawn for fire-and-forget concurrent tasks

  • ✅ Generic type inference for constructors and function calls

  • ✅ Closures with variable capture (immutable and mutable)

  • ✅ Lambda expressions: fn(x: int): int => x * 2

  • ✅ Function types: Fn[int, int]

  • ✅ Match guards: _ when condition =>

  • ✅ Default parameters: fn greet(name: string, greeting: string = "Hello")

  • ✅ Multi-line strings: """..."""

  • ✅ Array/string slicing: arr[0..5], s[3..]

  • Inline assembly (asm fn/asm proc) for AMD64 and ARM64

  • Baremetal compilation for OS/embedded development

  • Do-while and do-until loops - do while cond ... end do, do until cond ... end do

  • Expression interpolation - "${expr}" (e.g., "${count + 1}")

  • For-each iteration - for item in collection ... end for, for i, item in collection (with index)

  • For loop step - for i in 0 to 100 step 10 ... end for

  • await - blocking condition wait inside exclusive/shared Active Object methods (see 045_ACTIVE_OBJECTS.md)

  • Unsafe modules - unsafe module ... end module (bounds checks suppressed module-wide)

  • Array methods - arr.append(item), arr.pop(), arr.remove(index) (immutable-style, return new arrays)

  • Conditional imports - ifarch amd64 ... end ifarch for architecture-specific module imports

  • Process management (v0.4.0) - process_fork(), process_spawn(), process_exec(), process_setsid(), exit_now()

  • File descriptor operations (v0.4.0) - fd_open(), fd_close(), fd_read(), fd_write(), fd_dup(), fd_dup2(), fd_pipe()

  • Signal enhancements (v0.4.0) - signal_block(), signal_unblock(), signal_wait(), self-pipe pattern

  • Unix domain sockets (v0.4.0) - unix_connect(), unix_listen(), unix_accept()

  • Event loop / poll(2) (v0.4.0) - poll_add(), poll_wait(), poll_readable()

  • GC configuration (v0.4.0) - --no-gc compiler flag

  • TOML parser enhancements (v0.4.0) - Raised limit to 1024, added toml_parse_sized()

  • Filesystem stat/metadata (v0.5.0) - fs.stat module: is_file(), is_directory(), is_symlink(), exists(), file_size(), file_mode()

  • Filesystem permissions (v0.5.0) - fs.perm module: chmod(), chown(), set_executable(), set_readonly(), is_readable()

  • Filesystem links (v0.5.0) - fs.link module: symlink(), readlink(), hardlink()

  • Filesystem operations (v0.5.0) - fs.ops module: copy_file(), copy_file_preserve(), remove_file(), remove_tree(), rename(), copy_tree()

  • TLS on system OpenSSL (0.7.0) - net.tls builds against the OS-provided OpenSSL (>= 3.0); the vendored LibreSSL tree is gone. The net.tls API itself is unchanged.

  • Result/Option stdlib-wide migration (0.7.5) - fallible stdlib operations return result.Result[T, core.error.Error] (failure with a reason) or option.Option[T] (possible absence) instead of sentinels ("", -1, nil). core.option/core.result are now the canonical generic Option[T]/Result[T, E] — the old monomorphized core.option_generic/core.result_generic family is removed. New panic(msg) noreturn builtin; strict, validating JSON/TOML parsers. See 035_ERROR_HANDLING.md.

  • Same-named generics across modules (0.7.6) - two modules can each define their own Dup[T]; each is independently specialized under a module-qualified symbol. A module that can see both definitions still can't use the bare name (ambiguity error naming the candidates). See 055_GENERICS.md.

  • Full TOML value grammar (0.7.6) - encoding.toml validates scalar values (ints, floats, bools, RFC 3339 date-times), dotted keys (a.b.c = 1), inline tables (k = { x = 1 }), and inline arrays (k = [1, 2]). Malformed values are a positioned Err, not a silently accepted raw string.

  • All-paths-return analysis (0.7.6) - a value-returning fn that can fall off the end of its body without a return on every path is now a compile error, not a runtime UB risk.

  • Licensing (0.7.7) - Apache-2.0 WITH LLVM-exception, the first licensed release; generated C carries a provenance header.

  • Newly rejected, previously-accepted-and-unsound (0.7.7) - shared methods mutating Active Object state or self-calling an exclusive method (see Method Modifiers); spawn on an Active Object method (see Spawn Expression); a required parameter after a default parameter; Active Object method-level generics.

  • set operators fixed (0.7.7) - +/*/- on setof[T] now lower to bitwise operations, not integer arithmetic.

  • Closure capture completeness (0.7.7) - now walks string interpolation and 16 sibling expression forms it previously missed.

  • defer in Active Object methods (0.7.7) - runs at the implicit end of a void exclusive/shared method body.

  • Contextual arch keywords (0.7.7) - amd64/arm64/riscv64 are ordinary identifiers except right after for in asm fn ... for <arch>.

  • Removed: --gc-signals flag (0.7.7).

  • Raw address casts restored (0.7.8) - integer ↔ pointer/[T] as casts, unsafe-only (see Raw Address Casts).

  • Baremetal restored (0.7.8) - riscv64-baremetal and the other freestanding targets compile again.

  • Main-thread await fixed (0.7.8) - genuinely blocks now instead of returning immediately on a false condition.