Here is a kind of lengthy example because I was not able to reduce it further. Rust Playground
use std::marker::PhantomData;
use std::ops::{Add, Sub, Mul, Di
ScalarVal(1) + a resolves basically to , which looks for an Add implementation on ScalarVal.
For whatever reason, this one is checked first:
impl Add> for ScalarVal<::ScalarType>
where PixelP: Pixel,
ScalarVal<::ScalarType>: Add
PixelP is uninstantiated at this point, so PixelP: Pixel can't be checked. Thus we get to
ScalarVal<::ScalarType>: Add
Let's simplify this. Since PixelP is unknown right now, is unknown. The actual information known by the compiler looks more like
impl Add> for ScalarVal<_>
where ScalarVal<_>: Add
So ScalarVal<_> looks for an Add. This means we should look for an appropriate T. Obviously this means looking in ScalarVal's Add impls. Looking at the same one, we get
impl Add> for ScalarVal<_>
where ScalarVal<_>: Add
which means that if this one matches, T == Image.
Obviously then T2 == Image, T3 == Image, etc. This results in an overflow and general sadness. Rust never finds a disproof, so can't ever guarantee it's going down the wrong path.