shape_value/v2/heap_element.rs
1//! v2-raw HeapHeader-equipped element carrier trait.
2//!
3//! ## Purpose
4//!
5//! `HeapElement` is the compile-time trait that constrains the element type `T`
6//! of a `TypedArray<*const T>` instantiation to a HeapHeader-equipped v2-raw
7//! carrier. Implementors (`StringObj`, `DecimalObj`, ...) own the per-T drop
8//! semantics: `release_elem` decrements the refcount and fully deallocates
9//! when the count reaches zero.
10//!
11//! ## Authority
12//!
13//! Per ADR-006 §2.7.24 Q25.A SUPERSEDED + R20 S2-prime audit deliverable (b)
14//! §4.1.B decision: option (a) — `HeapElement` trait dispatch.
15//!
16//! The trait is the compile-time-monomorphized per-T release dispatcher for
17//! `TypedArray<*const T>::drop_array_heap`. Bodies dispatch via the Rust type
18//! system; no runtime `NativeKind` parameter, no `is_heap()` probe, no
19//! Bool-default fallback.
20//!
21//! ## Discipline
22//!
23//! - One method (`release_elem`), one `*const Self` parameter.
24//! - Implementor types must have `HeapHeader` at offset 0 (so
25//! `v2_release(&(*ptr).header)` is sound). The `#[repr(C)]` + first-field-
26//! header invariant per `StringObj` precedent enforces this structurally.
27//! - The trait is `unsafe` because callers must guarantee `ptr` validity
28//! (live allocation, no concurrent free).
29//!
30//! ## Forbidden
31//!
32//! Per ADR-006 §2.7.24 Q25.A SUPERSEDED + audit §4.1.B.3:
33//!
34//! - `HeapElement::release_elem` taking a `NativeKind` parameter — refused;
35//! the trait dispatches via the Rust type system, not via a runtime kind
36//! probe. This is the §2.7.7 #4/#7 forbidden pattern (`tag_bits`-style
37//! runtime dispatch on the kind discriminator) at the per-element layer.
38//! - Bool-default fallback in `release_elem` body — surface-and-stop with
39//! `NotImplemented(SURFACE: ...)` at the construction-site when an inner
40//! payload's drop semantics are unproven. Per §2.7.7 #9.
41//! - Implementing `HeapElement` for non-HeapHeader-equipped types
42//! (e.g. `Arc<>`-wrapped storage). The trait is structurally constrained
43//! to types with `HeapHeader` at offset 0; implementing it for an
44//! `Arc<>`-wrapped struct would fail the `(*ptr).header` field access
45//! at compile time.
46//! - Renaming `HeapElement` to defection-attractor framing (heap-bridge,
47//! elem-helper, release-translator, etc.) — per CLAUDE.md broader-family
48//! regex. The trait describes a structural property (this T lives on
49//! the v2-raw heap), not a dispatch role.
50
51/// v2-raw HeapHeader-equipped element carrier trait.
52///
53/// Implementors are `#[repr(C)]` structs with `HeapHeader` at offset 0. The
54/// trait dispatches per-T release at compile time via the Rust type system;
55/// `TypedArray<*const T: HeapElement>::drop_array_heap` calls
56/// `T::release_elem(elem_ptr)` for each stored element.
57///
58/// # Safety
59///
60/// Implementors must guarantee:
61/// 1. `Self` is `#[repr(C)]` with a `HeapHeader` field at offset 0.
62/// 2. `release_elem(ptr)` is sound when `ptr` points to a live `Self`
63/// allocation (one that the implementor's allocator produced and that
64/// has not yet been freed).
65/// 3. `release_elem(ptr)` decrements the refcount via `v2_release` and, if
66/// `v2_release` returns true, fully deallocates the allocation
67/// (including any nested payload buffers per the implementor's drop
68/// semantics).
69pub unsafe trait HeapElement {
70 /// Decrement the reference count of `*ptr`. If the refcount reaches
71 /// zero, fully deallocate the object (including any nested payload
72 /// buffers per the implementor's drop semantics).
73 ///
74 /// # Safety
75 /// `ptr` must point to a valid, live `Self` allocated via the
76 /// implementor's canonical v2-raw allocator. After this call returns,
77 /// `ptr` must not be dereferenced (the allocation may have been freed).
78 unsafe fn release_elem(ptr: *const Self);
79}