Trait for<'a> ... is not implemented for

I'm trying to get this code to compile, which requires the implementation of a trait for<'de> Handler<Value<'de>> to satisfy a bound. I think I'm implementing said trait, but I think there's some interaction with lifetimes (the for<'de> in particular) that is not being satisfied. Would appreciate some guidance :slight_smile:

It's a very annoying bug in Rust trait solver, related to type normalization issues. Basically,

given:

impl<'lt> Trait<'lt> for Implementor {
    type Assoc = Foo<'lt>;
}

then in a higher-order context (for<'lt>), Rust does not manage to normalize <Implementor as Trait<'lt>>::Assoc down to Foo<'lt>:disappointed:

1 Like

You could make call_foo generic on the lifetime, though it's unclear to me if this would hinder needed functionality elsewise.

fn call_foo<'de, A, F>(_f: F)
where
    A: Deserializable<'de> + 'static,
    F: Handler<<A as Deserializable<'de>>::Deserialize>,
{ }

Unfortunately that would break elsewhere (it's the function that's providing the lifetime 'de, not the caller) :frowning:

Ah-ha! :slight_smile: Do you know if there's a tracking issue for that?

A workaround for this is to add the required trait bounds to Assoc itself. I don't think it's always possible, but in simple cases it is.


Also, FWIW, based on @Kestrer's suggestion, I've applied the following changes, hope it helps:

- trait Handler<Event> {
-     fn call (
-         self: &'_ Self,
-         _event: Event,
-     );
- }
+ trait Handler2<'de, A : Deserializable<'de>> {
+     fn call (
+         self: &'_ Self,
+        _event: <A as Deserializable<'de>>::Deserialize,
+     );
+ }

- impl<'de, H> Handler<Value<'de>>
-     for Adapter<H>
- {
-     fn call (
-         self: &'_ Self,
-         _event: Value<'de>, // <DeserializeBorrowedValue as Deserializable<'de>>::Deserialize,
-     )
-     {}
- }
+ impl<'de, H, A> Handler2<'de, A>
+     for Adapter<H>
+ where
+     A : Deserializable<'de, Deserialize = Value<'de>>,
+ {
+     fn call (
+         self: &'_ Self,
+         _event: Value<'de>, // <DeserializeBorrowedValue as Deserializable<'de>>::Deserialize,
+     )
+     {}
+ }

  fn call_foo<A, F> (f: F)
  where
      A : for<'de> Deserializable<'de> + 'static,
-     F : for<'de> Handler<<A as Deserializable<'de>>::Deserialize>,
+     F : for<'de> Handler2<'de, A>,
  {
2 Likes

Worked like a charm! Many thanks for the help! :slight_smile:

1 Like