Memory Management

Aria's memory management is designed to let AI generate correct code without reasoning about ownership or lifetimes. The current implementation uses direct allocation; a garbage collector and manual annotations are planned.

Current State

In v0.1, Aria allocates via mmap (on macOS) with a bump allocator. Memory is not reclaimed during program execution. This is sufficient for compilation, CLI tools, and short-lived processes.

// Just allocate — no annotations needed
x := Thing{...}
list := [1, 2, 3, 4, 5]
map := Map{"key": "value"}

RAII with with Blocks

For resources that need deterministic cleanup, use with blocks. The resource is automatically cleaned up when the block exits:

with conn := db.connect("postgres://localhost/mydb")? {
    conn.query("SELECT * FROM users")?
    // conn is automatically closed here
}

The Drop Trait

Types that need cleanup implement Drop. Destructors run in LIFO (last-in, first-out) order per scope:

impl Drop for FileHandle {
    fn drop(mut self) {
        self.close()
    }
}

fn process() {
    a := FileHandle.open("a.txt")
    b := FileHandle.open("b.txt")
    // b.drop() runs first, then a.drop()
}

Defer

Use defer for cleanup that doesn't warrant a full Drop implementation. Up to 4 defers per function:

fn processFile(path: str) {
    file := io.open(path)?
    defer file.close()

    buffer := allocateBuffer(4096)
    defer freeBuffer(buffer)

    // ... use file and buffer
    // cleanup runs in reverse order on exit
}

Ownership & Move Semantics

By default, values are moved (not copied):

a := Thing{...}
b := a          // a is moved to b; a is no longer valid

// To copy, the type must derive Clone
a := Thing{...}
b := a.clone()  // explicit copy

Types crossing task boundaries must implement Send (moveable) and Share (safely shared). These are auto-derived for primitive types.

Planned Features

The following memory management features are specified but not yet implemented:

  • Garbage collector — tracing GC as the default memory strategy
  • @stack — stack allocation for short-lived data
  • @arena — arena allocation for batches freed together
  • @inline — embed data directly in structs (no heap indirection)
  • Pool[T] — object pooling for expensive-to-create resources
  • Use-after-move analysis — compile-time detection of moved values

Design Philosophy

Aria deliberately avoids a borrow checker. The AI generating code should not need to reason about lifetimes, borrows, or complex ownership graphs. The planned GC handles safety for the default path, with manual annotations as opt-in escape hatches for performance-critical code.

Next Steps