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?
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 impl
s, 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.