Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
8806297
Ingore zig-pkg/
lukewilliamboswell Apr 13, 2026
b9fb307
WIP: Zig 0.16 migration - build system and initial source fixes
lukewilliamboswell Apr 14, 2026
251359b
WIP: Zig 0.16 migration - resolve all compilation errors for roc binary
lukewilliamboswell Apr 14, 2026
42a7a25
WIP: Zig 0.16 migration - bulk type replacements across codebase
lukewilliamboswell Apr 14, 2026
d5f220c
WIP: Zig 0.16 migration - more type fixes and API replacements
lukewilliamboswell Apr 14, 2026
e2c1d44
WIP: Zig 0.16 migration - packed union padding and more fixes
lukewilliamboswell Apr 14, 2026
62b9dc8
WIP: Zig 0.16 migration - Layout packed union -> raw data with accessors
lukewilliamboswell Apr 14, 2026
d802756
WIP: Zig 0.16 migration - fix posix.write/read removal in host files
lukewilliamboswell Apr 14, 2026
7bf608c
WIP: Zig 0.16 migration - fix remaining posix.write/exit in hosts
lukewilliamboswell Apr 14, 2026
e7240d0
WIP: Zig 0.16 migration - fix Layout accessor usage across codebase
lukewilliamboswell Apr 14, 2026
d7ab329
WIP: Zig 0.16 migration - thread std.Io through codebase
lukewilliamboswell Apr 14, 2026
34214ff
Fix use-after-shrink in match branch free variable filtering
lukewilliamboswell Apr 14, 2026
037210d
WIP: Zig 0.16 migration - fix builtin_compiler crash and roc binary b…
lukewilliamboswell Apr 14, 2026
e3339e6
WIP: Zig 0.16 migration - fix all roc source compilation errors
lukewilliamboswell Apr 14, 2026
35acb55
WIP: Zig 0.16 migration - update bytebox dep and fix stable_array for…
lukewilliamboswell Apr 14, 2026
29f1c3a
WIP: Zig 0.16 migration - fix eval tests, TypeWriter double-free, and…
lukewilliamboswell Apr 14, 2026
8c0e69a
WIP: Zig 0.16 migration - fix glue host API changes and disable arm64…
lukewilliamboswell Apr 14, 2026
1a518eb
WIP: Zig 0.16 migration - fix tests for API changes
lukewilliamboswell Apr 15, 2026
0bc97c9
WIP: Zig 0.16 migration - fix tidy checks and remove dead code
lukewilliamboswell Apr 15, 2026
60de0eb
WIP: Zig 0.16 migration - fix eval code for API changes
lukewilliamboswell Apr 15, 2026
d67636b
WIP: Zig 0.16 migration - fix zig_lints.zig and auto-format
lukewilliamboswell Apr 15, 2026
c77199d
WIP: Zig 0.16 migration - fix check_test_wiring.zig
lukewilliamboswell Apr 15, 2026
93f03ff
WIP: Zig 0.16 migration - fix fuzz-repro.zig
lukewilliamboswell Apr 15, 2026
68e21e7
WIP: Zig 0.16 migration - fix playground and integration tests
lukewilliamboswell Apr 15, 2026
5b9ad53
WIP: Zig 0.16 migration - fix snapshot tool and playground
lukewilliamboswell Apr 15, 2026
df29a20
WIP: Zig 0.16 migration - rename Io to RocIo and thread std.Io throug…
lukewilliamboswell Apr 15, 2026
2d65325
WIP: Zig 0.16 migration - remove app_sys_io globals, thread std.Io th…
lukewilliamboswell Apr 15, 2026
9aede58
WIP: Zig 0.16 migration - embed sys_io in RocIo vtable, eliminate Io.…
lukewilliamboswell Apr 15, 2026
abd65a0
WIP: Zig 0.16 migration - fix fuzz-repro stdin reading and fuzz-canon…
lukewilliamboswell Apr 15, 2026
0dcc5ad
WIP: Zig 0.16 migration - ban std.Io in core modules, extend RocIo ab…
lukewilliamboswell Apr 15, 2026
98e46d6
WIP: Zig 0.16 migration - merge Allocators into RocCtx, rename io → ctx
lukewilliamboswell Apr 15, 2026
ee0ae23
WIP: Zig 0.16 migration - fix dead imports, thread sys_io through Bui…
lukewilliamboswell Apr 15, 2026
bc47ecc
WIP: Zig 0.16 migration - rename RocCtx→CoreCtx, CliContext→CliCtx, s…
lukewilliamboswell Apr 15, 2026
d1fcd1b
WIP: Zig 0.16 migration - round/floor/ceil builtins, env error rename…
lukewilliamboswell Apr 15, 2026
43eff3b
WIP: Zig 0.16 migration - fix snapshot tool: restore emptied snapshot…
lukewilliamboswell Apr 15, 2026
f763b38
WIP: Zig 0.16 migration - rename std.mem.indexOf* to find* (71 files)
lukewilliamboswell Apr 16, 2026
d69b1c3
WIP: Zig 0.16 migration - fix test failures and List.map dev backend …
lukewilliamboswell Apr 16, 2026
65daffa
WIP: Zig 0.16 migration - fix monotype slice use-after-free and test …
lukewilliamboswell Apr 16, 2026
442199a
WIP: Zig 0.16 migration - update roc-bootstrap to zig-0.16.0 release
lukewilliamboswell Apr 20, 2026
25dfa52
update bytebox to zig-0.16.0
lukewilliamboswell Apr 20, 2026
6538315
WIP: Zig 0.16 migration - add shim_io, fix link_libc, fix std_options…
lukewilliamboswell Apr 20, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci_cross_compile.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ jobs:

- uses: mlugg/setup-zig@8d6198c65fb0feaa111df26e6b467fea8345e46f # 2.0.5
with:
version: 0.15.2
version: 0.15.2 # TODO ZIG 16: update to 0.16.x
use-cache: false

- name: Setup MSVC (Windows)
Expand Down
29 changes: 15 additions & 14 deletions .github/workflows/ci_zig.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # ratchet:actions/checkout@v4
- uses: mlugg/setup-zig@8d6198c65fb0feaa111df26e6b467fea8345e46f # ratchet:mlugg/setup-zig@v2.0.5
with:
version: 0.15.2
version: 0.16.0
use-cache: true

- name: zig lints
Expand Down Expand Up @@ -89,35 +89,35 @@ jobs:
include:
- os: macos-15-intel
cpu_flag: -Dcpu=x86_64_v3
target_flag: ''
target_flag: ""
- os: macos-15
cpu_flag: ''
target_flag: ''
cpu_flag: ""
target_flag: ""
- os: ubuntu-22.04
cpu_flag: -Dcpu=x86_64_v3
target_flag: -Dtarget=x86_64-linux-musl
- os: ubuntu-24.04
cpu_flag: ''
cpu_flag: ""
target_flag: -Dtarget=x86_64-linux-musl
- os: ubuntu-24.04-arm
cpu_flag: ''
target_flag: '' # Native build for kcov (Zig 0.15.2 x86_64 has DWARF bug)
cpu_flag: ""
target_flag: "" # Native build for kcov (Zig 0.15.2 x86_64 has DWARF bug) # TODO ZIG 16: re-check if DWARF bug is fixed in 0.16
- os: windows-2022
cpu_flag: -Dcpu=x86_64_v3
target_flag: ''
target_flag: ""
- os: windows-2025
cpu_flag: -Dcpu=x86_64_v3
target_flag: ''
target_flag: ""
- os: windows-11-arm
cpu_flag: ''
target_flag: ''
cpu_flag: ""
target_flag: ""

steps:
- name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # ratchet:actions/checkout@v4
- uses: mlugg/setup-zig@8d6198c65fb0feaa111df26e6b467fea8345e46f # ratchet:mlugg/setup-zig@v2.0.5
with:
version: 0.15.2
version: 0.15.2 # TODO ZIG 16: update to 0.16.x
use-cache: true
# temp fix, see https://roc.zulipchat.com/#narrow/channel/395097-compiler-development/topic/CI/near/542085291
- name: delete llvm-config
Expand Down Expand Up @@ -152,7 +152,7 @@ jobs:

- name: Setup MSVC (Windows)
if: runner.os == 'Windows'
uses: ilammy/msvc-dev-cmd@0b201ec74fa43914dc39ae48a89fd1d8cb592756 # ratchet:ilammy/msvc-dev-cmd@v1.13.0
uses: ilammy/msvc-dev-cmd@0b201ec74fa43914dc39ae48a89fd1d8cb592756 # ratchet:ilammy/msvc-dev-cmd@v1.13.0
with:
arch: ${{ matrix.os == 'windows-11-arm' && 'arm64' || 'x64' }}

Expand Down Expand Up @@ -241,6 +241,7 @@ jobs:
}

# Parser code coverage - run on ARM64 Linux (native build)
# TODO ZIG 16: re-check if DWARF bug is fixed in 0.16 — may be able to enable x86_64 coverage
# Note: Zig 0.15.2 on x86_64 generates invalid DWARF .debug_line sections,
# causing libdw to fail parsing user source files. ARM64 works correctly.
- name: Install kcov dependencies
Expand Down Expand Up @@ -301,7 +302,7 @@ jobs:
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # ratchet:actions/checkout@v4
- uses: mlugg/setup-zig@8d6198c65fb0feaa111df26e6b467fea8345e46f # ratchet:mlugg/setup-zig@v2.0.5
with:
version: 0.15.2
version: 0.15.2 # TODO ZIG 16: update to 0.16.x
use-cache: true

- name: cross compile with llvm
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ target
generated-docs

zig-out
zig-pkg
.zig-cache
.direnv
.envrc
Expand Down
1 change: 1 addition & 0 deletions BUILDING_FROM_SOURCE.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ If you run into any problems getting Roc built from source, please ask for help

## Recommended way

<!-- TODO ZIG 16: update version to 0.16.x -->
[Download zig 0.15.2](https://ziglang.org/download/) and add it to your PATH.
[Search "Setting up PATH"](https://ziglang.org/learn/getting-started/) for more details.

Expand Down
146 changes: 146 additions & 0 deletions REMAINING_ISSUES.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
# Zig 0.16 Migration — Remaining Issues

## TL;DR

`zig build minici` is mostly green — `fmt`, `zig lints`, `tidy`, `check-test-wiring`,
`zig build`, Builtin.roc formatting, `snapshot`, checkfx, and the core module-test
pipeline all compile. The remaining blocker is a single **architectural regression**
introduced by the 0.16 migration:

> The shims (`libroc_interpreter_shim.a`, `libroc_dev_shim.a`) transitively link
> libc and reference compiler_rt symbols. That breaks Roc's promise that user
> programs are libc- and compiler_rt-independent.

Symptom when linking a user Roc app against `test/fx/platform` or `test/int/platform`:

```
ld.lld: error: undefined symbol: statx
>>> referenced by std/Io/Threaded.zig:3893 (Io.Threaded.fileStatLinux)
>>> main.o in libroc_shim.a

ld.lld: error: undefined symbol: __modti3
>>> referenced by std/Io/Threaded.zig:14253 (Io.Threaded.timestampToPosix)
>>> roc_builtins.o / host.o
```

The bundled platform `libc.a` is intentionally minimal and doesn't ship `statx`,
and user programs should never need compiler_rt's 128-bit math helpers.

---

## Root Cause

Commit `df29a20f08` ("WIP: Zig 0.16 migration - rename Io to RocIo and thread
std.Io through codebase") introduced into each shim main.zig:

```zig
// src/interpreter_shim/main.zig:58
// src/dev_shim/main.zig:34
var app_std_io: std.Io = std.Io.Threaded.global_single_threaded.io();
```

`app_std_io` is passed to `std.Thread.Mutex.lockUncancelable`/`unlock` and
`SharedMemoryAllocator.fromCoordination` — both of which gained a mandatory
`std.Io` parameter in 0.16.

Referencing `std.Io.Threaded.global_single_threaded.io()` instantiates the full
`std.Io.Threaded` vtable, which pulls the entire file/network/timestamp/stat
implementation into the compile graph. On Linux-musl:

- `fileStatLinux` / `dirStatFileLinux` → `std.c.statx` (because `statx_use_c`
returns `true` on musl) → `U statx`
- `timestampToPosix` → 128-bit `@mod`/`@divTrunc` → `__modti3`, `__divti3`

Before 0.16 the shim used `std.Thread.Mutex.lock()` and `SharedMemoryAllocator
.fromCoordination(allocator, page_size)` — neither took an `Io`, neither pulled
in `std.Io.Threaded`.

## Fix Direction

Need a minimal `std.Io` for the shim that only implements what mutex/futex and
mmap-style shared memory actually use. Options, roughly in increasing invasiveness:

1. **Thin wrapper Io.** Audit what methods `std.Thread.Mutex.lockUncancelable`,
`std.Thread.Mutex.unlock`, and `ipc.SharedMemoryAllocator.fromCoordination`
call on the Io vtable. Likely just `futexWait`/`futexWake` for mutex, and
a couple of mmap-adjacent calls for shm. Implement a custom `std.Io` whose
other vtable entries `@panic`/`unreachable`. This keeps `std.Io.Threaded`
out of the shim's compile graph entirely.
2. **Drop the Io parameter at our boundary.** Rework `ipc.SharedMemoryAllocator
.fromCoordination` so it doesn't take an `Io` — it can call `std.os.linux`
syscalls directly for shared memory. Similarly, replace `std.Thread.Mutex`
with a direct futex wrapper for the shim's single PlatformMutex.
3. **Two compile modes.** Move the `app_std_io` line behind a `comptime` flag
and provide a syscall-direct mutex implementation when building the shim.
Everything else (roc exe, tests) keeps using `std.Io.Threaded`.

(1) is probably the cleanest. (2) is less code but pushes into the ipc module.

Do **not**:
- Stub `statx` into `libhost.a` of each platform (I prototyped this — it works
mechanically but hides the real regression and the stub misses callers that
link against other platforms).
- Flip `createTestPlatformHostLib`'s `bundle_compiler_rt` on for musl targets
(same objection: paper-over).
- Regenerate the bundled `libc.a` files with a newer musl. The bundled libc is
a platform-provided contract; expanding it to satisfy compiler-side additions
is the wrong direction.

See also: `~/.claude/projects/-home-lbw-Documents-Github-roc/memory/feedback_roc_libc_independence.md`.

---

## What's Already Fixed on This Branch (uncommitted)

| Area | Change | File |
|---|---|---|
| std.posix removals | `std.posix.close`/`inotify_init1`/`inotify_add_watch` → `std.os.linux.*` with manual errno handling. `std.Io.Dir.openDirAbsolute`/`dir.close`/iterator `next` gained required `io` parameter (currently supplied via `std.Io.Threaded.global_single_threaded.io()` locally — TODO: thread io through the Watcher struct). | `src/watch/watch.zig` |
| Darwin `std.c._NSGetExecutablePath` | Wrapped in `switch (comptime builtin.os.tag)` with Linux (`readLinkAbsolute /proc/self/exe`) and Windows (`peb.ImagePathName`) branches. 0.16's comptime assertion on `std.c.darwin` now passes on non-Darwin hosts. | `src/cli/linker.zig` |
| Test-level libc linkage | Expanded `createModuleTests` link_libc to `true` for all module tests (was just `ipc`, `bundle`, `eval`, `repl`, `sljmp`). Any module whose source touches `std.c` or transitively imports one that does now compiles its tests. | `src/build/modules.zig` |
| Exe-level libc linkage | Added `.link_libc = true` explicitly to `builtin_compiler_exe` (via `ctx.CoreCtx`), `test_runner_exe` (direct `std.c` use), `roc_subcommands_test`, `glue_test`, `fx_platform_test`. | `build.zig` |

## Reverted (attempted workarounds — do not re-apply)

- `.link_libc = false` on shim_lib root module (doesn't override transitive
`.link_libc = true` from `bundle → zstd` import chain, and breaks other
modules that legitimately need libc on shim's compile graph).
- `@export(&statxCompat, ...)` from `test/fx/platform/host.zig` forwarding to
the `SYS_statx` syscall with manual errno.
- `lib.bundle_compiler_rt = … or is_linux_musl` in `createTestPlatformHostLib`
to drag `__modti3`/`__divti3` into each musl `libhost.a`.

---

## Other Follow-Ups Spotted (not blockers for `minici`)

- **ci_zig.yml still pins zig 0.15.2** for the matrix jobs and the
`check-once` nix/benchmark jobs are on 0.16.0. Once the shim fix lands and CI
is green on 0.16, flip the remaining `version: 0.15.2 # TODO ZIG 16` pins in
`.github/workflows/ci_zig.yml`.
- **watch.zig io threading.** The `std.Io.Threaded.global_single_threaded.io()`
call sites the sub-agent added as part of the posix-removal fix violate the
spirit of `ci/tidy.zig`'s ban (the ban is scoped to core modules, so tidy
passes today). Thread a real `std.Io` through the `Watcher` struct later.
- **DWARF bug re-check.** `ci_zig.yml` has `TODO ZIG 16: re-check if DWARF bug
is fixed in 0.16` around the ARM64-only kcov coverage job. Should retest.

---

## How to Reproduce Today

From repo root:

```bash
rm -rf .zig-cache src/cli/libroc_*.a
zig build # should succeed
zig build test-cli 2>&1 | tail # fails with statx / __modti3 symbols
```

Or the full pipeline:

```bash
zig build minici # fails at the `zig build test-cli` sub-step
```

The earlier sub-steps (`fmt`, `zig lints`, `tidy`, snapshot, module tests) all
pass.
Loading
Loading