"cycle detected when checking visibilities" in abstract trait
Asked Answered
U

1

6

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()
    }
}
Ujiji answered 26/1 at 20:53 Comment(2)
Could you provide a minimal reproducible example?Aubervilliers
Just a note: the &'a self feels wrong.Ermeena
M
2

I think this explains the issue a little bit. If you can compile with nightly Rust you should get a better error.

Marcasite answered 27/1 at 21:29 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.