slice-dst: Add example for SliceWithHeader#70
slice-dst: Add example for SliceWithHeader#70MattesWhite wants to merge 3 commits intoCAD97:masterfrom
Conversation
CAD97
left a comment
There was a problem hiding this comment.
The example looks good modulo one tricky soundness pitfall (inline) that I want to be sure we aren't accidentally leading users into.
|
|
||
| /// Our [`Vec`] implementation. | ||
| /// | ||
| /// _Note:_ In contrast to [`std::vec::Vec`] this stores its length on the heap. |
There was a problem hiding this comment.
suggestion: use erasable::Thin and store Thin<Box<HeapData<T>>>, so the pointer is thin (single-usize-big) and length/capacity are both exclusively on the heap. SliceWithHeader stores its (slice) length inline to support erasing. (The eventual custom derive will omit this.)
There was a problem hiding this comment.
I'm a little bit reluctant to introduce erasable::Thin here. It addresses another issue and is from another crate. I would prefer to stick to an honorable mention here and put another example in the erasable crate.
crates/slice-dst/examples/my_vec.rs
Outdated
| } | ||
| fn iter(&self) -> impl Iterator<Item = &T> { | ||
| self.0.slice.iter().take(self.len()).map(|t| unsafe { | ||
| // Safe as only the initialized elements are iterated. |
There was a problem hiding this comment.
issue: unfortunately, this isn't sound as written, because anyone can use RefCast::ref_cast to convert between &MySlice and &HeapData, and change the header, changing how many initialized items are believed to exist. Or... it would be unsound if you added a DerefMut impl for MyVec, anyway. Having an example that's only sound due to a technicality is probably not the best idea 😄
suggestion: there are a few ways to fix this:
- (lazy) note explicitly that access to
&mut MySlice<_>would be unsound, due to the above; - (simple) just wrap
[T]instead ofHeapData<T>forMySlice<T>, as it doesn't need access to any of the other heap data (and is already a fat pointer, though usingThincould avoid this); - (chore) just inline the
transmuteusage that ref-cast abstracts away; or (funky) use the priv-in-pub trick discussed in Support private casts dtolnay/ref-cast#9 to get an effectively private cast.
There was a problem hiding this comment.
Thank you very much for pointing this out. I chose the chore option with a detailed // SAFETY: comment. I hope this is okay for you.
|
Feel free to ignore the clippy warnings CI reported; I fixed them in #72. |
The implementation of a 'cast trait' opened the opportunity to violate `MyVec`'s contract, making the implementation unsound.
Keeping Cargo.lock in git often causes unnecessary conflicts when merging branches.
This PR is the result of the discussion in #69 .
It adds an example for the
slice-dstcrate and demonstrates how a customVeccan be implemented.