Proper use of pointers and ownership of arrays

Hi there. I'd like to get some advice on using pointers correctly.

I'm trying to create a struct called Tensor that contains an array as data. Tensors can have different sized arrays, but the sizes are known at compile time. I don't want to use a Vector since the underlying data of a Tensor will have the same size for its entire existence.

I think the solution is to create the Tensor with a pointer (data) like

struct Tensor<T> {
    data: NonNull<T>,
    ...
}

I wrote a macro that makes it easy to create arrays of any size and type:

macro_rules! new_tensor {
    ( $type:ty; $value:literal; $( $x:expr ),* ) => {
        {   
            let temp_array: [$type; $( $x* )* 1] = [$value; $( $x* )* 1];
            let array_ptr = &temp_array.as_mut_ptr();
            temp_array
        }
    };
    ...
}

So new_tensor![u32; 2; 1, 3, 3]; creates an array with type u32 of all 2's with total size (1 * 3 * 3 = 9).

But now I'm not sure about the best way to create a Tensor with the array pointer (array_ptr). And how to make sure I get the ownership right. Any help would be appreciated, thanks!

I think const generics are closest to the functionality you really want, but those are still unstable.

If the only reason you don't want to use a Vec is because you know the data will have the same size for its entire existence, then maybe making data instead hold a boxed slice would work for you:

struct Tensor<T> {
    data: Box<[T]>,
}

impl<T> Default for Tensor<T> {
    fn default() -> Self {
        let data = Vec::new().into_boxed_slice();
        Self { data }
    }
}

impl<T> Tensor<T> {
    pub fn new(data: Vec<T>) -> Self {
        Self { data: data.into_boxed_slice() }
    }
}

Vec::into_boxed_slice()