shame
shame copied to clipboard
`sm::CpuAligned` not implemented for `!Sized + sm::CpuLayout` structs
the trait sm::CpuAligned is not public and not implemented for !Sized + sm::CpuLayout structs.
as of now, the following code doesn't compile
#[derive(sm::CpuLayout)]
#[repr(C)]
struct Unsized {
a: f32,
b: [f32],
}
< Unsized as sm::CpuAligned>::CPU_ALIGNMENT;
Solution:
- add
sm::CpuAlignedto the public interface. - add an impl block for
sm::CpuAlignedin the#[derive(sm::CpuLayout)]macro that takes the same bounds as the impl block forsm::CpuLayoutand infers the alignment and optional size from the fields.
implementing sm::CpuAligned in the derive macro causes overlapping implementations with the blanket std::marker::Sized implementation
this is the code used:
impl<#generics_decl> #re::CpuAligned for #derive_struct_ident<#(#idents_of_generics),*>
where
#(#first_fields_type: ::std::marker::Sized,)*
#(#field_type: #re::CpuAligned,)*
#where_clause_predicates {
const CPU_ALIGNMENT: usize = {
use #re::CpuAligned;
let mut max_align = <#last_field_type>::CPU_ALIGNMENT;
#({
let field_align = <#first_fields_type>::CPU_ALIGNMENT;
if field_align > max_align {
max_align = field_align;
}
})*
max_align
};
const CPU_SIZE: Option<usize> = {
use std::alloc::Layout;
let mut layout = Layout::from_size_align(0, 1)
.expect("taken directly from official docs");
#(
layout = layout.extend(Layout::new::<#first_fields_type>())
.expect("compile time layout overflow").0;
)*
match <#last_field_type>::CPU_SIZE {
None => None,
Some(last_size) => {
let last_align = <#last_field_type>::CPU_ALIGNMENT;
let last_field_layout = Layout::from_size_align(last_size, last_align)
.expect("compile time invalid layout");
let layout = layout.extend(last_field_layout)
.expect("compile time layout overflow").0;
layout.pad_to_align();
Some(layout.size())
},
}
};
fn alignment() -> usize {
Self::CPU_ALIGNMENT
}
}
Progress on this issue might require merging sm::CpuAligned with sm::CpuLayout.