capnproto-rust
capnproto-rust copied to clipboard
HasStructSize::struct_size() -> HasStructSize::STRUCT_SIZE
HasStructSize::struct_size() was added at a time when Rust did not yet have associated constants. Converting it from a method to a constant makes it available for usage at compile time.
Thanks, looks good from my side 👍.
This is maybe not as useful as I had hoped. See https://github.com/rust-lang/rust/issues/45447
No, unfortunately the associated constant is not that useful in the current state of affairs, but the desired functionality (creating an appropriately-sized array where to place the builder's buffer for simple in-place messages) can be achieved by creating a trait which defines an array type for the buffer. An example is in Rust Playground here: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=c8fe8990babd025d0419449d09ec421e or plaintext here:
mod _private {
pub const SIZE: usize = 4;
}
trait IsInPlaceCapable {
type StorageType : Sized + Default;
}
struct Reader {}
struct Builder {}
impl IsInPlaceCapable for Reader {
type StorageType = [u64; _private::SIZE];
}
impl IsInPlaceCapable for Builder {
type StorageType = [u64; _private::SIZE];
}
struct Wrapper<T: IsInPlaceCapable>
{
array: <T as IsInPlaceCapable>::StorageType
}
impl<T: IsInPlaceCapable> Wrapper<T> {
fn new() -> Self {
Self {
array: <T as IsInPlaceCapable>::StorageType::default()
}
}
fn print_size(&self) {
println!("{}", std::mem::size_of::<Self>());
}
}
fn main() {
let x = Wrapper::<Reader>::new();
x.print_size();
}
Merging for inclusion in 0.15.0, which I intend to release after Rust 1.65 comes out next week.
With this change, the _private::struct_size
constant goes away. I checked that your example still works using an associated constant, as you will now need to do:
trait HasSize {
const SIZE: usize;
}
trait IsInPlaceCapable {
type StorageType : Sized + Default;
}
struct Reader {}
impl HasSize for Reader {
const SIZE: usize = 4;
}
struct Builder {}
impl HasSize for Builder {
const SIZE: usize = 4;
}
impl IsInPlaceCapable for Reader {
type StorageType = [u64; Reader::SIZE];
}
impl IsInPlaceCapable for Builder {
type StorageType = [u64; Builder::SIZE];
}
struct Wrapper<T: IsInPlaceCapable>
{
array: <T as IsInPlaceCapable>::StorageType
}
impl<T: IsInPlaceCapable> Wrapper<T> {
fn new() -> Self {
Self {
array: <T as IsInPlaceCapable>::StorageType::default()
}
}
fn print_size(&self) {
println!("{}", std::mem::size_of::<Self>());
}
}
fn main() {
let x = Wrapper::<Reader>::new();
x.print_size();
}
With this change, the _private::struct_size constant goes away.
Thanks. It is no problem to use the associated constant instead in our project.