Skip to content

fix(ir): preserve receive resumption in after bodies - #41

Merged
mremond merged 1 commit into
mainfrom
fm/task-a802d986
Nov 14, 2026
Merged

mremond merged 1 commit into
mainfrom
fm/task-a802d986

Conversation

@mremond

@mremond mremond commented Nov 14, 2026

Copy link
Copy Markdown
Member

Why

A receive nested directly in an after body must wait independently and preserve earlier values, as on BEAM.

What changed

  • Nested receives accept messages delivered while waiting.
  • Inner timeouts run for their own duration.
  • Earlier values survive message and timeout wakeups.

Before and after

Before: The reported probe corrupted an earlier atom and completed a requested 500 ms inner timeout in 10 ms.

After: The probe receives the delayed message and completes the 500 ms inner timeout in 510 ms, matching BEAM behavior.

This changes compiled program behavior, not a graphical view; native and BEAM output provide the evidence.

Checked

Live validation: Demonstrated for this version. 3 of 3 scenarios driven live in the product.

Scenario Result Evidence
Delayed message inside an after body ✅ Passed live The native probe receives x and preserves aft, producing {aft,{late,x}} exactly as BEAM.
Independent inner timeout and earlier values ✅ Passed live The native probe waits 510 ms for a 500 ms inner timeout; the regression preserves an earlier tuple, list and binary.
Tail, deeper and successive nested receives (supplementary) ✅ Passed live All five regression scenarios completed ten consecutive times per native scheduler mode and on BEAM with identical output.
  • Delayed-message probe: Native prints {aft,{late,x}}, matching BEAM instead of {#unknown<0x0>,nolate}.
  • Sender-free inner timeout: Native waited 510 ms for a 500 ms timeout; baseline waited 10 ms and BEAM waited 513 ms.
  • Native and BEAM regression: Five scenarios passed ten consecutive times each with native default schedulers, one native scheduler and BEAM OTP 29; complete output matched.
  • Current-version local gate: Strict clippy, 2,168 Rust tests, 490 native tests, allocator and stacktrace checks passed; two external-module tests skipped.
  • Native timer probe: All 24 configurations passed with 30 runs each; the largest median lateness was 1.56 ms.
  • Independent review: No findings; the reviewed patch remained identical after the default-branch update.
How it was checked

Built the runtime before the compiler with cargo build --release --locked -p nera-runtime and cargo build --release --locked -p nera.

cargo clippy --workspace --all-targets --locked -- -D warnings

cargo test --workspace --locked --no-fail-fast: 2,168 passed, zero failed, one ignored.

./target/release/nera test -j 1 --timeout 30: 490 passed, zero failed, two external-module skips.

python3 scripts/test-allocator-config.py and python3 scripts/test-stacktrace-order.py passed.

python3 scripts/test-native-timer.py passed all default/single-scheduler and normal/utility/background configurations. Background-priority tail lateness reached 113.78 ms; this probe does not establish maximum latency.

The unchanged tests/receive_nested_after.erl passed ten sequential executions per mode with exact output, normal exit and no stderr, including its completion marker.

The complete gate was rerun after bringing in the default branch's test-storage update. Receive lowering and runtime behavior were unchanged by that update.

Local execution covered macOS arm64 and BEAM OTP 29, not native Linux or Windows.

Risk

Risk: low in every dimension.

Full risk assessment
Dimension Level Why
Blast radius low Changes receive lowering order in one compiler area.
Behavior low Corrects nested receive suspension to match BEAM.
Undo low Reverting the commit restores the previous behavior; no data migration.
Evidence low Native and BEAM probes, repeated regression and full local gate passed.
Sensitivity low No sign-ins, keys, settings or persistent user data are changed.
Novelty low Uses the existing wait-before-body ordering already used for receive clauses.
Dependencies low No dependencies changed.

Pipeline

Updates from git push no-mistakes

Infinitary checked this version: an independent review that also judged the documents, and live validation the review accepted.

@github-actions github-actions Bot added this to the 0.1.1 milestone Nov 14, 2026
@mremond
mremond merged commit db23128 into main Nov 14, 2026
22 checks passed
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.

1 participant