UPDATE: Fixed in stable 1.49.0!
Can anyone shed some light on why this may be happening? Not sure if this is a compiler bug (known or unknown) or just a gap in my understanding.
I'm half expecting the reply "GAT hasn't landed yet"
The issue
A type Num
derived from a trait is bound by both Mul<Self::Num>
and Mul<Self::Distraction>
.
When I attempt to multiply two values of the Num
type, the compiler errors:
expected Trait::Distraction, found Trait::Num
.
I stumbled upon this oddity in a larger context (unit conversion system where I use the result of the multiplication for further processing before returning from the function), but I didn't believe the compiler error.
Simplifying down to the essentials, it also duplicates on the playground:
pub trait Trait {
type Num: Copy
+ Mul<Self::Num, Output = Self::Num>
+ Mul<Self::Distraction, Output = Self::Num>;
type Distraction: Copy;
}
/// ... snip from a larger type impl ...
fn mul<T: Trait>(a: T::Num, b: T::Num) -> T::Num {
// using explicit function -- WORKS!
let explicit_function: T::Num = <T::Num as Mul<T::Num>>::mul(a, b);
// original impl -- COMPILE ERROR: expected Trait::Distraction, found Trait::Num
a * b
}
Strange ways the error disappears
What seems stranger to me is what makes the error disappear:
-
removing the trait by redefining
Num
andDistraction
as generic type parameters to the function itself (see fixed playground 1), or - swapping the order of the trait bounds on lines 5, 6 (see fixed playground 2).
If it weren't for #2, I'd be OK with "the compiler just does this, it's expected". Curious if anyone has run into this before, or has any insight to share.
Thanks!