psionic12
psionic12

Reputation: 305

associated type `Element` not found for `Self`

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 for Self

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

Answers (2)

psionic12
psionic12

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

Ibraheem Ahmed
Ibraheem Ahmed

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

Related Questions