Skip to content

P1: fix Zig FFI to build and match the Idris2 ABI#29

Merged
hyperpolymath merged 1 commit into
mainfrom
claude/new-session-1fphit
Jun 26, 2026
Merged

P1: fix Zig FFI to build and match the Idris2 ABI#29
hyperpolymath merged 1 commit into
mainfrom
claude/new-session-1fphit

Conversation

@hyperpolymath

Copy link
Copy Markdown
Owner

Summary

The Zig FFI in src/interface/ffi/src/main.zig failed zig test src/main.zig -lc under Zig 0.14.0, and one test asserted behaviour the ABI contract does not provide. This PR fixes both, keeping the Idris2 ABI (src/interface/abi/Oblibeniser/ABI/Foreign.idr + Types.idr) as the source of truth.

Errors found

  1. Compile errorarray_list.ArrayListAligned no longer exposes popOrNull in Zig 0.14.0. oblibeniser_undo_pop called h.undo_stack.popOrNull():

    src/main.zig:447:31: error: no field or member function named 'popOrNull' in 'array_list.ArrayListAligned(u64,null)'
    
  2. Test failure — the "compute and verify inverse" test finalised the operation with a null (0) post-snapshot pointer, so post_snapshot stayed null and oblibeniser_compute_inverse correctly returned not_reversible (its contract requires both pre- and post-state snapshots). The test asserted ok:

    3/7 main.test.compute and verify inverse...expected main.Result.ok, found main.Result.not_reversible
    

Fixes

  1. Replaced popOrNull() with pop(), which in Zig 0.14.0 already returns an optional (?T); the orelse empty-stack handling is unchanged.
  2. Updated the test to record with a real pre-state snapshot and finalise with a real post-state snapshot, then assert ok for compute_inverse and additionally verify_inverse. This exercises the documented contract instead of weakening the FFI logic.

No exported C symbol names or Result enum integer values were changed.

ABI conformance

  • Every C:<name> in Foreign.idr has a matching export fn <name> (20/20 symbols, verified by diff — no missing/extra symbols).
  • Result enum values match resultToInt: Ok=0, Error=1, InvalidParam=2, OutOfMemory=3, NullPointer=4, NotReversible=5, AuditViolation=6, InverseProofFailed=7.

Verification

  • cd src/interface/ffi && zig test src/main.zig -lcall 7 tests pass, zero errors/warnings.
  • cd src/interface/abi && idris2 --build oblibeniser-abi.ipkgexit 0 (build dir removed afterwards).

Only src/interface/ffi/src/main.zig is touched.

Note: any rust-ci / Hypatia / governance red checks are pre-existing estate-infra unrelated to this Zig-only change.

🤖 Generated with Claude Code

https://claude.ai/code/session_019xMKB3T4Vo5FYC7Czx3JSH


Generated by Claude Code

The Zig FFI in src/interface/ffi/src/main.zig failed `zig test src/main.zig
-lc` under Zig 0.14.0 and one test asserted behaviour the ABI contract does
not provide.

Errors found:

1. Compile error: `array_list.ArrayListAligned` no longer exposes
   `popOrNull`. `oblibeniser_undo_pop` called `h.undo_stack.popOrNull()`,
   which does not exist in Zig 0.14.0.

2. Test failure: the "compute and verify inverse" test finalised the
   operation with a null (0) post-snapshot pointer, so `post_snapshot`
   stayed null and `oblibeniser_compute_inverse` correctly returned
   `not_reversible` (per its contract: an inverse needs both pre- and
   post-state snapshots). The test asserted `ok`, so it failed.

Fixes:

1. Replaced `popOrNull()` with `pop()`, which in Zig 0.14.0 already returns
   an optional (`?T`); the `orelse` empty-stack handling is unchanged.

2. Updated the test to record with a real pre-state snapshot and finalise
   with a real post-state snapshot, then assert `ok` for compute_inverse and
   additionally verify_inverse. This exercises the documented contract
   instead of weakening the FFI logic.

The Idris2 ABI (src/interface/abi/Oblibeniser/ABI/Foreign.idr + Types.idr)
remains the source of truth: every `C:<name>` symbol still has a matching
`export fn`, and the Result enum integer values (Ok=0 .. InverseProofFailed=7)
are unchanged and match resultToInt.

Verification:
  - `zig test src/main.zig -lc` -> all 7 tests pass, zero errors/warnings.
  - `idris2 --build oblibeniser-abi.ipkg` -> exit 0.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019xMKB3T4Vo5FYC7Czx3JSH
@hyperpolymath hyperpolymath marked this pull request as ready for review June 26, 2026 22:08
@hyperpolymath hyperpolymath merged commit f42c879 into main Jun 26, 2026
20 of 22 checks passed
@hyperpolymath hyperpolymath deleted the claude/new-session-1fphit branch June 26, 2026 22:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants