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 optional zerocopy support #62

Draft
wants to merge 4 commits into
base: master
Choose a base branch
from

Conversation

zebreus
Copy link

@zebreus zebreus commented Nov 8, 2024

This PR adds a flag that enables implementations for zerocopy traits on BitFlags.

Converting a BitFlags into the underlying number is trivial and always safe, so we can just derive those traits. Converting from a number to BitFlags is more tricky, because not every bit-pattern is valid. To assert that the bit-pattern is valid this PR provides a custom implementation of the zerocopy::TryFromBytes trait. Custom implementations for zerocopy traits TryFromBytes seem somewhat discouraged but supported, so it should be fine to implement that.

Copy link
Owner

@meithecatte meithecatte left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For now I'm not looking at the details of how the zerocopy API works. I'll take a closer look later.

T::Numeric: Immutable,
T::Numeric: FromZeros,
{
fn only_derive_is_allowed_to_implement_this_trait() {}
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this could use a comment linking to google/zerocopy#287, so that this doesn't scream "crimes! damn crimes!" at anyone who looks at this later.

src/lib.rs Outdated
Comment on lines 1104 to 1107
{
(my_candidate.read_unaligned::<zerocopy::pointer::BecauseImmutable>() ^ T::ALL_BITS)
== T::EMPTY
}
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This bit manipulation looks suspicious. Please add tests that exercise this. Or, maybe something like BitFlags::from_bits_truncate(x).bits() == x would be better, in terms of code reuse.

With the zerocopy feature activated we implement some zerocopy
traits containing an `only_derive_is_allowed_to_implement_this_trait`
function. That is fine as long as we know what we are doing.
Comment on lines +689 to +695
#[must_use]
#[inline(always)]
pub fn validate_bits(bits: T::Numeric) -> bool {
// SAFETY: We're truncating out all the invalid bits so it will
// only be different if there are invalid bits set.
(bits & T::ALL_BITS) == bits
}
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Honestly, I'm not sure if this makes sense as a public API.

// Dereference the pointer to the candidate
let candidate =
my_candidate.read_unaligned::<zerocopy::pointer::BecauseImmutable>();
return BitFlags::<T>::validate_bits(candidate);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
return BitFlags::<T>::validate_bits(candidate);
BitFlags::<T>::validate_bits(candidate)

@@ -1102,8 +1129,11 @@ mod impl_zerocopy {
let my_candidate =
unsafe { candidate.assume_validity::<zerocopy::pointer::invariant::Valid>() };
{
(my_candidate.read_unaligned::<zerocopy::pointer::BecauseImmutable>() ^ T::ALL_BITS)
== T::EMPTY
// TODO: Currently this assumes that the candidate is aligned. We actually need to check this beforehand
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if this is something I would've caught. Do you have any links I could reference for example zerocopy implementations for similar types?

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.

2 participants