-
Notifications
You must be signed in to change notification settings - Fork 136
Description
When deriving IntoBytes, we check to see whether any generics are present:
zerocopy/zerocopy-derive/src/lib.rs
Line 1291 in e5c4179
| } else if ast.generics.params.is_empty() { |
If they are, we require all fields to be Unaligned:
zerocopy/zerocopy-derive/src/lib.rs
Lines 1312 to 1321 in e5c4179
| } else if is_c && !repr.is_align_gt_1() { | |
| // We can't use a padding check since there are generic type arguments. | |
| // Instead, we require all field types to implement `Unaligned`. This | |
| // ensures that the `repr(C)` layout algorithm will not insert any | |
| // padding unless #[repr(align)] explicitly adds padding, which we check | |
| // for in this branch's condition. | |
| // | |
| // FIXME(#10): Support type parameters for non-transparent, non-packed | |
| // structs without requiring `Unaligned`. | |
| (None, true) |
This requirement could be lifted if the only generic parameters are const parameters which are not used in the body of the type. This should just be a matter of filtering ast.generics.const_params() and only retaining const params which appear in the type's body. There may be edge cases in which a const param is only used inside of another quantification (e.g. there's a nested const argument that shadows the outer one), but it's fine to conservatively treat these as being equal – it will just result in more types being rejected than should be.
Original text
I have a const generic in a type, and no matter what types I set the inner fields (including a padding field), the derive macro insists that usize, u64, u32, etc. are unaligned. I tried setting a different type for the generic (u8, u16, u32), still the same problem.
use std::path::{Path, PathBuf};
use zerocopy::{FromBytes, Immutable, IntoBytes};
const MERC_SCALE: f64 = 123.456;
const TILE_SIZE: [f64; 20] = [1.; 20];
#[derive(Clone, IntoBytes, FromBytes, Immutable)]
#[repr(C)]
pub struct Tile<const L: usize>(pub u32, pub u32);
impl<const L: usize> Tile<L> {
pub fn path<P: AsRef<Path>>(&self, prefix: P, extension: &str) -> PathBuf {
prefix.as_ref().join(L.to_string()).join(self.0.to_string()).join(self.1.to_string()).with_extension(extension)
}
}
pub fn get_tile<const L: usize>(x: f64, y: f64) -> Tile<L> {
let tile_size = TILE_SIZE[L];
Tile(((MERC_SCALE + x) / tile_size) as u32, ((MERC_SCALE - y) / tile_size) as u32)
}Error:
|
9 | #[derive(Clone, IntoBytes, FromBytes, Immutable)]
| ^^^^^^^^^ the trait `zerocopy::Unaligned` is not implemented for `u32`