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

Support Unalign for unsized types? #209

Open
joshlf opened this issue Aug 1, 2023 · 4 comments
Open

Support Unalign for unsized types? #209

joshlf opened this issue Aug 1, 2023 · 4 comments
Labels
compatibility-breaking Changes that are (likely to be) breaking

Comments

@joshlf
Copy link
Member

joshlf commented Aug 1, 2023

Since Unalign<T> is repr(packed), T must be Sized (you can switch to T: ?Sized + Copy, but actually this is still Sized because Copy: Clone and Clone: Sized). We could lift this restriction by wrapping the inner T in a ManuallyDrop. However, we'd need to figure out what to do about dropping. We could implement Drop when T: Sized or when T: Unaligned (so dropping in-place is valid), but when T: !Sized, we'd either have to leak the type or else implement some crazy approximation of dynamic stack allocation in order to move the value into an aligned location in order to drop it in-place. Alternatively, perhaps we can prove that it's never possible to create an owned, unsized Unalign<T>, and so the no-drop thing never matters in practice?

Background: If a type is repr(packed), its fields may live at invalid offsets at runtime, which means that Rust must prevent those fields from being operated on in-place. If a field requires dropping, Rust generates drop glue for these fields by first moving them into the local stack frame with correct alignment. At this point, they can be safely dropped in-place. However, if the type is unsized, then there's no way for it to be moved into the local stack frame. Thus, Rust only allows unaligned fields which don't have drop glue. In the case of generic types, this requires wrapping in a ManuallyDrop.

@joshlf
Copy link
Member Author

joshlf commented Aug 1, 2023

cc @djkoloski since you mentioned this behavior in #126 (comment)

@djkoloski
Copy link
Member

Requiring T: ?Sized + Copy is the same as requiring T: Sized because Copy: Clone and Clone: Sized.

@joshlf
Copy link
Member Author

joshlf commented Aug 17, 2023

Requiring T: ?Sized + Copy is the same as requiring T: Sized because Copy: Clone and Clone: Sized.

Ah hmmm yes that's a very good point.

@joshlf
Copy link
Member Author

joshlf commented Aug 17, 2023

Okay, updated to describe our options. Seems like wrapping in a ManuallyDrop might actually work, but there is one big catch relating to dropping unsized values.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
compatibility-breaking Changes that are (likely to be) breaking
Projects
None yet
Development

No branches or pull requests

2 participants