Playing around with generic associated types, I encountered what looks like a compiler bug:
trait Monad {
type M<T>;
fn bind<T, U, F: Fn(T) -> Self::M<U>>(m: Self::M<T>, f: F) -> Self::M<U>;
fn unit<T>(x: T) -> Self::M<T>;
fn map<T, U, F: Fn(T) -> U>(m: Self::M<T>, f: F) -> Self::M<U> {
Self::bind(m, |x| Self::unit(f(x)))
}
/// applicative operator `<*>`
fn app<T, U, F: Fn(T) -> U>(f: Self::M<F>, m: Self::M<T>) -> Self::M<U> where Self::M<T>: Clone {
Self::bind(f, |f| Self::map(m.clone(), f)) // this fails with:
// ^^^^^^^^^^^^^^^^^^^^^^^ expected type parameter `T`, found type parameter `U`
// Self::bind::<_, U, _>(f, |f| Self::map(m.clone(), f)) // this compiles
}
}
The app implementation fails with the error above, which looks to me like type inference is inferring the wrong types (and not failing to infer types).
```
error[E0308]: mismatched types
--> src\monad.rs:12:27
|
11 | fn app U>(f: Self::M, m: Self::M) -> Self::M where Self::M: Clone {
| - - found type parameter
| |
| expected type parameter
12 | Self::bind(f, |f| Self::map(m.clone(), f)) // this fails
| ^^^^^^^^^^^^^^^^^^^^^^^ expected type parameter `T`, found type parameter `U`
|
= note: expected associated type `::M`
found associated type `::M`
= note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound
= note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters
error[E0308]: mismatched types
--> src\monad.rs:12:9
|
11 | fn app U>(f: Self::M, m: Self::M) -> Self::M where Self::M: Clone {
| - - expected type parameter ---------- expected `::M` because of return type
| |
| found type parameter
12 | Self::bind(f, |f| Self::map(m.clone(), f)) // this fails
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected type parameter `U`, found type parameter `T`
|
= note: expected associated type `::M`
found associated type `::M`
= note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound
= note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters
For more information about this error, try `rustc --explain E0308`.
error: could not compile `misc` due to 2 previous errors
```
Playing around with generic associated types, I encountered what looks like a compiler bug:
The
app
implementation fails with the error above, which looks to me like type inference is inferring the wrong types (and not failing to infer types).Meta
rustc --version --verbose
:Also tried on nightly, same error.
Compiler Output
``` error[E0308]: mismatched types --> src\monad.rs:12:27 | 11 | fn app U>(f: Self::M, m: Self::M) -> Self::M where Self::M: Clone {
| - - found type parameter
| |
| expected type parameter
12 | Self::bind(f, |f| Self::map(m.clone(), f)) // this fails
| ^^^^^^^^^^^^^^^^^^^^^^^ expected type parameter `T`, found type parameter `U`
|
= note: expected associated type `::M`
found associated type `::M`
= note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound
= note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters
error[E0308]: mismatched types
--> src\monad.rs:12:9
|
11 | fn app U>(f: Self::M, m: Self::M) -> Self::M where Self::M: Clone {
| - - expected type parameter ---------- expected `::M` because of return type
| |
| found type parameter
12 | Self::bind(f, |f| Self::map(m.clone(), f)) // this fails
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected type parameter `U`, found type parameter `T`
|
= note: expected associated type `::M`
found associated type `::M`
= note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound
= note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters
For more information about this error, try `rustc --explain E0308`.
error: could not compile `misc` due to 2 previous errors
```