I am trying to make work a trait that depends on multiple levels of other abstract traits. I am running into this error:
error[E0391]: cycle detected when checking effective visibilities
|
note: ...which requires computing type of `wavefront::<impl at src/wavefront.rs:28:1: 47:46>::pos_iterator::{opaque#0}`...
--> src/wavefront.rs:54:34
|
54 | fn pos_iterator(&'a self) -> impl Iterator<Item = Self::Vert3D>
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...which requires computing type of opaque `wavefront::<impl at src/wavefront.rs:28:1: 47:46>::pos_iterator::{opaque#0}`...
--> src/wavefront.rs:54:34
|
54 | fn pos_iterator(&'a self) -> impl Iterator<Item = Self::Vert3D>
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...which requires type-checking `wavefront::<impl at src/wavefront.rs:28:1: 47:46>::pos_iterator`...
--> src/wavefront.rs:54:5
|
54 | fn pos_iterator(&'a self) -> impl Iterator<Item = Self::Vert3D>
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: ...which again requires checking effective visibilities, completing the cycle
note: cycle used when checking that `wavefront::<impl at src/wavefront.rs:28:1: 47:46>` is well-formed
--> src/wavefront.rs:28:1
|
28 | / impl<'a, V2, V3, V, E, F, VI, EI, FI> WaveFrontCompatible<'a>
29 | | for dyn HalfMeshLike<
30 | | VertData = V,
31 | | EdgeData = E,
... |
46 | | EI: Iterator<Item = HEdgeHandle<V, E, F>>,
47 | | FI: Iterator<Item = FaceHandle<V, E, F>>,
| |_____________________________________________^
= note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
I have tried changing my types, trying to add more traits, specialising the return types... I just don't understand, why is the compiler trying to instantiate the types here, why is it not waiting until I try to apply the trait to a concrete type to know if it can or not deduce the types?
Code:
pub trait WaveFrontCompatible<'a>
{
type Scalar: num_traits::Float + Debug + AddAssign + Display;
type Vert2D: VectorLike<Scalar = Self::Scalar>;
type Vert3D: VectorLike<Scalar = Self::Scalar>;
type Index: num_traits::int::PrimInt + Display;
fn pos_iterator(&'a self) -> impl Iterator<Item = Self::Vert3D>;
fn uv_iterator(&'a self) -> impl Iterator<Item = Self::Vert2D>;
fn norm_iterator(&'a self) -> impl Iterator<Item = Self::Vert3D>;
fn segment_iterator(&'a self) -> impl Iterator<Item = [Self::Index; 2]>;
fn pos_index_iterator(
&'a self,
) -> impl Iterator<Item = impl Iterator<Item = Self::Index>>;
fn uv_index_iterator(
&'a self,
) -> impl Iterator<Item = impl Iterator<Item = Self::Index>>;
fn norm_index_iterator(
&'a self,
) -> impl Iterator<Item = impl Iterator<Item = Self::Index>>;
}
trait FaceDataGetters
{
type Normal;
type Uv;
fn normal_count(&self) -> usize;
fn uv_count(&self) -> usize;
fn normal(&self, id: usize);
fn uv(&self, id: usize);
}
trait VertDataGetters
{
type V3;
fn position(&self) -> Self::V3;
}
impl<'a, V2, V3, V, E, F, VI, EI, FI> WaveFrontCompatible<'a>
for dyn HalfMeshLike<
VertData = V,
EdgeData = E,
FaceData = F,
VertIterator = VI,
EdgeIterator = EI,
FaceIterator = FI,
>
where
V: VertDataGetters + Debug + Clone,
V2: VectorLike + Debug + Clone,
V2::Scalar: Display + Debug,
V3: VectorLike + Debug + Clone,
V3::Scalar: Display + Debug,
E: Debug + Clone,
F: Debug + Clone + FaceDataGetters<Normal = V3, Uv = V2>,
VI: Iterator<Item = VertHandle<V, E, F>>,
EI: Iterator<Item = HEdgeHandle<V, E, F>>,
FI: Iterator<Item = FaceHandle<V, E, F>>,
{
type Index = usize;
type Scalar = V3::Scalar;
type Vert2D = V2;
type Vert3D = V3;
fn pos_iterator(&'a self) -> impl Iterator<Item = Self::Vert3D>
{
self.iter_verts().map(|v| v.data().position())
}
fn norm_iterator(&'a self) -> impl Iterator<Item = Self::Vert3D>
{
self.iter_faces()
.map(|face| face.data().iter_normals())
.flattent()
}
fn uv_iterator(&'a self) -> impl Iterator<Item = Self::Vert2D>
{
self.iter_faces()
.map(|face| face.data().iter_uvs())
.flatten()
}
fn pos_index_iterator(
&'a self,
) -> impl Iterator<Item = impl Iterator<Item = Self::Index>>
{
self.iter_faces()
.map(|f| f.vertex_handles().map(|v| v.id().0 as usize))
}
fn norm_index_iterator(
&'a self,
) -> impl Iterator<Item = impl Iterator<Item = Self::Index>>
{
self.norm_iterator().enumerate().map(|i| i.0)
}
fn uv_index_iterator(
&'a self,
) -> impl Iterator<Item = impl Iterator<Item = Self::Index>>
{
self.norm_uv().enumerate().map(|i| i.0)
}
fn segment_iterator(&'a self) -> impl Iterator<Item = [Self::Index; 2]>
{
std::iter::empty()
}
}
&'a self
feels wrong. – Ermeena