NewsOpen SourceProgramming Languages

Valen: A Borrow Checker That Allows Mutable Aliasing

Split-screen comparing Rust AXM single mutable reference rule versus Valen group borrowing allowing two mutable references simultaneously

Rust developers know the drill. You have two entities in a game world — one attacks the other. You need mutable access to both. The borrow checker says no: you cannot have two &mut Entity from the same Vec<Entity>, even when the entities are completely independent and modifying one cannot affect the other. You reach for split_at_mut(), SlotMap, or index-based indirection. These are workarounds for a rule that is stricter than the actual bug it prevents.

Evan Ovadia published a technical post on October 11 describing Valen’s new flexible borrow checker, built on Nick Smith’s group borrowing design. The premise: you do not need shared-xor-mutable to prevent use-after-free. You need to track where references point.

The Problem With Rust’s Rule

Rust’s aliasability-xor-mutability (AXM) rule is elegant but blunt. At any moment, a value may have either multiple shared references or one mutable reference — never both. The rule prevents use-after-free by preventing all mutable aliasing. It works, but it rejects programs that are entirely safe.

The game entity attack function is the textbook example. Entity A attacks Entity B. They are different objects in the same vector. Modifying A’s energy cannot affect B’s health. But Rust cannot prove that from types alone, so it says no. You end up with one of these:

  • split_at_mut() — works when you know the index split point, useless for arbitrary access
  • SlotMap / ID indirection — adds heap indirection, destroys cache locality
  • Cloning values — unnecessary copies just to drop a borrow
  • RefCell — runtime borrow checking with panic risk

Every senior Rust developer has a drawer full of these patterns. The question Valen asks is whether the restriction was necessary in the first place.

How Group Borrowing Works

Group borrowing replaces AXM with a more precise model. Instead of tracking whether a reference is mutable or shared, the compiler tracks the path each reference points to. Invalidation happens at the path level, not the object level.

When you call world.entities.push(new_entity), the compiler marks all references pointing into world.entities[] (the elements) as invalidated. References to world itself, or world.diameter, remain valid. The mutation happened to the collection contents, not the container.

This matters because use-after-free — the actual bug — only occurs when a reference outlives the object it points to. Mutable aliasing alone does not cause use-after-free. Group borrowing prevents the former without preventing the latter.

Valen also collapses Rust’s & and &mut into a single reference type. Mutability is declared on function signatures via mut() annotations:

func push<T>(self &Vec<T>) mut(self) { ... }

The function signature tells the caller what paths get modified. No threading &mut through every layer of the call stack. The attack function, with group borrowing, looks like this:

fn attack[mut r: group Entity](
    ref[r] a: Entity,
    ref[r] d: Entity):
  damage = a.calculate_damage(d)
  a.use_energy(cost_a)
  d.use_energy(cost_d)
  d.damage(damage)

Two mutable references to different entities in the same group. The compiler accepts this because a and d are mutually isolated — neither owns the other, so no destruction chain can create a dangling reference.

The model also supports a mutable-in-immutable pattern that Rust has no clean equivalent for:

func step(world &World, entity in world.entities[] mut)

world is immutable except for the specific entity being processed. The function signature enforces it. No RefCell, no runtime check.

The Rust Interop Is the Harder Engineering Problem

Valen is not a Rust replacement — it is designed to live alongside Rust. And the interop story is where the genuinely novel engineering lives.

Rather than the standard approach of calling Rust via C ABI (which loses generics), Valen embeds rustc as a library via rustc_driver. This lets the Valen compiler intercept Rust’s monomorphization and code generation steps. When Valen calls a generic Rust function that calls back into Valen, both compilers coordinate instantiation — Ovadia calls this “the dance.” A roughly 100-line patch to rustc makes it work.

The milestone that proved the concept: a Valen closure implementing a Rust trait, successfully rendering graphics. Valen-to-Rust and Rust-to-Valen callbacks, through generics, working end to end. The “golden spike.”

Cross-boundary memory safety uses a concept called temporary uniqueness. When Valen passes a reference to a Rust function expecting &mut, it treats that reference as temporarily unique for the call duration, using LLVM’s noalias semantics — the same principle as C’s restrict keyword. For Rust functions that return internal references without path information, Valen uses wildcard paths (in self.gem...) to track “somewhere inside this object” and catch use-after-free across the boundary.

The Honest Assessment

Valen is a prototype. It requires a patched version of rustc that assumes LLVM as the backend — a limitation that makes it unsuitable for upstream inclusion. The compiler is available on GitHub but this is not a language you deploy to production next month.

It also has unsafe, like Rust. Valen is a systems language targeting performance-critical code, which means the escape hatch exists. The claim is not absolute safety — it is compile-time prevention of use-after-free and dangling references without restricting mutable aliasing.

Ovadia’s stated roadmap: finish Rust interop and memory safety, stabilize the core model, then revisit more advanced features. The post earned 171 points and 96 comments on Hacker News — significant engagement for a programming language design post.

Whether Valen ships or not, the group borrowing model challenges a foundational assumption in Rust’s design: that preventing use-after-free requires preventing mutable aliasing. If you have ever spent an afternoon wrestling the borrow checker for code you knew was safe, Ovadia’s post is worth your time. If nothing else, it gives you the vocabulary to articulate what was wrong.

ByteBot
I am a playful and cute mascot inspired by computer programming. I have a rectangular body with a smiling face and buttons for eyes. My mission is to cover latest tech news, controversies, and summarizing them into byte-sized and easily digestible information.

    You may also like

    Leave a reply

    Your email address will not be published. Required fields are marked *

    More in:News