Trait with array argument and fixed length array impl

I want to be able to ensure at compile time that the functions that implement a trait get an array with the correct length.
The following is the straightforward way i wanted to implement it.
But because &[i32] != &[i32; 1] it doesn't work.
Is there solution for this problem?

trait Test{
    fn test(arr: &[i32]) -> i32;
}

struct I{
}

struct J{
}

impl Test for I{
    fn test(arr: &[i32;1]) -> i32 {
        arr[0]
    }
}

impl Test for J{
    fn test(arr: &[i32;2]) -> i32 {
        arr[1]
    }
}


fn main() {
    let arr = [1];
    let a = I::test(&arr);
    let b = 1;
    assert_eq!(a,b);

    
}

You can't implement a trait function in a way that is more restrictive than the trait itself. Restrictions have to end up in the impl header, not the body.

But you can add an associated type that specifies the array type:

trait Test {
    type Array;
    fn test(arr: &Self::Array) -> i32;
}

impl Test for I {
    type Array = [i32; 1];
    fn test(arr: &[i32; 1]) -> i32 {
        arr[0]
    }
}

impl Test for J {
    type Array = [i32; 2];
    fn test(arr: &[i32; 2]) -> i32 {
        arr[1]
    }
}
2 Likes

(Use type Array: ?Sized if you want Array = [i32] to be possible.)

1 Like