Skip to content
La3 Docs
Browse docs

Ownership and Memory

References, raw pointers, moves, borrows, and deterministic drops.

References

Shared and mutable references mirror Rust's aliasing rules and make mutation visible.

A value can have many readers or one writer, not both. That rule is the backbone of the safe memory model.

fn sum(xs: &[i32]) -> i32 {
    xs.reduce(0, |a, x| a + x)
}

fn double_in_place(x: &mut i32) {
    *x *= 2
}

Raw pointers

Raw pointers exist for low-level work and intentionally drop lifetime guarantees.

  • &raw takes a bare address, not a safe reference.
  • Pointer arithmetic is scaled by element size.
  • unsafe marks the region where the compiler stops proving the invariants.
let arr: [i32; 5] = [10, 20, 30, 40, 50]
let p: *i32 = &raw arr[0]

unsafe {
    let third = *(p + 2)
}

Moves and borrows

Ownership is checked statically so the compiler can insert drops and reject use-after-move bugs early.

  • Move semantics apply to non-Copy values.
  • Borrow checking prevents dangling references and conflicting access.
  • The MIR pass is where the precision grows, because control-flow-aware lifetime information is needed for the hard cases.

Drops

Owned values are dropped deterministically when they leave scope, in reverse declaration order.

  • Heap-owning values get explicit drop glue.
  • Moved-out values are not dropped twice.
  • The MIR lowering inserts the actual drop points after proving the analysis safe.