Repository navigation
Zero-cost type family conversions - #3906
Conversation
By ensuring that the type family members have recursively identical memory layouts, we can enable zero-cost conversions via `::std::mem::transmute`. Caveats: - Concrete family members have a smaller total size, so the root node of their type tree must be converted. However, this is O(1) since all child nodes are `RuntimeTy` or `RealizedTy`, meaning we do not have to walk the children. - Downcasts still require a walk to verify - We rely on some de-facto sound but not formally guaranteed memory layouts from rust: primarily, that `Vec` and tuples should have a consistent memory layout based on element memory size. At a later date, we can switch to guaranteed-safe versions (but in practice this is fine)
Instead of walking and copying for narrowing, we instead walk to verify (no reallocations) then transumte in-place if the narrowing is legal.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
⏭️ Performance benchmarks were skippedPerf benchmarks (CodSpeed) are opt-in on pull requests — they no longer run on every push. They always run automatically after merge to To run them on this PR, do any of the following, then push a commit (or re-run CI):
|
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (4)
📝 WalkthroughWalkthroughThis PR introduces zero-cost transmute-based widening and narrowing conversions between type-family members with equal-size representations, replacing structural rebuild-based conversions for such pairs. It adds explicit discriminant tagging, layout assertions, satellite repr(C) layouts, RuntimeTy delegation via borrowed views, and new tests validating discriminant stability and narrowing correctness. ChangesZero-cost transmute conversions for type family
Estimated code review effort: 4 (Complex) | ~60 minutes Sequence Diagram(s)sequenceDiagram
participant Caller
participant NarrowImpl as "TryFrom<&Sup> for &Sub"
participant Validator as "validate_body"
participant SatValidator as "gen_sat_validator"
Caller->>NarrowImpl: try_from(&sup_value)
NarrowImpl->>Validator: validate(&sup_value)
Validator->>SatValidator: recurse into satellite fields
SatValidator-->>Validator: Ok(()) or Not<Sub>
Validator-->>NarrowImpl: Ok(()) or Not<Sub>
alt validation passes
NarrowImpl->>NarrowImpl: transmute borrow to &Sub
NarrowImpl-->>Caller: Ok(&Sub)
else validation fails
NarrowImpl-->>Caller: Err(Not<Sub> variant)
end
Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Binary size checks passed✅ 7 passed
Generated by |
By ensuring relevant type family enums have a recursively identical memory layout:
RealizedTy -> RuntimeTy -> Tyconversions are now a zero-cost transmuteTy -> RuntimeTy -> RealizedTyconversions are now a read-only walk followed by zero-cost transmute (no copy/reallocations)RuntimeTy/RealizedTywe only have to move the type head.Summary by CodeRabbit
New Features
Bug Fixes