Unable to call const generic functions in a generic function

Hi all,

I writing an algorithm that can adapt itself to differently-sized integers with the help of num-traits. The code needs to determine the size of a bounded generic type compile-time. However, when I compiled the code, I got complaints about error[E0401]: can't use generic parameters from outer function. But when I browse the help text of this error, I can only see cascaded function definitions, but not function calls.

Is a way to get the size of a generic type at compile time? Many thanks for any suggestions! (I am new to Rust, so if I have made some silly mistakes, please point them out directly :wink:)

Here is a simplified version of my code:

fn foo<T>(value: T) -> SomeStruct
    where T: num_traits::PrimInt + num_traits::Signed {
    const BYTES: usize = std::mem::size_of::<T>();

    // ...
    
    todo!()
}

Compiler output:

error[E0401]: can't use generic parameters from outer function
 --> src\[...].rs:7:46
  |
5 | fn foo<T>(value: T) -> SomeStruct
  |        - type parameter from outer function
6 |     where T: num_traits::PrimInt + num_traits::Signed {
7 |     const BYTES: usize = std::mem::size_of::<T>();
  |                                              ^ use of generic parameter from outer function

For more information about this error, try `rustc --explain E0401`.
error: could not compile `[...]` due to previous error

Here is a version that works.
The tradeoff is that BYTES isn't a const anymore, but a local binding.

It makes me think that const code might actually be processed before monomorphization.
Otherwise the call to std::mem::size_of<T>() should have the concrete type available and thus it should be possible to bind its result to a const.

Thanks @jjpe! Actually I have already considered said solution and found it work. Sad to learn that BYTES can't be a const, which makes it unsuitable for array length.

It makes me think that const code might actually be processed before monomorphization.

I assume this must be what you have said. Even a simple statement like const V: i32 = N; where N is a const generic parameter will fail to compile.

Yes; basically fn-level consts have global scope, only their visibility is local to the fn.

1 Like