Zeroable derive custom bounds#196
Conversation
60f5524 to
4965884
Compare
26e6e95 to
74aa251
Compare
|
As I replied in the second thread, I believe the bounds generated for each field are a must-have, otherwise this is unsafe with wrongly provided bounds. If the user wants such an unsafe impl, they can always write |
|
As stated, the normal soundness checks are still performed, so the derive macro cannot produce unsound code that compiles, as it also emits checks that guarantee that each field is For a concrete exampleFor a concrete example, this code (under this PR) expands to the following code. #[derive(bytemuck::Zeroable)]
#[zeroable(bound = "u32: Copy, U: bytemuck::Zeroable")]
struct Asdf<T, U> {
x: Box<T>,
y: U,
}
// expands to
struct Asdf<T, U> {
x: Box<T>,
y: U,
}
const _: fn() = || {
#[allow(clippy::missing_const_for_fn)]
#[doc(hidden)]
fn check<T, U>()
where
u32: Copy,
U: bytemuck::Zeroable,
{
fn assert_impl<T: ::bytemuck::Zeroable>() {}
assert_impl::<Box<T>>();
}
};
const _: fn() = || {
#[allow(clippy::missing_const_for_fn)]
#[doc(hidden)]
fn check<T, U>()
where
u32: Copy,
U: bytemuck::Zeroable,
{
fn assert_impl<T: ::bytemuck::Zeroable>() {}
assert_impl::<U>();
}
};
unsafe impl<T, U> ::bytemuck::Zeroable for Asdf<T, U>
where
u32: Copy,
U: bytemuck::Zeroable,
{
}The (Also, note to self, unrelated to this PR: the multiple separate |
|
@zachs18 thanks for the reply and for providing the expansion code, very helpful! What is the reason the expanded code generates the |
744a0e5 to
e4d7b31
Compare
|
(The failing CI on |
Lokathor
left a comment
There was a problem hiding this comment.
Looks good to me, I'll wait a while for wdanilo to have a chance to look at it.
Adds the ability to use custom bounds when using
derive(Zeroable)instead of the normal "add a bound to each of the generics".The normal soundness checks are still performed, so the custom bound must guarantee that the struct is actually zeroable, or compilation will fail.
Unresolved questions:
Zeroablewith explicitly provided bounds #190 (comment))? i.e. "Perfect Derive". This wouldn't be hard, and might make the whole "give explicit bounds" part of this PR obsolete (since the "bound on the fields" can be done without additional information), except as to restrict the impl.Emit bounds for each field
Ifemitted
that would work and not require the user to give any bounds.
Possible future work:
Podfor Allow derivingPodfor structs where generics are used only asPhantomData#191. I was looking at it, and it's harder than just re-using this PR's code because of the additional requirements ofPod.)