Generic generics

So wait, how does Any have generic functions again?

Oh, right, TypeId.

Uh. Model this on stable? (This would require a bit more than just GGs, but...)

// ideally the commented "where" would be a thing, but if not we just mark the trait
// as unsafe and call it a day.
unsafe trait AnyA<'any_a> where Self: 'any_a /*where Self<'static>: 'static*/ {
  fn type_id(&self) -> TypeId;
}

// note that types such as &'static str are valid in T<'a> position, since 'a can just be ignored.
// so this would actually be implemented for *all* types with one or less lifetime parameters.
unsafe impl<'any_a, T<'a>> AnyA<'any_a> for T<'any_a> where T<'static>: 'static {
  fn type_id(&self) -> TypeId { TypeId::of::<T<'static>>() }
}

impl<'any_a> dyn AnyA<'any_a> {
  fn downcast_ref<T<'t_a>: AnyA<'t_a>>(&self) -> Option<&T<'any_a>> where T<'static>: 'static {
    if TypeId::of::<T<'static>>() == self.type_id() {
      // SAFETY: same as Any + because the lifetimes are literally encoded in the type system!
      unsafe { Some(&*(self as *const dyn AnyA<'t_a> as *const T<'t_a>)) } 
    } else {
      None
    }
  }
}

struct Foo<'a>(&'a str);

fn bar<'bar_a>(x: &dyn AnyA<'bar_a>) -> Option<&'bar_a str> {
  x.downcast_ref::<T<'t_a>=Foo<'t_a>>().map(|foo| foo.0)
}

let s = String::from("hello world!");
let foo = Foo(&s);
let s_str = bar(&foo as &dyn AnyA<'_>);