diff --git a/.claude/knowledge/abi-ownership-and-handles.md b/.claude/knowledge/abi-ownership-and-handles.md index 460617b..7ceb250 100644 --- a/.claude/knowledge/abi-ownership-and-handles.md +++ b/.claude/knowledge/abi-ownership-and-handles.md @@ -66,3 +66,38 @@ the `Arena`/segment lifetime as nested *inside* the resource's own lifetime, so Java's own bookkeeping fails fast on a use-after-close even before the call reaches Rust (belt-and-braces, not a substitute for the Rust-side check). + +## Rust 1.99 (2026-10-10): what the C-ABI changes do and do not buy here + +MEASURED on 1.99.0 / LLVM 23. lgj-abi is clippy-clean with `-D warnings`. All +four Java suites pass (`AllTests` 612, consumers 70 + 68 + 3 + 12) against a +`liblgj_abi.so` built by 1.99. lgj-abi's graph contains no lance, lancedb or +arrow, so the lance 13 move does not reach this crate. + +- **`UnsafeCell` contents may be accessed without `get` (newly guaranteed).** + This does NOT change the soundness of the writable mask lane. + - `lgj_mask_describe` hands Java the address of `MaskWords.words`. That is + a boxed heap buffer, not the inside of the lock's `UnsafeCell`. Java writes + to it through the segment, outside the lock. + - It is sound today because no Rust reference to those words is live while + Java writes. The one production writer, `RowStore.importRows`, writes a + mask whose handle has not been returned to anyone yet. Every Rust op + re-borrows through the lock. + - A concurrent Java writer would still be a data race, and the guarantee + does not make a race defined. That needs `AtomicU64` words plus a + documented protocol, which this ABI deliberately does not define. + - Possible hardening, not done: take the address under the write guard + (`as_mut_ptr`), so it carries write provenance. Not done because + `write_mask` also invalidates `resolved_carving`, so every describe would + drop the carving cache. That is a behaviour change for no reachable + defect. +- **C-variadic definitions / `VaList` (stabilized):** not applicable. The ABI + is fixed-arity and bulk-only (`docs/abi.md` §6), and `no-c-ever.md` holds. +- **`no_mangle` on generic items is now a hard error:** the 30 `#[no_mangle]` + exports are all non-generic. +- **Extern statics no longer promoted:** none are referenced. +- **`Box::into_non_null` / `Vec::from_parts`:** no site here. Handles are + registry ids, never raw boxes. + +REVISIT WHEN: the ABI grows a concurrent-writer protocol (then: atomic word +lanes), or a Java writer other than `importRows` appears. diff --git a/README.md b/README.md index 558b6ed..54bcb75 100644 --- a/README.md +++ b/README.md @@ -71,7 +71,8 @@ no `cbindgen`, no `jextract`, no JNI. See `docs/abi.md` §1 and ## Toolchains -- Rust: **1.97.1** stable, matching `ndarray`/`lance-graph`'s pin. +- Rust: stable, pinned in `native/lgj-abi/rust-toolchain.toml` (the version + lives there only, matching `ndarray`/`lance-graph`'s pin). - Production JDK: **JDK 28** (`/opt/jdks/jdk-28+16`). Panama FFM is final there and needs no flag; Valhalla (JEP 401) is preview-gated and production uses it, so `--enable-preview` is required — for the value classes, never diff --git a/native/lgj-abi/Cargo.toml b/native/lgj-abi/Cargo.toml index ea6b8a6..4eba618 100644 --- a/native/lgj-abi/Cargo.toml +++ b/native/lgj-abi/Cargo.toml @@ -2,7 +2,7 @@ name = "lgj-abi" version = "0.1.0" edition = "2021" -rust-version = "1.98.1" +rust-version = "1.99.0" license = "MIT OR Apache-2.0" publish = false description = "The lance-graph-java machine membrane: a self-describing, versioned, bulk-only psABI surface. No C, no JNI, no headers." diff --git a/native/lgj-abi/rust-toolchain.toml b/native/lgj-abi/rust-toolchain.toml index f19a0b1..ba52bec 100644 --- a/native/lgj-abi/rust-toolchain.toml +++ b/native/lgj-abi/rust-toolchain.toml @@ -2,7 +2,7 @@ # Stable only. Matches ndarray / lance-graph / the rest of the AdaWorldAPI # stack. No nightly features anywhere in this crate — in particular no # `core::simd` / portable-simd (abi.md §8). -channel = "1.98.1" +channel = "1.99.0" components = ["clippy", "rustfmt"] # Bump log (append one line per bump; the version itself is the `channel` @@ -11,6 +11,12 @@ components = ["clippy", "rustfmt"] # carried by ndarray / lance-graph / OGAR. Forced, not # optional: ndarray 0.17.2 now declares rustc 1.98, so # a 1.97.1 build of this crate fails to resolve at all. +# 1.98.1 → 1.99.0 2026-10-10: workspace-wide sweep (lance-graph #1437). +# Must merge BEFORE the ndarray / lance-graph bumps: CI +# checks the siblings out at main, and once they declare +# rust-version 1.99 a 1.98 build here no longer resolves. +# Measured: clippy -D warnings clean; AllTests 612 + +# consumers 153 green against a 1.99-built .so. # # This is THE toolchain file for this repo. A second one briefly existed at # the repository root; it was removed rather than kept in sync, because two