I published a crate on crates.io recently and when I tried using it my code no longer compiles, reverting to the local version through crate = { path = "/path/to/crate/" }
fixes compilation. The source code in both versions is the same, I am using the latest version of the crate in both.
The actual error is this:
In this impl
impl<'a, V, E, F> WaveFrontCompatible<'a> for HalfMesh<V, E, F>
where
V: PrimitiveContainer,
E: PrimitiveContainer,
F: PrimitiveContainer,
V::PrimitiveData: VertDataGetters,
F::PrimitiveData: FaceDataGetters<
Normal = <<V as PrimitiveContainer>::PrimitiveData as VertDataGetters>::V3,
Uv = <<V as PrimitiveContainer>::PrimitiveData as VertDataGetters>::V2,
>,
{
type Index = usize;
type Scalar = <<V as PrimitiveContainer>::PrimitiveData as VertDataGetters>::Scalar;
type Vert2D = <<V as PrimitiveContainer>::PrimitiveData as VertDataGetters>::V2;
type Vert3D = <<V as PrimitiveContainer>::PrimitiveData as VertDataGetters>::V3;
}
error[E0277]: cannot multiply `<<V as traits::PrimitiveContainer>::PrimitiveData as geometry_traits::VertDataGetters>::Scalar` by `<<V as traits::PrimitiveContainer>::PrimitiveData as geometry_traits::VertDataGetters>::V2`
--> src/wavefront.rs:19:19
|
19 | type Vert2D = <<V as PrimitiveContainer>::PrimitiveData as VertDataGetters>::V2;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no implementation for `<<V as traits::PrimitiveContainer>::PrimitiveData as geometry_traits::VertDataGetters>::Scalar * <<V as traits::PrimitiveContainer>::PrimitiveData as geometry_traits::VertDataGetters>::V2`
i.e. the compiler claims that Scalar and V2 cannot be multiplied together.
If we look at the definition of that trait we see this:
pub trait VertDataGetters
{
type Scalar: ScalarLike;
type V2: VectorLike<Scalar = Self::Scalar>;
type V3: VectorLike<Scalar = Self::Scalar>;
fn position(&self) -> Self::V3;
fn normal(&self) -> Self::V3;
fn uv(&self) -> Self::V2;
}
If we then look at the definition of VectorLike
we see this:
pub trait VectorLike:
LinAlg<Self::Scalar>
+ Index<usize, Output = Self::Scalar>
+ IndexMut<usize, Output = Self::Scalar>
+ Default
{
type Scalar: ScalarLike + Mul<Self, Output = Self>;
}
And finally, the defintion of LinAlg
pub trait LinAlg<S>:
Mul<S, Output = Self>
+ Add<Output = Self>
+ AddAssign<Self>
+ Sub<Output = Self>
+ Div<S, Output = Self>
+ Neg
+ Copy // Consider removing this one and only requiring clone.
+ Sized
where S: ScalarLike + Mul<Self, Output = Self>,
{
}
So LinAlg<S>
requires that the type implements multiplication with S
in both diretions.
Then VectorLike
forwards that restriction to VectorLike::Scalar
.
So VertDataGetters
guarantees that all of V2 * Scalar
, V3 * Scalar
, Scalar * V2
and V3 * Scalar
are valid operations via:
type V2: VectorLike<Scalar = Self::Scalar>;
type V3: VectorLike<Scalar = Self::Scalar>;
So this error:
no implementation for `<<V as traits::PrimitiveContainer>::PrimitiveData as geometry_traits::VertDataGetters>::Scalar * <<V as traits::PrimitiveContainer>::PrimitiveData as geometry_traits::VertDataGetters>::V2`
Should be impossible since that product exists due to the trait bounds specified on the type. Why am I seeing this?