Reputation: 305
I'm trying to wrap to_be_bytes
method into traits(currently they are implement directly from primitive types), so that I can use it on generic types. Here's my code:
trait ToBeBytes {
fn to_be_bytes(&self) -> [u8; mem::size_of::<Self>()];
}
the problem occurs at mem::size_of::<Self>()
, the compiler said that
the size for values of type
Self
cannot be known at compilation time
I came up with a concept called type placeholder, so I changed to this:
trait ToBeBytes {
type Element;
fn to_be_bytes(&self) -> [u8; mem::size_of::<Self::Element>()];
}
and now the compiler said:
associated type
Element
not found forSelf
I tried the example in tutorials:
pub trait Iterator {
type Item;
fn next(&mut self) -> Option<Self::Item>;
}
and it compiles.
So what's the difference between my code and the example? How can I accomplish my goal (wrap to_be_bytes
into traits)?
Upvotes: 1
Views: 659
Reputation: 305
The problem here is that rust do not fully support constant generic yet, according to this blog:
Currently, const parameters may only be instantiated by const arguments of the following forms:
- A standalone const parameter.
- A literal (i.e. an integer, bool, or character).
- A concrete constant expression (enclosed by {}), involving no generic parameters. For example:
fn foo<const N: usize>() {} fn bar<T, const M: usize>() { foo::<M>(); // ok: `M` is a const parameter foo::<2021>(); // ok: `2021` is a literal foo::<{20 * 100 + 20 * 10 + 1}>(); // ok: const expression contains no generic parameters foo::<{ M + 1 }>(); // error: const expression contains the generic parameter `M` foo::<{ std::mem::size_of::<T>() }>(); // error: const expression contains the generic parameter `T` let _: [u8; M]; // ok: `M` is a const parameter let _: [u8; std::mem::size_of::<T>()]; // error: const expression contains the generic parameter `T` }
Upvotes: 0
Reputation: 13518
Compiling your code results in the following error:
error: generic parameters may not be used in const operations
--> src/lib.rs:4:55
|
4 | fn to_be_bytes(&self) -> [u8; std::mem::size_of::<Self>()];
| ^^^^ cannot perform const operation using `Self`
|
= note: type parameters may not be used in const expressions
= help: use `#![feature(const_generics)]` and `#![feature(const_evaluatable_checked)]` to allow generic const expressions
And sure enough, your code compiles with #![feature(const_evaluatable_checked, const_generics)]
.
Upvotes: 1