Conversation
There was a problem hiding this comment.
Pull request overview
This PR extends multitude (and aligns related plurality behavior) to support compiler-checked trait-object coercion for Box/Rc/Arc using a hybrid metadata strategy (thin handles for sized/str/slice, vtable carried in erased handles), while also tightening unwind-safety contracts, correcting Serde ignored-value dispatch, and standardizing benchmark naming/setup/teardown and related docs.
Changes:
- Add trait-object coercion API (
Coercion+coerce!) and update smart-pointer internals to support handle-resident vtable metadata. - Define/verify unwind-safety contracts for arenas/pools and escaped handles, including new behavioral tests.
- Fix
deserialize_ignored_anyto dispatch throughdeserialize_any, and audit/update documentation and benchmark organization to match new behavior.
Reviewed changes
Copilot reviewed 79 out of 79 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| crates/plurality/tests/unwind_safe.rs | Adds unwind-safety contract tests for plurality pool/owners. |
| crates/plurality/src/sync.rs | Adds explicit unwind-safety trait impls for plurality::Arc. |
| crates/plurality/src/rc.rs | Adds explicit unwind-safety trait impls for plurality::Rc. |
| crates/plurality/src/pool.rs | Adds explicit unwind-safety trait impls for plurality::Pool. |
| crates/plurality/src/boxed.rs | Adds explicit unwind-safety trait impls for plurality::Box. |
| crates/plurality/src/alloced.rs | Adds explicit unwind-safety trait impls for plurality::Alloc. |
| crates/multitude/tests/variance_and_zst.rs | Extends variance assertions to cover Rc. |
| crates/multitude/tests/utf16.rs | Updates test docs to match revised refcount/metadata wording. |
| crates/multitude/tests/unwind_safe.rs | Adds unwind-safety contract tests for multitude arena/owners. |
| crates/multitude/tests/unsize.rs | Adds trait-object coercion + hybrid handle layout tests (feature dst). |
| crates/multitude/tests/send_sync.rs | Updates Send/Sync rationale wording for Rc. |
| crates/multitude/tests/loom.rs | Adds loom coverage for mixed sized/erased Arc drop races (feature dst). |
| crates/multitude/tests/audit_repro.rs | Updates doc text to match allocation-local shared strong count model. |
| crates/multitude/tests/arena.rs | Updates doc text to match allocation-local shared strong count model. |
| crates/multitude/tests/arena_string.rs | Updates string handle-size rationale to match prefix-based length storage. |
| crates/multitude/src/zerocopy.rs | Clarifies alignment panic wording. |
| crates/multitude/src/vec/mutate.rs | Improves doc precision for capacity reclamation and reserve_exact. |
| crates/multitude/src/vec/mod.rs | Updates struct docs and refill-hint comments for shared freeze prefix. |
| crates/multitude/src/vec/freeze.rs | Extends freeze docs to include Rc and clarifies metadata usage. |
| crates/multitude/src/thin_smart_ptr_common.rs | Updates shared impl macro for handle-resident metadata + new trait bounds. |
| crates/multitude/src/strings/utf16_string.rs | Updates drain docs and parameterizes common-string docs with units. |
| crates/multitude/src/strings/string.rs | Updates drain docs and parameterizes common-string docs with units. |
| crates/multitude/src/strings/string_common.rs | Refactors shared string docs to use $units and trims repetitive examples. |
| crates/multitude/src/rc.rs | Refactors Rc to support handle metadata + adds unsize/unsize_pin. |
| crates/multitude/src/lib.rs | Updates crate-level docs for hybrid pointer widths, Rc freezes, and DST APIs. |
| crates/multitude/src/internal/constants.rs | Clarifies freeze-prefix behavior and alignment-related semantics. |
| crates/multitude/src/internal/chunk.rs | Updates chunk docs for per-family chunk refs and ordering explanations. |
| crates/multitude/src/internal/chunk_provider.rs | Clarifies cache-floor publication comment. |
| crates/multitude/src/internal/chunk_mutator.rs | Updates docs for shared strong counts and shared freeze prefix. |
| crates/multitude/src/internal/arena_buf.rs | Updates freeze-prefix docs and invariants for shared-owner prefix. |
| crates/multitude/src/dst/mod.rs | Updates DST module docs to reflect hybrid metadata storage. |
| crates/multitude/src/de/value/tests.rs | Adds regression test proving deserialize_ignored_any dispatch correctness. |
| crates/multitude/src/de/value.rs | Fixes deserialize_ignored_any to delegate to deserialize_any. |
| crates/multitude/src/de/reuse.rs | Updates docs for all-or-nothing String reuse semantics. |
| crates/multitude/src/de/mod.rs | Updates module docs and bounds to use SmartPointerPointee. |
| crates/multitude/src/de/json.rs | Clarifies trailing-input check timing and arena reset/reuse wording. |
| crates/multitude/src/de/json_error.rs | Clarifies Display behavior for limit violations vs parse/shape errors. |
| crates/multitude/src/cow.rs | Updates bounds from ptr_meta::Pointee to SmartPointerPointee. |
| crates/multitude/src/coerce.rs | Introduces Coercion + coerce! macro for compiler-checked unsizing. |
| crates/multitude/src/bytemuck.rs | Clarifies alignment panic wording. |
| crates/multitude/src/box.rs | Refactors Box to support handle metadata + adds unsize. |
| crates/multitude/src/arena/reserve.rs | Updates reserve docs for shared freeze prefix and Rc freezes. |
| crates/multitude/src/arena/mod.rs | Adds explicit unwind-safety trait impls for Arena. |
| crates/multitude/src/arena/alloc_value.rs | Updates docs/comments around strong counts and chunk pinning. |
| crates/multitude/src/arena/alloc_utf16.rs | Updates UTF-16 allocation docs for Rc and shared strong counts. |
| crates/multitude/src/arena/alloc_unsized.rs | Refactors DST allocation docs and metadata sizing logic for hybrid model. |
| crates/multitude/src/arena/alloc_uninit.rs | Updates alignment limits wording for slice APIs (64 KiB for ref slices). |
| crates/multitude/src/arena/alloc_str.rs | Updates str allocation docs for Rc + shared strong counts. |
| crates/multitude/src/arena/alloc_slice_ref.rs | Updates alignment-limit docs for &mut [T] allocations. |
| crates/multitude/src/arena/alloc_slice_box.rs | Removes outdated dst-feature note from docs. |
| crates/multitude/src/arena/alloc_prefixed.rs | Updates prefixed allocation docs for Box vs Rc/Arc layouts. |
| crates/multitude/src/arc.rs | Refactors Arc to support handle metadata + adds unsize/unsize_pin. |
| crates/multitude/src/allocator_impl.rs | Clarifies allocator alignment cap wording and grow fast-path comment. |
| crates/multitude/src/alloc_handle.rs | Clarifies pinning constraints and adds unwind-safety impls for Alloc. |
| crates/multitude/docs/DESIGN.md | Updates design documentation for hybrid metadata and freeze semantics. |
| crates/multitude/docs/BUMPALO.md | Updates comparison table for trait-object pointer width and DST support scope. |
| crates/multitude/Cargo.toml | Renames Callgrind bench targets to consistent criterion_*_cg naming. |
| crates/multitude/benches/multitude_serde_cg.rs | Renames typed lifecycle bench functions for clearer grouping. |
| crates/multitude/benches/multitude_record_batch/shared.rs | Makes hot paths reset arena internally; centralizes warm-cache setup. |
| crates/multitude/benches/multitude_record_batch.rs | Removes allocation tracking, adopts per-iteration reclamation + consistent setup. |
| crates/multitude/benches/multitude_record_batch_cg.rs | Switches state to &mut so hot paths can reset between iterations. |
| crates/multitude/benches/gungraun_alloc/linux.rs | Removes old Callgrind wrapper (superseded by criterion_alloc_cg). |
| crates/multitude/benches/criterion_rc_array.rs | Switches to batched Criterion harness excluding setup/teardown. |
| crates/multitude/benches/criterion_rc_array_cg/linux.rs | Renames/reshapes Callgrind group and functions to match Criterion pairing. |
| crates/multitude/benches/criterion_rc_array_cg.rs | Updates bench wiring and naming to criterion_rc_array_cg. |
| crates/multitude/benches/criterion_drop.rs | Renames groups/benches for consistent naming and pairing with Callgrind. |
| crates/multitude/benches/criterion_drop_cg/linux.rs | Renames Callgrind groups/functions to match Criterion pairing. |
| crates/multitude/benches/criterion_drop_cg.rs | Updates bench wiring and naming to criterion_drop_cg. |
| crates/multitude/benches/criterion_arena_vs_allocator.rs | Renames Criterion group for consistent prefixing. |
| crates/multitude/benches/criterion_arc_array.rs | Switches to batched Criterion harness excluding setup/teardown. |
| crates/multitude/benches/criterion_arc_array_cg/linux.rs | Renames/reshapes Callgrind group and functions to match Criterion pairing. |
| crates/multitude/benches/criterion_arc_array_cg.rs | Updates bench wiring and naming to criterion_arc_array_cg. |
| crates/multitude/benches/criterion_alloc.rs | Renames groups and aligns naming/pairing with Callgrind bench. |
| crates/multitude/benches/criterion_alloc_cg/linux.rs | Adds new Callgrind wrapper organized by Criterion group/variant naming. |
| crates/multitude/benches/criterion_alloc_cg.rs | Wires new Callgrind groups and updates naming/invocation docs. |
Comments suppressed due to low confidence (1)
crates/multitude/src/box.rs:108
RefUnwindSafe/UnwindSafeare implemented only forBox<T, A>(default metadata). Like theSend/Syncimpls above, any explicit non-defaultMwould fall back to auto-trait behavior and may bypass the intended unwind-safety bounds. Implement these forBox<T, A, M>instead.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #617 +/- ##
========================================
Coverage 100.0% 100.0%
========================================
Files 470 471 +1
Lines 45251 45399 +148
========================================
+ Hits 45251 45399 +148
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 79 out of 79 changed files in this pull request and generated no new comments.
Comments suppressed due to low confidence (1)
crates/multitude/tests/unsize.rs:18
size_of::<...>()is used later in this test file, butsize_ofis never imported or qualified. As written, this will not compile (e.g. the assertions intrailing_trait_object_dst_uses_handle_metadataandonly_trait_object_handles_pay_for_metadata).
|
[design] Box/Arc/Rc/Pool/Alloc in both Would it be worth factoring the |
|
Thanks for the suggestion. I considered sharing the unwind assertion harness, but I prefer keeping these small test-only helpers local for now. A shared dev crate or macro would add dependency and macro indirection while centralizing only test syntax, not the intentionally distinct ownership and allocator contracts each crate must assert. Keeping each contract self-contained also makes drift visible as an explicit test change in that crate; extraction would make more sense if the harness grows materially. |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 79 out of 79 changed files in this pull request and generated no new comments.
Comments suppressed due to low confidence (2)
crates/multitude/benches/criterion_arc_array.rs:6
- The module-level docs say “Setup and result teardown are excluded”, but the
iter_batchedroutine returns(result, arena). Criterion will drop that return value as part of the timed iteration loop, so teardown is still included in the measured cost. Please update the docs (or change the benchmark structure) so the description matches what’s being measured.
//! Builds an `Arc<[Arc<[u8]>]>` of `PROPERTIES` binary blobs two ways and
//! compares them: `std::sync::Arc` (global allocator) vs `multitude::Arc`.
//! Setup and result teardown are excluded, so every case measures build cost.
crates/multitude/benches/criterion_rc_array.rs:6
- The module-level docs say “Setup and result teardown are excluded”, but the
iter_batchedroutine returns(result, arena). Criterion will drop that return value as part of the timed iteration loop, so teardown is still included in the measured cost. Please update the docs (or change the benchmark structure) so the description matches what’s being measured.
//! Builds an `Rc<[Rc<[u8]>]>` of `PROPERTIES` binary blobs two ways and
//! compares them: `std::rc::Rc` (global allocator) vs `multitude::Rc`.
//! Setup and result teardown are excluded, so every case measures build cost.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 79 out of 79 changed files in this pull request and generated no new comments.
Comments suppressed due to low confidence (1)
crates/multitude/src/coerce.rs:16
- The type-level documentation overstates the guarantee:
Coercionis only compiler-checked when constructed viacoerce!;Coercion::newis explicitlyunsafeand can violate the unsizing/coherence contract (even thoughunsize_metadatachecks the data-pointer address at runtime). Tightening this wording helps API users understand when they actually have compiler-checked safety.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 85 out of 85 changed files in this pull request and generated no new comments.
Comments suppressed due to low confidence (2)
crates/multitude/src/bytemuck.rs:82
- The alignment limit documented here ("64 KiB or greater") doesn’t match the actual scalar allocation guard:
Arena::try_alloc_withrejectsalign_of::<T>() >= MAX_SMART_PTR_ALIGN(32 KiB) before attempting allocation. This should document the 32 KiB ceiling so callers know what will actually panic.
crates/multitude/src/zerocopy.rs:79 - The documented alignment cap ("64 KiB or greater") doesn’t match the scalar allocation path used here (
Arena::try_alloc_with), which rejectsalign_of::<T>() >= 32 KiB(MAX_SMART_PTR_ALIGN). Please update the docs to reflect the actual limit.
|
Addressed the two suppressed alignment-documentation findings from the latest Copilot review in a501b81. The scalar |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 85 out of 85 changed files in this pull request and generated no new comments.
Comments suppressed due to low confidence (2)
crates/multitude/tests/serialization.rs:1168
- These assertions assume
JsonError'sDisplayalways includes aBacktrace:section, but backtrace capture/rendering is behind#[cfg(feature = "std")]inJsonError. Sinceserde_jsondoes not implystd,to_string()will omit this section whenstdis disabled.
Gate the backtrace-related expectations (and the nearby error.backtrace() call) on feature = "std" so this test works under --no-default-features --features serde_json too.
crates/multitude/tests/serialization.rs:1041
- These assertions assume
multitudeis built with thestdfeature (they require theBacktrace:section to be present inJsonError'sDisplay). Howeverserde_jsondoes not implystd, andJsonErroronly includes backtrace rendering behind#[cfg(feature = "std")]. This makes the test fail (or become feature-combination dependent) under--no-default-features --features serde_json.
Gate the backtrace assertion on feature = "std" (and optionally assert its absence when std is disabled) so this test matches the actual Display contract across supported feature sets.
This issue also appears on line 1165 of the same file.
Add compiler-checked coercion APIs for Box, Rc, and Arc using hybrid metadata. Sized values, strings, and slices retain thin handles, while trait objects carry their vtable metadata in each erased handle. Define unwind-safety contracts for Multitude and Plurality, strengthen DST and refcount coverage, and correct Serde ignored-value dispatch. Audit API documentation and make Criterion and Callgrind benchmark setup, teardown, naming, and reporting consistent. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 30099931-5bbd-4483-b487-915be7e43641
|
Addressed the latest suppressed no- |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 85 out of 85 changed files in this pull request and generated no new comments.
Comments suppressed due to low confidence (2)
crates/multitude/src/arena/alloc_uninit.rs:123
- The docs here say allocations panic when
align_of::<T>()is at least 64 KiB, but the smart-pointer alignment ceiling isCHUNK_ALIGN / 2(= 32 KiB). This is likely to mislead users about what alignments are accepted (and there are other64 KiBmentions later in this file that should be updated similarly).
crates/multitude/src/arena/alloc_slice_ref.rs:82 - These docs say allocations panic when
align_of::<T>()is at least 64 KiB, but the arena’s smart-pointer alignment cap isCHUNK_ALIGN / 2(= 32 KiB). This should be corrected (and the other64 KiBmentions in this file should be updated similarly) to match the actual validation logic.
Add compiler-checked coercion APIs for Box, Rc, and Arc using hybrid metadata. Sized values, strings, and slices retain thin handles, while trait objects carry their vtable metadata in each erased handle.
Define unwind-safety contracts for Multitude and Plurality, strengthen DST and refcount coverage, and correct Serde ignored-value dispatch.
Audit API documentation and make Criterion and Callgrind benchmark setup, teardown, naming, and reporting consistent.