# \[Roc\] How Our Rust-to-Zig Rewrite is Going

**URL:** <https://ziggit.dev/t/roc-how-our-rust-to-zig-rewrite-is-going/16743>\
**Category:** Media\
**Created:** [July 16, 2026, 3:36pm UTC](https://ziggit.dev/t/roc-how-our-rust-to-zig-rewrite-is-going/16743 "2026-07-16T15:36:45Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![alanza](https://ziggit.dev/user_avatar/ziggit.dev/alanza/32/6006_2.png) [@alanza](https://ziggit.dev/u/alanza)\
**Post date:** [July 16, 2026, 3:36pm UTC](https://ziggit.dev/t/roc-how-our-rust-to-zig-rewrite-is-going/16743/1 "2026-07-16T15:36:45Z")

</div>

> **[How Our Rust-to-Zig Rewrite is Going](https://rtfeldman.com/rust-to-zig)**

Richard’s style of writing is less similar to mine than Andrew’s or Mitchell’s: he reads as a bit more generous and takes time to say things that I might just leave to a reader to notice.

Excellent move, to move up this blog post ahead of the 0.1.0 announcement, given current events 😉

Anyway, all in all a great read. Interesting insights into the way a project’s design helps it fit into one language better or worse than another. After all this talk about tracing GCs, I’m positively itching to write a language with one in Zig and see why it’s so fiendishly difficult!!

---

<div class="post-metadata">

**Author:** ![glfmn](https://ziggit.dev/user_avatar/ziggit.dev/glfmn/32/1763_2.png) [@glfmn](https://ziggit.dev/u/glfmn)\
**Post date:** [July 16, 2026, 8:57pm UTC](https://ziggit.dev/t/roc-how-our-rust-to-zig-rewrite-is-going/16743/2 "2026-07-16T20:57:28Z")

</div>

I see stuff like this and then suddenly it seems tantalizing fun:

[![](https://ziggit.dev/uploads/default/original/2X/4/464c59c19f67508d30345b361107c30c47d3bb2a.jpeg "GopherCon 2025: Advancing Go Garbage Collection with Green Tea - Michael Knyszek") ](https://www.youtube.com/watch?v=gPJkM95KpKo)

Granted, these tricks are sort of a like “rest of the fucking owl” situation, and I’m sure the rest of the owl bites, but optimizations like this are really cool.

---

<div class="post-metadata">

**Author:** ![KilianHanich](https://ziggit.dev/user_avatar/ziggit.dev/kilianhanich/32/8254_2.png) [@KilianHanich](https://ziggit.dev/u/KilianHanich)\
**Post date:** [July 16, 2026, 9:26pm UTC](https://ziggit.dev/t/roc-how-our-rust-to-zig-rewrite-is-going/16743/3 "2026-07-16T21:26:31Z")

</div>

> As discussed earlier, having full control over allocations and deallocations is what I want in our compiler’s implementation. And in tests, I also appreciate the testing allocators detecting leaks—it can even detect leaks in compiled Roc code! Unfortunately, to get that benefit requires a lot of “init this, defer deinit” code in tests that has to be correct or else the test fails on a memory leak. None of that is necessary in Rust. I care more about the compiler’s implementation being the way I want it than the tests looking nicer, but in a perfect world I could somehow have both.

For this purpose I normally just create a local arena for the test local data which I need as parameters and the like for the the actual function I want to test.

---

<div class="post-metadata">

**Author:** ![DigitalGems9000](https://ziggit.dev/user_avatar/ziggit.dev/digitalgems9000/32/8630_2.png) [@DigitalGems9000](https://ziggit.dev/u/DigitalGems9000)\
**Post date:** [July 16, 2026, 11:18pm UTC](https://ziggit.dev/t/roc-how-our-rust-to-zig-rewrite-is-going/16743/4 "2026-07-16T23:18:07Z")

</div>

![rust_to_zig_rewrite](https://ziggit.dev/uploads/default/original/2X/6/64882a92c3e59029d866242747f9bcd850c6c472.jpeg)

---

<div class="post-metadata">

**Author:** ![yosh](https://ziggit.dev/user_avatar/ziggit.dev/yosh/32/9569_2.png) [@yosh](https://ziggit.dev/u/yosh)\
**Post date:** [July 17, 2026, 11:29am UTC](https://ziggit.dev/t/roc-how-our-rust-to-zig-rewrite-is-going/16743/5 "2026-07-17T11:29:44Z")

</div>

Sounds cool - could you share an example?

---

<div class="post-metadata">

**Author:** ![KilianHanich](https://ziggit.dev/user_avatar/ziggit.dev/kilianhanich/32/8254_2.png) [@KilianHanich](https://ziggit.dev/u/KilianHanich)\
**Post date:** [July 17, 2026, 8:12pm UTC](https://ziggit.dev/t/roc-how-our-rust-to-zig-rewrite-is-going/16743/6 "2026-07-17T20:12:31Z")

</div>

I don’t really have a simple example, but I guess this one works? This test isn’t supposed to check for leaks or anything else, just that it creates the correct argv for spawning a process.

```Zig
test createCreateArgv {
    var helper_arena = std.heap.ArenaAllocator.init(std.testing.allocator);
    defer helper_arena.deinit();
    const helper_allocator = helper_arena.allocator();
    // setup
    const mounts = [_]container.Mount{
        container.Mount{
            .destination = "/test",
            .source = "/test",
            .kind = .{ .devpts = .{} },
            .options = .{ .rw = true },
            .propagation = .none,
        },
    };

    var env = std.process.EnvMap.init(helper_allocator);
    const env_key = "XDG_RUNTIME_DIR";
    const env_val = "/run/hi";
    try env.put(env_key, env_val);

    const img = b: {
        var img: Image = undefined;
        img.id = "hello";
        break :b img;
    };

    const entrypoint_argv = [_][]const u8{
        "test",
        "test",
    };

    const key = "key";

    const name = "name";

    const expected = &create_base ++ &[_][]const u8{
        name,
        "--env",
        env_key ++ "=" ++ env_val,
        "--label",
        label ++ "=" ++ key,
        "--mount=type=devpts,destination=" ++ mounts[0].destination ++ ",ro=false,exec",
        img.id,
    } ++ entrypoint_argv;

    // do
    const args = try createCreateArgv(helper_allocator, .{
        .entrypoint_argv = &entrypoint_argv,
        .env = env,
        .image = img,
        .mounts = &mounts,
        .key = key,
        .name = name,
    });

    // check
    outer: for (expected) |e| {
        for (args) |a| {
            if (std.mem.eql(u8, e, a)) {
                continue :outer;
            }
        } else {
            const stderr = std.debug.lockStderrWriter(&.{});
            defer std.debug.unlockStderrWriter();
            stderr.print("missing value: {s}\nhad: {{", .{e}) catch {};
            if (args.len > 0) {
                stderr.writeAll(args[0]) catch {};
                for (args[1..]) |a| {
                    stderr.print(", {s}", .{a}) catch {};
                }
            }
            stderr.writeAll("}\n") catch {};
            return error.TestValueNotFound;
        }
    }
}

```

The output to stderr is to make debugging easier since the test failed, but it’s kinda hard to know which value is wrong. (This codebase is still on 0.15.2.)

---

<div class="post-metadata">

**Author:** ![lalinsky](https://ziggit.dev/user_avatar/ziggit.dev/lalinsky/32/3720_2.png) [@lalinsky](https://ziggit.dev/u/lalinsky)\
**Post date:** [July 18, 2026, 12:38pm UTC](https://ziggit.dev/t/roc-how-our-rust-to-zig-rewrite-is-going/16743/7 "2026-07-18T12:38:00Z")

</div>

Was going through the Roc code and it seems that my prediction was right. Due to the `std.posix` removal, people are now resorting to this and only mainstream systems are being supported, even though this could be trivially done as POSIX/Windows split if the wrappers stayed in the library. It’s a real shame that people will have to reimplement this stuff over and over again.

> <https://github.com/roc-lang/roc/blob/6dc62d3611fadecb59122a111621da7d06c0aeab/src/shim_io.zig>

---

<div class="post-metadata">

**Author:** ![alanza](https://ziggit.dev/user_avatar/ziggit.dev/alanza/32/6006_2.png) [@alanza](https://ziggit.dev/u/alanza)\
**Post date:** [July 18, 2026, 2:16pm UTC](https://ziggit.dev/t/roc-how-our-rust-to-zig-rewrite-is-going/16743/8 "2026-07-18T14:16:53Z")

</div>

i think your prediction is still too early to be called, much as you seem to want your sour grapes validated in every thread 🙂

---

<div class="post-metadata">

**Author:** ![yosh](https://ziggit.dev/user_avatar/ziggit.dev/yosh/32/9569_2.png) [@yosh](https://ziggit.dev/u/yosh)\
**Post date:** [July 18, 2026, 3:01pm UTC](https://ziggit.dev/t/roc-how-our-rust-to-zig-rewrite-is-going/16743/9 "2026-07-18T15:01:10Z")

</div>

Thanks for sharing! It seems like having to init/deinit an allocator for each test is exactly what Richard was lamenting, so I wonder if you could do that setup/teardown only once for a whole set of tests, to cut down on boilerplate?

(I’m new to Zig - only just started ziglings - so forgive me if that’s a naïve question!)

---

<div class="post-metadata">

**Author:** ![KilianHanich](https://ziggit.dev/user_avatar/ziggit.dev/kilianhanich/32/8254_2.png) [@KilianHanich](https://ziggit.dev/u/KilianHanich)\
**Post date:** [July 18, 2026, 7:15pm UTC](https://ziggit.dev/t/roc-how-our-rust-to-zig-rewrite-is-going/16743/10 "2026-07-18T19:15:43Z")

</div>

You could (by putting it into a separate function), but from my experience you rarely have much shared setup and teardown code between tests.
