Consider this (toy) code:
trait A<D> {
type B;
fn frob(&mut self) -> Self::B where Self: A<D>;
}
enum E<D> {
See(usize),
Dee(D),
}
impl<D> A<D> for Vec<D> {
type B = E<D>;
fn frob(&mut self) -> Self::B where Self: A<D> {
if self.len() > 3 {
E::See(self.len()) // replacing with Self::B gives E0599 instead
} else {
E::Dee(self.pop().unwrap())
}
}
}
In the implementation of frob
for Vec<D>
, Self::B
should be E<D>
, so this code should compile. However, it produces the following errors, as if the compiler forgot the identity of Self::B
:
Compiling playground v0.0.1 (/playground)
error[E0308]: mismatched types
--> src/lib.rs:15:13
|
13 | fn frob(&mut self) -> Self::B where Self: A<D> {
| ------- expected `<Vec<D> as A<D>>::B` because of return type
14 | if self.len() > 3 {
15 | E::See(self.len())
| ^^^^^^^^^^^^^^^^^^ expected associated type, found enum `E`
|
= note: expected associated type `<Vec<D> as A<D>>::B`
found enum `E<_>`
= help: consider constraining the associated type `<Vec<D> as A<D>>::B` to `E<_>` or calling a method that returns `<Vec<D> as A<D>>::B`
= note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
error[E0308]: mismatched types
--> src/lib.rs:17:13
|
12 | type B = E<D>;
| -------------- expected this associated type
13 | fn frob(&mut self) -> Self::B where Self: A<D> {
| ------- expected `<Vec<D> as A<D>>::B` because of return type
...
17 | E::Dee(self.pop().unwrap())
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected associated type, found enum `E`
|
= note: expected associated type `<Vec<D> as A<D>>::B`
found enum `E<D>`
For more information about this error, try `rustc --explain E0308`.
error: could not compile `playground` due to 2 previous errors
Removing the seemingly redundant type bound Self: A<D>
on the impl, however, makes the code compile.
What is happening here? Is this behavior intended?