Reputation: 13
I'm quite new to rust and to familiarize my self with it I'm trying to implement my own matrix structs.
An other user made me realize that maybe I did not have enough info, so heres a minimum viable code that gives me the error. https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=0dcd5a8c2ebdecb80867addfe7d38ccc
MathData is a trait implemented by f32 and f64 to limit the generic to only these two.
pub trait MatData<T> {}
impl MatData<f64> for f64 {}
impl MatData<f32> for f32 {}
The matrix Struct and Implementation:
pub struct Mat4<T: MatData<T>> {
data: [T; 16],
}
impl<T: MatData<T>> Index<usize> for Mat4<T> {
type Output = T;
fn index(&self, i: usize) -> &T {
&self.data[i]
}
}
impl<T: MatData<T>> IndexMut<usize> for Mat4<T> {
fn index_mut(&mut self, i: usize) -> &mut T {
&mut self.data[i]
}
}
impl<T> MulAssign for Mat4<T>
where
T: MatData<T> + Mul + Add + Mul<Output = T> + Add<Output = T> + Copy,
{
fn mul_assign(&mut self, rhs: Self) {
self[0] = self[0] * rhs[0] + self[1] * rhs[4] + self[2] * rhs[8] + self[3] * rhs[12];
self[1] = self[0] * rhs[1] + self[1] * rhs[5] + self[2] * rhs[9] + self[3] * rhs[13];
self[2] = self[0] * rhs[2] + self[1] * rhs[6] + self[2] * rhs[10] + self[3] * rhs[14];
self[3] = self[0] * rhs[3] + self[1] * rhs[7] + self[2] * rhs[11] + self[3] * rhs[15];
self[4] = self[4] * rhs[0] + self[5] * rhs[4] + self[6] * rhs[8] + self[7] * rhs[12];
self[5] = self[4] * rhs[1] + self[5] * rhs[5] + self[6] * rhs[9] + self[7] * rhs[13];
self[6] = self[4] * rhs[2] + self[5] * rhs[6] + self[6] * rhs[10] + self[7] * rhs[14];
self[7] = self[4] * rhs[3] + self[5] * rhs[7] + self[6] * rhs[11] + self[7] * rhs[15];
self[8] = self[8] * rhs[0] + self[9] * rhs[4] + self[10] * rhs[8] + self[11] * rhs[12];
self[9] = self[8] * rhs[1] + self[9] * rhs[5] + self[10] * rhs[9] + self[11] * rhs[13];
self[10] = self[8] * rhs[2] + self[9] * rhs[6] + self[10] * rhs[10] + self[11] * rhs[14];
self[11] = self[8] * rhs[3] + self[9] * rhs[7] + self[10] * rhs[11] + self[11] * rhs[15];
self[12] = self[12] * rhs[0] + self[13] * rhs[4] + self[14] * rhs[8] + self[15] * rhs[12];
self[13] = self[12] * rhs[1] + self[13] * rhs[5] + self[14] * rhs[9] + self[15] * rhs[13];
self[14] = self[12] * rhs[2] + self[13] * rhs[6] + self[14] * rhs[10] + self[15] * rhs[14];
self[15] = self[12] * rhs[3] + self[13] * rhs[7] + self[14] * rhs[11] + self[15] * rhs[15];
}
}
When using it like so:
mat_a *= mat_b;
I get this from the compiler:
binary assignment operation
*=
cannot be applied to typematrix::Mat4<T>
the traitstd::ops::MulAssign
is not implemented formatrix::Mat4<T>
"
Upvotes: 1
Views: 310
Reputation: 8793
This happens because your MulAssign
implementation:
impl<T> MulAssign for Mat4<T>
where
T: MatData<T> + Mul + Add + Mul<Output = T> + Add<Output = T> + Copy,
is not general enough as Transform
implementation which is:
impl<T> Transform<T>
where
T: MatData<T> + Add + Mul + Copy,
The difference is MulAssign
implementation explicitly states the associated types of Mul
and Add
as Output = T
, this makes the MulAssign
impl less general than Transform
impl and as a result you cannot use MulAssign
behavior in Transform
To use it you either need to make MulAssign
more general(according to your implementation it is not possible) or(then) you need to make Transform
less general like :
impl<T> Transform<T>
where
T: MatData<T> + Mul<Output = T> + Add<Output = T> + Copy,
{
Upvotes: 0