The following code compiles fine until you'll uncomment the for<'a> Rem<&'a Self, Output = Self>
bound.
use std::ops::Rem;
trait Trait:
Sized +
Rem<Output = Self> +
//for<'a> Rem<&'a Self, Output = Self>
{}
trait A {
type Inner: Trait;
}
fn test<T: A>() -> T::Inner {
let (x, y): (T::Inner, T::Inner) = panic!();
x % y
}
With the hrtb bound compilation fails with the following error:
error[E0308]: mismatched types
--> src/lib.rs:16:9
|
16 | x % y
| ^ expected `&<T as A>::Inner`, found associated type
|
= note: expected reference `&<T as A>::Inner`
found associated type `<T as A>::Inner`
help: consider constraining the associated type `<T as A>::Inner` to `&<T as A>::Inner`
|
13 | fn test<T: A<Inner = &<T as A>::Inner>>() -> T::Inner {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
help: consider borrowing here
|
16 | x % &y
| ^^
Which is really weird because
- it worked before
- error suggests using
T: A<Inner = &<T as A>::Inner>
which is recursion -
T::Inner
should be bothRem<&'_ Self>
andRem<Self>
so(x: T::Inner) % (y: T::Inner)
should compile
The workaround is to use either function that the same type for rhs:
fn rem_own<T: Rem>(x: T, y: T) -> T::Output {
x % y
}
Or to use explicit <T::Inner as Rem<T::Inner>>::rem(x, y)
instead of x % y
.
To me, this feels like a compiler bug, but maybe I'm missing something?
Playground: [link]