Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add T: ?Sized to every Smart Pointer in the Library #8

Open
wants to merge 7 commits into
base: master
Choose a base branch
from

Conversation

luca3s
Copy link

@luca3s luca3s commented Oct 11, 2024

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.

@luca3s luca3s changed the title Add T: ?Sized to most Pointers on Nightly Add T: ?Sized to most Pointers Oct 19, 2024
@luca3s
Copy link
Author

luca3s commented Oct 19, 2024

I added a from_box API to the types i previously made T: ?Sized. The code is stronly inspired by Arc::from(Box). This allows creating the pointers from Iterators and Vecs. It also allows to remove the nightly feature and work around the lack of unsize coercion by first creating a box, then coercing the box and then creating the node from that box. This requires one additional allocation and copy compared to direct coercion.

would close #3, now also on stable

Nightly Features

Although this doesn't require nightly anymore it would still profit a lot from some features:
rust-lang/rust#123430 allows Coercion (less copying and very useful for dyn objects).

rust-lang/rust#75091 or rust-lang/rust#81513 would simplify the code and make the intentions a lot clearer. Doesn't make a difference to users of the library.

@luca3s luca3s changed the title Add T: ?Sized to most Pointers Add T: ?Sized to every Smart Pointer in the Library Oct 20, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Owned<T: ?Sized>
1 participant