Add T: ?Sized to every Smart Pointer in the Library #8
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
After almost giving up, i finally found a design that allows preserving the Metadata of fat pointers outside of the Atomic. Sadly the creation of the unsized type currently requires nightly (derive_smart_pointer), so i don't assume this will get merged until that is stable.
(Maybe some APIs like copying the unsized data from a box into the Node would work on stable, but i didn't really test)
The nightly feature is also required by the Rust for Linux people, so maybe it will be stabilized soon.
would close #3
Design
I put a self-referential pointer inside of NodeHeader which stores the MetaData of the type. This also exists for Sized types, because otherwise the size of the type would need to change when doing the unsize coercion (not possible). This pointer is set when calling queue_drop, because it is only needed for dropping the node. before that i think (not sure) that the metadata could change (e.g. std::mem::swap) so i don't put it into there before.
This of course disallows moving the Node after calling queue_drop, but that is already not allowed as that would also dangle the ptr to the current node in the drop queue.
Then inside drop the constant offset (due to repr(C)) to the self_ptr is used to read it and cast it to the specific type. Then this ptr is used to drop the type.
The nightly feature ptr_metadata would allow to only store the metadata and not a self ptr with it, but that wouldn't change much.
This doesn't add T: ?Sized for SharedCell because i honestly didn't spend enough time to understand the design of it, so i didn't find a place to put the metadata. Here the metadata also needs to exists before calling queue_drop, so it would need to be stored somewhere else than for the other pointer types.