rusttypestraits

Require in a Trait that all Iterators<Item = Self> implement a Trait


Very concretely I have the trait LogSumExp which is implemented for all Iterator<Item = f32> and Iterator<Item = f64>

I have my own Trait FloatTrait which is only implemented for f32 and f64 and helps me keep trait bounds in the program to a minimum but still be generic over these two types.

I want to express that any Iterator<Item : FloatTrait> : LogSumExp

It this somehow possible?


Solution

  • No, it is not possible to express that "for a type X to implement FloatTrait, it must also mean that all Iterator<Item=X>: LogSumExp". You can provide additional constraints that aren't directly on Self by using a where clause in the trait definition, but to do what you want would require some kind of higher-kinded constraint support that doesn't yet exist.


    Old answer addressing a different angle:

    No, Iterator<Item: FloatTrait>: LogSumExp cannot be assumed to be true just because Iterator<Item = f32>: LogSumExp and Iterator<Item = f64>: LogSumExp. Even if FloatTrait is not implemented beyond f32 and f64, the compiler will still operate with the presumption that other implementations could exist. Therefore a FloatTrait constraint is not just an alias for f32 | f64.

    In order to get that behavior, you would have to craft your implementation such that it does cover all FloatTrait possibilities (known and unknown). Instead of individual impls, you'd have to do it like this:

    impl<I> LogSumExp for I where I: Iterator, I::Item: FloatTrait {
        ...
    }
    

    If that sounds silly because no other implementations could possibly exist (due to being private, or sealed, or in a binary crate) then you aren't alone. The orphan rules and trait coherence for implementations and constraints are designed around stable extensibility across crates, which means it they are a thorn for local-crate-only things.