-
Notifications
You must be signed in to change notification settings - Fork 18
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
base: master
Are you sure you want to change the base?
Conversation
There was a problem hiding this 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() {} |
There was a problem hiding this comment.
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
{ | ||
(my_candidate.read_unaligned::<zerocopy::pointer::BecauseImmutable>() ^ T::ALL_BITS) | ||
== T::EMPTY | ||
} |
There was a problem hiding this comment.
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.
1cda797
to
b67dbea
Compare
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.
#[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 | ||
} |
There was a problem hiding this comment.
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); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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 |
There was a problem hiding this comment.
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?
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 toBitFlags
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 thezerocopy::TryFromBytes
trait. Custom implementations for zerocopy traitsTryFromBytes
seem somewhat discouraged but supported, so it should be fine to implement that.