I'm trying to implement some abstract linear algebra traits and structs as part of my practices learning rust. In the code below when I implement VectorAbstract<TValue> for VectorDynamic<TValue> there's no problem; but when I try to do the same for VectorStatic<TValue, DIM_COUNT> I get the following error :
the const parameter `DIM_COUNT` is not constrained by the impl trait, self type, or predicates
unconstrained const parameter
note: expressions using a const parameter must map each value to a distinct output value
note: proving the result of expressions other than the parameter are unique is not supported
What am I doing wrong here ?
What's the correct way to implement this ?
Here's my code :
pub trait VectorAbstract<TValue: Scalar>: VectorSpaceElement + // a dozen std traits
{
fn dot(lhs: &Self, rhs: &Self) -> TValue;
}
pub trait VectorDynamic<TValue: Scalar>: VectorAbstract<TValue> {
fn dim_count(&self) -> usize;
fn from_list(arr: Vec<TValue>) -> Self;
}
pub trait VectorStatic<TValue: Scalar, const DIM_COUNT: usize>: VectorAbstract<TValue> {
fn from_array(arr: [TValue; DIM_COUNT]) -> Self;
}
impl<TValue: Scalar, TVector: VectorDynamic<TValue>> VectorAbstract<TValue> for TVector {
fn dot(lhs: &Self, rhs: &Self) -> TValue {
// ... dot product body for dynamic vectors ...
}
}
impl<TValue: Scalar, const DIM_COUNT: usize, TVector: VectorStatic<TValue, DIM_COUNT>>
VectorAbstract<TValue> for TVector
{
fn dot(lhs: &Self, rhs: &Self) -> TValue {
// ... dot product body for static vectors ...
}
}
UPDATE 1
I also tried the following :
pub trait VectorStatic<TValue: Scalar>: VectorAbstract<TValue> {
const DIM_COUNT: usize;
fn from_array(arr: [TValue; Self::DIM_COUNT]) -> Self;
}
impl<TValue: Scalar, TVector: VectorStatic<TValue>> VectorAbstract<TValue> for TVector {
fn dot(lhs: &Self, rhs: &Self) -> TValue {
// ... dot product body for static vectors ...
}
}
But I get the following error where I'm declaring the from_array function :
generic parameters may not be used in const operations
cannot perform const operation using `Self`
note: type parameters may not be used in const expressions
Note : I want the DIM_COUNT to be obtained in compile time somehow, so no fn dim_count() for VectorStatic.
UPDATE 2
Also when I completely remove the implementation for VectorStatic, I get another error in another file where I have a Vector2 struct and try to implement VectorStatic<TValue, 2> for that:
pub struct Vector2<TValue: Scalar> {
pub x: TValue,
pub y: TValue,
}
impl<TValue: Scalar> VectorStatic<TValue, 2> for Vector2<TValue> {
// ... implementation ...
}
And here's the error :
the trait bound `math::algebra::vectors::vector2::Vector2<TValue>: math::algebra::abstractions::VectorDynamic<TValue>` is not satisfied
the trait `math::algebra::abstractions::VectorDynamic<TValue>` is not implemented for `math::algebra::vectors::vector2::Vector2<TValue>`
Note that this Vector2 struct is not supposed to be a VectorDynamic at all.
There's definitely something I have not understood clearly here, maybe rust thinks I'm trying to make every VectorAbstract a VectorDynamic or something like that ?
What is it that I'm missing ?
UPDATE 3
Perhaps I should also mention that I already tried the following :
impl<TValue: Scalar> VectorAbstract<TValue> for dyn VectorDynamic<TValue>
{
fn dot(lhs: &Self, rhs: &Self) -> TValue {
// ... dot product body for dynamic vectors ...
}
}
impl<TValue: Scalar, const DIM_COUNT: usize> VectorAbstract<TValue> for dyn VectorStatic<TValue, DIM_COUNT>
{
fn dot(lhs: &Self, rhs: &Self) -> TValue {
// ... dot product body for static vectors ...
}
}
But in that case I get this error for both :
the trait `math::algebra::abstractions::VectorDynamic/VectorStatic` cannot be made into an object
and then a dozen lines that say because they used Self as a type parameter.