Skip to content

Commit 9e966a2

Browse files
authored
Handle const generics and bounded lifetimes in derives (#654)
Previously, the derive was not stripping out inline bounds. Fixes #653
1 parent 6f773ef commit 9e966a2

10 files changed

+148
-3
lines changed

zerocopy-derive/src/lib.rs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -606,14 +606,21 @@ fn impl_block<D: DataExt>(
606606
}
607607
quote!(#param)
608608
});
609+
609610
// The identifiers of the parameters without trait bounds or type defaults.
610611
let param_idents = input.generics.params.iter().map(|param| match param {
611612
GenericParam::Type(ty) => {
612613
let ident = &ty.ident;
613614
quote!(#ident)
614615
}
615-
GenericParam::Lifetime(l) => quote!(#l),
616-
GenericParam::Const(cnst) => quote!(#cnst),
616+
GenericParam::Lifetime(l) => {
617+
let ident = &l.lifetime;
618+
quote!(#ident)
619+
}
620+
GenericParam::Const(cnst) => {
621+
let ident = &cnst.ident;
622+
quote!({#ident})
623+
}
617624
});
618625

619626
quote! {

zerocopy-derive/tests/enum_known_layout.rs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
mod util;
88

9-
use {static_assertions::assert_impl_all, zerocopy::KnownLayout};
9+
use {core::marker::PhantomData, static_assertions::assert_impl_all, zerocopy::KnownLayout};
1010

1111
#[derive(KnownLayout)]
1212
enum Foo {
@@ -29,3 +29,18 @@ enum Baz {
2929
}
3030

3131
assert_impl_all!(Baz: KnownLayout);
32+
33+
// Deriving `KnownLayout` should work if the enum has bounded parameters.
34+
35+
#[derive(KnownLayout)]
36+
#[repr(C)]
37+
enum WithParams<'a: 'b, 'b: 'a, const N: usize, T: 'a + 'b + KnownLayout>
38+
where
39+
'a: 'b,
40+
'b: 'a,
41+
T: 'a + 'b + KnownLayout,
42+
{
43+
Variant([T; N], PhantomData<&'a &'b ()>),
44+
}
45+
46+
assert_impl_all!(WithParams<'static, 'static, 42, u8>: KnownLayout);

zerocopy-derive/tests/struct_as_bytes.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,3 +132,18 @@ struct Unsized {
132132
}
133133

134134
assert_impl_all!(Unsized: AsBytes);
135+
136+
// Deriving `AsBytes` should work if the struct has bounded parameters.
137+
138+
#[derive(AsBytes)]
139+
#[repr(transparent)]
140+
struct WithParams<'a: 'b, 'b: 'a, const N: usize, T: 'a + 'b + AsBytes>(
141+
[T; N],
142+
PhantomData<&'a &'b ()>,
143+
)
144+
where
145+
'a: 'b,
146+
'b: 'a,
147+
T: 'a + 'b + AsBytes;
148+
149+
assert_impl_all!(WithParams<'static, 'static, 42, u8>: AsBytes);

zerocopy-derive/tests/struct_from_bytes.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,3 +62,18 @@ struct TypeParams<'a, T: ?Sized, I: Iterator> {
6262
assert_impl_all!(TypeParams<'static, (), IntoIter<()>>: FromBytes);
6363
assert_impl_all!(TypeParams<'static, AU16, IntoIter<()>>: FromBytes);
6464
assert_impl_all!(TypeParams<'static, [AU16], IntoIter<()>>: FromBytes);
65+
66+
// Deriving `FromBytes` should work if the struct has bounded parameters.
67+
68+
#[derive(FromZeroes, FromBytes)]
69+
#[repr(transparent)]
70+
struct WithParams<'a: 'b, 'b: 'a, const N: usize, T: 'a + 'b + FromBytes>(
71+
[T; N],
72+
PhantomData<&'a &'b ()>,
73+
)
74+
where
75+
'a: 'b,
76+
'b: 'a,
77+
T: 'a + 'b + FromBytes;
78+
79+
assert_impl_all!(WithParams<'static, 'static, 42, u8>: FromBytes);

zerocopy-derive/tests/struct_from_zeroes.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,3 +60,18 @@ struct TypeParams<'a, T: ?Sized, I: Iterator> {
6060
assert_impl_all!(TypeParams<'static, (), IntoIter<()>>: FromZeroes);
6161
assert_impl_all!(TypeParams<'static, AU16, IntoIter<()>>: FromZeroes);
6262
assert_impl_all!(TypeParams<'static, [AU16], IntoIter<()>>: FromZeroes);
63+
64+
// Deriving `FromZeroes` should work if the struct has bounded parameters.
65+
66+
#[derive(FromZeroes)]
67+
#[repr(transparent)]
68+
struct WithParams<'a: 'b, 'b: 'a, const N: usize, T: 'a + 'b + FromZeroes>(
69+
[T; N],
70+
PhantomData<&'a &'b ()>,
71+
)
72+
where
73+
'a: 'b,
74+
'b: 'a,
75+
T: 'a + 'b + FromZeroes;
76+
77+
assert_impl_all!(WithParams<'static, 'static, 42, u8>: FromZeroes);

zerocopy-derive/tests/struct_known_layout.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,3 +45,18 @@ struct TypeParams<'a, T, I: Iterator> {
4545

4646
assert_impl_all!(TypeParams<'static, (), IntoIter<()>>: KnownLayout);
4747
assert_impl_all!(TypeParams<'static, AU16, IntoIter<()>>: KnownLayout);
48+
49+
// Deriving `KnownLayout` should work if the struct has bounded parameters.
50+
51+
#[derive(KnownLayout)]
52+
#[repr(C)]
53+
struct WithParams<'a: 'b, 'b: 'a, const N: usize, T: 'a + 'b + KnownLayout>(
54+
[T; N],
55+
PhantomData<&'a &'b ()>,
56+
)
57+
where
58+
'a: 'b,
59+
'b: 'a,
60+
T: 'a + 'b + KnownLayout;
61+
62+
assert_impl_all!(WithParams<'static, 'static, 42, u8>: KnownLayout);

zerocopy-derive/tests/struct_unaligned.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,3 +83,18 @@ struct TypeParams<'a, T: ?Sized, I: Iterator> {
8383
assert_impl_all!(TypeParams<'static, (), IntoIter<()>>: Unaligned);
8484
assert_impl_all!(TypeParams<'static, u8, IntoIter<()>>: Unaligned);
8585
assert_impl_all!(TypeParams<'static, [u8], IntoIter<()>>: Unaligned);
86+
87+
// Deriving `Unaligned` should work if the struct has bounded parameters.
88+
89+
#[derive(Unaligned)]
90+
#[repr(transparent)]
91+
struct WithParams<'a: 'b, 'b: 'a, const N: usize, T: 'a + 'b + Unaligned>(
92+
[T; N],
93+
PhantomData<&'a &'b ()>,
94+
)
95+
where
96+
'a: 'b,
97+
'b: 'a,
98+
T: 'a + 'b + Unaligned;
99+
100+
assert_impl_all!(WithParams<'static, 'static, 42, u8>: Unaligned);

zerocopy-derive/tests/union_from_bytes.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,3 +54,19 @@ where
5454
}
5555

5656
assert_impl_all!(TypeParams<'static, (), IntoIter<()>>: FromBytes);
57+
58+
// Deriving `FromBytes` should work if the union has bounded parameters.
59+
60+
#[derive(FromZeroes, FromBytes)]
61+
#[repr(C)]
62+
union WithParams<'a: 'b, 'b: 'a, const N: usize, T: 'a + 'b + FromBytes>
63+
where
64+
'a: 'b,
65+
'b: 'a,
66+
T: 'a + 'b + Copy + FromBytes,
67+
{
68+
a: [T; N],
69+
b: PhantomData<&'a &'b ()>,
70+
}
71+
72+
assert_impl_all!(WithParams<'static, 'static, 42, u8>: FromBytes);

zerocopy-derive/tests/union_from_zeroes.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,3 +54,19 @@ where
5454
}
5555

5656
assert_impl_all!(TypeParams<'static, (), IntoIter<()>>: FromZeroes);
57+
58+
// Deriving `FromZeroes` should work if the union has bounded parameters.
59+
60+
#[derive(FromZeroes)]
61+
#[repr(C)]
62+
union WithParams<'a: 'b, 'b: 'a, const N: usize, T: 'a + 'b + FromZeroes>
63+
where
64+
'a: 'b,
65+
'b: 'a,
66+
T: 'a + 'b + Copy + FromZeroes,
67+
{
68+
a: [T; N],
69+
b: PhantomData<&'a &'b ()>,
70+
}
71+
72+
assert_impl_all!(WithParams<'static, 'static, 42, u8>: FromZeroes);

zerocopy-derive/tests/union_known_layout.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,3 +47,19 @@ where
4747
}
4848

4949
assert_impl_all!(TypeParams<'static, (), IntoIter<()>>: KnownLayout);
50+
51+
// Deriving `KnownLayout` should work if the union has bounded parameters.
52+
53+
#[derive(KnownLayout)]
54+
#[repr(C)]
55+
union WithParams<'a: 'b, 'b: 'a, const N: usize, T: 'a + 'b + KnownLayout>
56+
where
57+
'a: 'b,
58+
'b: 'a,
59+
T: 'a + 'b + Copy + KnownLayout,
60+
{
61+
a: [T; N],
62+
b: PhantomData<&'a &'b ()>,
63+
}
64+
65+
assert_impl_all!(WithParams<'static, 'static, 42, u8>: KnownLayout);

0 commit comments

Comments
 (0)