Problem with (generic) associated types and type aliases

Working on my crate to provide Lua generic sandboxes, I ran into the following problem. I would like to create to type aliases M<'a> and D<'a, 'b>, which refer to a particular machine type (which has a lifetime argument) and its associated type Datum (which is a GAT with another lifetime argument).

While I can define M<'a> as alias for LuaMachine<'a> and use <M as Machine>::Datum<'_> as type in my code, I cannot define an alias D<'a, 'b> = <M<'a> as Machine>::Datum<'b>.

Does anyone know why?

#![feature(generic_associated_types)]

use std::marker::PhantomData;

trait Machine<'a> {
    type Datum<'b>
    where
        Self: 'b;
}

#[derive(Default)]
struct LuaMachine<'a> {
    _phantom: PhantomData<fn(&'a ()) -> &'a ()>,
}

struct LuaDatum<'a, 'b> {
    _machine: &'b LuaMachine<'a>,
}

impl<'a> Machine<'a> for LuaMachine<'a> {
    type Datum<'b>
    where
        Self: 'b,
    = LuaDatum<'a, 'b>;
}

type M<'a> = LuaMachine<'a>;
// This won't work:
type D<'a, 'b> = <M<'a> as Machine>::Datum<'b>;

fn main() {
    let _m: M = Default::default();
    // But this works:
    let _d: <M as Machine>::Datum<'_> = LuaDatum { _machine: &_m };
}

(Playground)

Errors:

   Compiling playground v0.0.1 (/playground)
error[E0106]: missing lifetime specifier
  --> src/main.rs:29:18
   |
29 | type D<'a, 'b> = <M<'a> as Machine>::Datum<'b>;
   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected named lifetime parameter
   |
note: these named lifetimes are available to use
  --> src/main.rs:29:8
   |
29 | type D<'a, 'b> = <M<'a> as Machine>::Datum<'b>;
   |        ^^  ^^

For more information about this error, try `rustc --explain E0106`.
error: could not compile `playground` due to previous error

Figured it out myself:

-type D<'a, 'b> = <M<'a> as Machine>::Datum<'b>;
+type D<'a, 'b> = <M<'a> as Machine<'a>>::Datum<'b>;

(Playground)

Sorry for the noise :sweat_smile:

Apparently I ran into some confusing error messages when trying to solve the problem (only on nightly, not with stable Rust), which is why I just filed a bug report.

Darn it, what a shame, I thought I finally had a question I could answer, but then realised you already figured it out yourself!

Next time :wink:

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.