I like translating these lifetime-only GAT examples back into stable Rust. Let's see what we get.
struct MyDatum<'a> {
s: &'a str,
}
trait MaybeString<'a> {
fn get_str(&self) -> Option<&'a str>;
}
impl<'a> MaybeString<'a> for MyDatum<'a> {
fn get_str(&self) -> Option<&'a str> {
Some(self.s)
}
}
trait HasDatum<'a> {
type Datum;
}
type Datum<'a, T> = <T as HasDatum<'a>>::Datum;
trait Machine: for<'a> HasDatum<'a> {}
struct MyMachine {}
impl<'a> HasDatum<'a> for MyMachine {
type Datum = MyDatum<'a>;
}
impl Machine for MyMachine {}
fn run<M>(m: M)
where
M: Machine,
for<'a> Datum<'a, M>: MaybeString<'a>,
{
}
fn main() {
run(MyMachine {});
}
error[E0277]: the trait bound `for<'a> <_ as HasDatum<'a>>::Datum: MaybeString<'a>` is not satisf
--> src/main.rs:38:5
|
38 | run(MyMachine {});
| ^^^ the trait `for<'a> MaybeString<'a>` is not implemented for `<_ as HasDatum<'a>>::Datum`
|
note: required by a bound in `run`
--> src/main.rs:33:27
|
30 | fn run<M>(m: M)
| --- required by a bound in this
...
33 | for<'a> Datum<'a, M>: MaybeString<'a>,
| ^^^^^^^^^^^^^^^ required by this bound in `run`
wonderful, it's the same error
Let me try some things, how about implementing a helper trait for this higher-ranked bound? [short failed attempt to even reasonably do this elided…]
That's curious, the error message consistently uses _
instead of MyMachine
. Does it change if we more explicitly specify the type in the call?
fn main() {
run::<MyMachine>(MyMachine {});
}
aaaand... now it compiles. (With the GAT version, too.) Don't ask me why, feels like a bug to me that this additional information makes a difference here.