v0.1.6 · preview · linux

Owned values, explicit types, no GC. A language that reads clean and runs like C.

Zmeu is a typed systems language with an owned-value memory model and a low-ceremony, indentation-based surface. It lowers through an MLIR pipeline to the same LLVM IR shape as equivalent C — ownership, borrows, and effects checked up front, so invalid programs never reach the backend.

$ git clone https://github.com/yxanul/zmeu
Read the docs
Apache 2.0 · open source Rust front end · MLIR → LLVM 362 examples
Zmeu, the dragon mascot
One program · two languages

Less to write. Nothing given up.

A sum type and an exhaustive match. Zmeu proves every case is handled and drops the ceremony; C makes you hand-roll a tag and write a default you can forget.

zmeuexhaustive · checked
enum Shape:
    case Circle(radius: f64)
    case Rect(side: f64)

def area(shape: Shape) -> f64:
    return match shape:
        case Circle(r) => 3.14159 * r * r
        case Rect(s)   => s * s
Cmanual tag · unchecked
typedef enum { CIRCLE, RECT } Tag;

typedef struct { Tag tag; double v; } Shape;

double area(Shape s) {
    switch (s.tag) {
        case CIRCLE: return 3.14159 * s.v * s.v;
        case RECT:   return s.v * s.v;
    }
    return 0.0; /* unreachable, still required */
}
Measured, not asserted

C-class performance,
with the receipts.

≈ C within ±3% of C on ~⅔ of 52 microbenchmarks, faster on 8, and at or ahead of stock rustc on the large majority.

zmeu, C and Rust built -O3 -march=native on LLVM 22; hyperfine, 40 runs, identical output verified. Reproduce with benchmarks/run.sh.

Methodology & fixtures →
benchmark fasterC = 1.00×slower × C
option_unwrapsum-type unwrap 0.75×
bitwise_castsinteger bit ops + casts 0.83×
recursionrecursive calls, hot loop 0.89×
generic_identitymonomorphised generic 0.99×
result_trytry-propagation 1.00×
struct_fieldsvalue-struct access 1.01×
nested_array_sumclang autovectorises; ties Rust 1.22×
Lower is faster than C. One honest loss kept in: where clang auto-vectorises, zmeu lands with Rust.
The claim, enforced

The same machine code as C — and CI won't let it drift.

Result, Optional, generics and try lower to the same LLVM IR shape as equivalent C — no hidden boxing, no dispatch, no allocation. Every pull request re-counts the emitted IR against a declared threshold per case. An optimisation regression blocks the merge, so “zero-cost” is a test, not a hope.

--emit-mir--emit-mlir--emit-llvm
benchmarks/ir_thresholds.tsv
case              panic oob alloca
result_try            0     0    0
generic_identity      0     0    0
option_unwrap         0     0    0
merge-blocking on regression
The memory model

Owned by default. Borrowed on purpose.

Single ownership, deterministic drop

Every value has one owner. Destructors run on scope exit — no GC, no reference counting, no runtime tax.

view and mut view borrows

Share without copying. Aliasing and lifetimes are checked before any code is generated; there is no unsafe escape hatch over the type system.

Proven at CFG MIR, before lowering

The front end's borrow and effect checker rejects invalid programs. Soundness never rides on an LLVM pass.

borrow.zmeushared view · no copy
def sum(xs: view [i32]) -> i32:
    var total = 0
    for x in xs:
        # yes, total += x is on the way — longhand for now :)
        total = total + x
    return total

def main() -> i32:
    let nums: [i32; 4] = [3, 8, 11, 20]
    return sum(view nums)