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
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>
…
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)
Ah-ha! 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.
https://github.com/rust-lang/rust/issues/76407
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>,
{
Worked like a charm! Many thanks for the help!
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.