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