Search code examples
rustrust-no-std

How to initialize a Option<T> array in rust?


So I'm trying to implement a simple queue for a no_std environment with no heap allocations like this:

pub struct Queue<T: Sized, const SIZE: usize> {
    pub data: [Option<T>; SIZE],
}

impl<T: Sized, const SIZE: usize> Queue<T, SIZE> {
    pub const fn new() -> Queue<T, SIZE> {
        const DEFAULT: Option<T> = None;
        Queue {
            data: [DEFAULT; SIZE],
        }
    }
}

It seems to me that this should be possible since T is sized and a None value can be const so it can be copied without T having to implement the Copy trait. I cannot seem to figure out how to do it however. The above syntax gives an error with a wonderfully useless tip suggesting I should replace T with T:

error[E0401]: can't use generic parameters from outer function
  --> src/queue.rs:11:31
   |
9  | impl<T: Sized, const SIZE: usize> Queue<T, SIZE> {
   |      - type parameter from outer function
10 |     pub const fn new() -> Queue<T, SIZE> {
11 |         const DEFAULT: Option<T> = Default::default();
   |                      -        ^ use of generic parameter from outer function
   |                      |
   |                      help: try using a local generic parameter instead: `<T>`

Is there any way to achieve this? I'm using the 2021 edition of rust by the way.


Solution

  • Associated constants of a type are allowed to use its parameters, so this compiles:

    pub struct Queue<T: Sized, const SIZE: usize> {
        pub data: [Option<T>; SIZE],
    }
    
    impl<T: Sized, const SIZE: usize> Queue<T, SIZE> {
        const NONE_T: Option<T> = None;
    
        pub const fn new() -> Queue<T, SIZE> {
            Queue {
                data: [Self::NONE_T; SIZE],
            }
        }
    }
    

    (Playground)

    It's unfortunate that the constant can't be inside the function, but it can at least be private.