Weird issue with trait constraints

I'm trying to use the frunk crate to implement a trait to a limited subset of heterogeneous lists. Something similar to the snippet below:

use {
    frunk::{HCons, HList, HNil},
    std::ops::Add,
};

trait Marker {}

impl Marker for i8 {}
impl Marker for i16 {}
impl Marker for u32 {}
impl Marker for u64 {}

trait Valid {}

impl Valid for HNil {}
impl<Head, Tail> Valid for HCons<Head, Tail>
where
    Head: Valid,
    Tail: Valid,
{
}

impl<AllMarkedTypes> Valid for AllMarkedTypes where AllMarkedTypes: Marker {}

trait Converter {
    type Validated: Valid;
}

impl Converter for () {
    type Validated = HList![];
}

impl<A> Converter for (A,)
where
    A: Converter,
    // A::Validated: Add<<() as Converter>::Validated>,
    // <A::Validated as Add<<() as Converter>::Validated>>::Output: Valid,
{
    type Validated = <A::Validated as Add<<() as Converter>::Validated>>::Output;
}

The way it's coded above, with the two commented constraints, it doesn't compile (as expected), showing a reasonable message about A::Validated not implementing Add<...>. Uncommenting the first line shows a different but still reasonable message, about how Add<...> is now implemented but its Output doesn't implement Valid. It even suggests the second commented line (simplified, because it replaces <() as Converter>::Validated with its concrete type HNil).

However, with both lines uncommented, it seems to act very strangely, because it still gives the same error but now repeated four times.

I think there's surely something I'm overlooking here, but I'm not sure what it is :confused: Any pointers would be greatly appreciated.

Thanks in advance!

Janito

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.