Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
da0cc95
Ingore zig-pkg/
lukewilliamboswell Apr 13, 2026
771a428
WIP: Zig 0.16 migration - build system and initial source fixes
lukewilliamboswell Apr 14, 2026
5c1f987
WIP: Zig 0.16 migration - resolve all compilation errors for roc binary
lukewilliamboswell Apr 14, 2026
1a41df2
WIP: Zig 0.16 migration - bulk type replacements across codebase
lukewilliamboswell Apr 14, 2026
998261f
WIP: Zig 0.16 migration - more type fixes and API replacements
lukewilliamboswell Apr 14, 2026
1907078
WIP: Zig 0.16 migration - packed union padding and more fixes
lukewilliamboswell Apr 14, 2026
fe83418
WIP: Zig 0.16 migration - Layout packed union -> raw data with accessors
lukewilliamboswell Apr 14, 2026
1f6a06e
WIP: Zig 0.16 migration - fix posix.write/read removal in host files
lukewilliamboswell Apr 14, 2026
da71b25
WIP: Zig 0.16 migration - fix remaining posix.write/exit in hosts
lukewilliamboswell Apr 14, 2026
bbc94c3
WIP: Zig 0.16 migration - fix Layout accessor usage across codebase
lukewilliamboswell Apr 14, 2026
3ee7be3
WIP: Zig 0.16 migration - thread std.Io through codebase
lukewilliamboswell Apr 14, 2026
d976530
Fix use-after-shrink in match branch free variable filtering
lukewilliamboswell Apr 14, 2026
7e49e03
WIP: Zig 0.16 migration - fix builtin_compiler crash and roc binary b…
lukewilliamboswell Apr 14, 2026
c0a6ca4
WIP: Zig 0.16 migration - fix all roc source compilation errors
lukewilliamboswell Apr 14, 2026
9ea8296
WIP: Zig 0.16 migration - update bytebox dep and fix stable_array for…
lukewilliamboswell Apr 14, 2026
e1b36da
WIP: Zig 0.16 migration - fix eval tests, TypeWriter double-free, and…
lukewilliamboswell Apr 14, 2026
dc6e1cd
WIP: Zig 0.16 migration - fix glue host API changes and disable arm64…
lukewilliamboswell Apr 14, 2026
5660fff
WIP: Zig 0.16 migration - fix tests for API changes
lukewilliamboswell Apr 15, 2026
03efc99
WIP: Zig 0.16 migration - fix tidy checks and remove dead code
lukewilliamboswell Apr 15, 2026
98b2650
WIP: Zig 0.16 migration - fix eval code for API changes
lukewilliamboswell Apr 15, 2026
1f78fcd
WIP: Zig 0.16 migration - fix zig_lints.zig and auto-format
lukewilliamboswell Apr 15, 2026
ecd265b
WIP: Zig 0.16 migration - fix check_test_wiring.zig
lukewilliamboswell Apr 15, 2026
17260dd
WIP: Zig 0.16 migration - fix fuzz-repro.zig
lukewilliamboswell Apr 15, 2026
4b22776
WIP: Zig 0.16 migration - fix playground and integration tests
lukewilliamboswell Apr 15, 2026
c5d5b97
WIP: Zig 0.16 migration - fix snapshot tool and playground
lukewilliamboswell Apr 15, 2026
b140be8
WIP: Zig 0.16 migration - rename Io to RocIo and thread std.Io throug…
lukewilliamboswell Apr 15, 2026
76d7c83
WIP: Zig 0.16 migration - remove app_sys_io globals, thread std.Io th…
lukewilliamboswell Apr 15, 2026
580c076
WIP: Zig 0.16 migration - embed sys_io in RocIo vtable, eliminate Io.…
lukewilliamboswell Apr 15, 2026
7c8468a
WIP: Zig 0.16 migration - fix fuzz-repro stdin reading and fuzz-canon…
lukewilliamboswell Apr 15, 2026
b51b466
WIP: Zig 0.16 migration - ban std.Io in core modules, extend RocIo ab…
lukewilliamboswell Apr 15, 2026
2bdb9ab
WIP: Zig 0.16 migration - merge Allocators into RocCtx, rename io → ctx
lukewilliamboswell Apr 15, 2026
2435bff
WIP: Zig 0.16 migration - fix dead imports, thread sys_io through Bui…
lukewilliamboswell Apr 15, 2026
4e0cd30
WIP: Zig 0.16 migration - rename RocCtx→CoreCtx, CliContext→CliCtx, s…
lukewilliamboswell Apr 15, 2026
699e6cb
WIP: Zig 0.16 migration - round/floor/ceil builtins, env error rename…
lukewilliamboswell Apr 15, 2026
c54795d
WIP: Zig 0.16 migration - fix snapshot tool: restore emptied snapshot…
lukewilliamboswell Apr 15, 2026
36d9b16
WIP: Zig 0.16 migration - rename std.mem.indexOf* to find* (71 files)
lukewilliamboswell Apr 16, 2026
385a880
WIP: Zig 0.16 migration - fix test failures and List.map dev backend …
lukewilliamboswell Apr 16, 2026
bce5388
WIP: Zig 0.16 migration - fix monotype slice use-after-free and test …
lukewilliamboswell Apr 16, 2026
864e9da
WIP: Zig 0.16 migration - update roc-bootstrap to zig-0.16.0 release
lukewilliamboswell Apr 20, 2026
18cf677
update bytebox to zig-0.16.0
lukewilliamboswell Apr 20, 2026
493f7ea
WIP: Zig 0.16 migration - add shim_io, fix link_libc, fix std_options…
lukewilliamboswell Apr 20, 2026
84dcc7d
WIP: Zig 0.16 migration - fix minici tidy violation and stack overflo…
lukewilliamboswell Apr 23, 2026
31230d2
WIP: Zig 0.16 migration - fix channel sendTimeout/recvTimeout hanging…
lukewilliamboswell Apr 23, 2026
3d5414d
WIP: Zig 0.16 migration - fix two compile test failures
lukewilliamboswell Apr 23, 2026
93c6483
WIP: Zig 0.16 migration - fix ModuleEnv.Serialized roundtrip crash
lukewilliamboswell Apr 23, 2026
bea6201
WIP: Zig 0.16 migration - fix REPL exit code 1 on EOF stdin
lukewilliamboswell Apr 23, 2026
898c791
Add BUG_REPORT.md for remaining test-cli failures on zig-16
lukewilliamboswell Apr 23, 2026
4ea7d74
WIP: Zig 0.16 migration - fix echo-platform SIGSEGV on dev backend
lukewilliamboswell Apr 23, 2026
6f3bbe3
WIP: Zig 0.16 migration - fix roc test caching and build test assertions
lukewilliamboswell Apr 23, 2026
5ddebd3
fix int platform host to write test output to stdout via std.Io
lukewilliamboswell Apr 23, 2026
b619ed4
Remove BUG_REPORT.md - all three bugs resolved
lukewilliamboswell Apr 23, 2026
cfb82d6
WIP: Zig 0.16 migration - fix post-rebase minici failures
lukewilliamboswell Apr 24, 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