Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can't create a constant using mem::size_of inside a function on a sized generic type (E401)

Tags:

I have a Rust program where I've been trying to use const functions as an alternative to macros to generate various constants at compile-time (which has been going great so far), but I've just hit a roadblock where the snippet below won't compile because size_of takes a generic parameter, and the compiler says I can't use the one from the function's signature:

const fn _IOC<T:Sized>(dir:u32, code:u8, nr:u8) -> u32 {
    // use of generic parameter from outer function (E0401)
    const size: usize = ::core::mem::size_of::<T>();

    (dir  << 30) | ((size as u32) << 16) | ((code as u32) << 8) | ((nr as u32))
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn it_works() {
        let myioctl = _IOC::<[u8; 65]>(3, b'H', 0x06);
        assert_eq!(myioctl, 0xC0414806);
    }
}

This is the error:

error[E0401]: can't use generic parameters from outer function
 --> src/lib.rs:3:48
  |
1 | const fn _IOC<T:Sized>(dir:u32, code:u8, nr:u8) -> u32 {
  |               - type parameter from outer function
2 |     // use of generic parameter from outer function (E0401)
3 |     const size: usize = ::core::mem::size_of::<T>();
  |                                                ^ use of generic parameter from outer function

I'm not sure I understand why this specific error would apply to the code above. Should I regard this as a compiler edge-case that isn't currently supported by the language or is there a way to make this work that I'm not seeing?

like image 486
Santo Guevarra Avatar asked Jan 19 '20 08:01

Santo Guevarra


1 Answers

You shouldn't be declaring size as a const. It should just be a regular immutable variable:

let size = ::core::mem::size_of::<T>();

Playground

like image 150
sshashank124 Avatar answered Oct 11 '22 18:10

sshashank124