Skip to content

v35.5.0 — FJARR_LEAK Phase 2 D-FULL (full-strict default-on)

Choose a tag to compare

@fajarkraton fajarkraton released this 10 May 07:29
· 81 commits to main since this release

🔐 FJARR_LEAK Phase 2 D-FULL — full-strict default-on

Closes Compass §4.4 "@safe sebagai default" for affine semantics.
All non-primitive types (str, [T], struct, enum, tuple-with-move-fields,
Tensor, Quantized) are now Move by default — reuse after consume requires
explicit .clone(). The --strict-ownership CLI flag is preserved as a no-op
for compatibility (default mode is now what strict mode used to be).

Headline change

  • is_copy_type(ty) permanently delegates to is_copy_type_strict(ty).
  • --strict-ownership is no longer required for affine semantics; flag accepted but no-op.

Cascade fixes (Phase 3)

  • stdlib/parser_ast.fj (1 site): op_prec reads from opi[0] instead of consuming bound op.
  • stdlib/codegen_driver.fj (~30 sites): re-fetch from ast in let-bindings, postpone fn-arg consume to last use, broad vars.clone() / ast.clone() insertions on hot paths.
  • stdlib/analyzer.fj (6 sites): extract_ident calls now .clone() each str/[T] arg.

COW _FjArr runtime (Phase 5)

_FjArr C struct gains int rc. _fj_arr_clone is O(1) refcount-bump (not deep memcpy). _fj_arr_grow does Copy-on-Write deep copy when rc > 1. Without COW, .clone() cascades caused OOM (>26 GB) at chain bootstrap. With COW, phase17 self-compile is unchanged from v35.4.1 within noise: ~50s parallel (default cargo test) / ~101–103s serial (--test-threads=1). D-FULL adds ~0s overhead. (Corrected 2026-05-10 — initial ship-note erroneously reported a 2× slowdown by comparing parallel-baseline vs serial-post-ship; see docs/PHASE17_PERF_B0_FINDINGS.md for the apples-to-apples reproduction.)

Interpreter .clone() recognition

Universal O(1) .clone() for Value::Array/Str/Tensor/Struct/Enum/Tuple/Map/Quantized via Rc/Arc-share. Mutating ops (push etc.) already use Arc::make_mut so sharing is safe.

Test contract migration (Phase 4)

  • 7 lib tests in borrow_lite.rs + type_check/mod.rs flipped from is_ok() to assert SE024/ME001/ME003.
  • 12 integration test files updated to the new contract.
  • 19 Q6A example files updated with .clone() insertions (auto via auto_clone_fix3.py + manual for f-string/loop cases).

E2 design decision: skip (E2.C)

Methods do not consume receivers. arr.method(x) reads arr without marking it moved — internally consistent with the existing functional-style C runtime where push/pop/etc. return fresh arrays. Documented in docs/D_FULL_OPTION_B_PHASE_PLAN.md §3.

Engineering gates

Gate Result
cargo test --lib 7,633 / 7,633 PASS
cargo test --release --test selfhost_stage1_full 86 / 86 PASS @ ~13.7s
cargo test --release --test selfhost_phase17_self_compile 4 / 4 PASS — ~50s parallel / ~101s serial; unchanged from v35.4.1 within noise; Stage 2 byte-equality preserved through D-FULL
cargo clippy --lib -- -D warnings clean
cargo fmt -- --check clean

Source of truth

Predecessors in this arc

v35.1.0 (FJARR_LEAK Phase 1 arena, 88 B/array → 0) → v35.2.0 (Phase 2 D-LITE opt-in) → v35.5.0 (Phase 2 D-FULL default-on).