Cannot infer appropriate lifetime for serde Serializer code

I've been trying to write a serde Serializer, but running into problems. See this playground:

https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=ca0a7c49bbdc988fd0c497586b758078

I cannot change the traits (they're part of serde), only the impls. So how do I fix the serialize_field() implementation so that the correct lifetime can be inferred? Conceptually the lifetimes should not be an issue, but I have not been able to figure out how to convey this to the compiler.

Let Rust do the hard work for you :wink:

impl Serializer for &'_ mut MySerializer<'_> {}

impl SerializeStruct for &'_ mut MySerializer<'_> {
    fn serialize_field<T: Serialize>(&mut self, _key: &'static str, value: &T) -> Result<(), ()> {
        value.serialize(&mut **self)
    }
} 

The problem is, that &'a mut and MySerializer<'a> have the same lifetime. You can introduce a second one 'b and then then it's something like this:

impl<'a, 'b> Serializer for &'a mut MySerializer<'b> {}
impl<'a, 'b> SerializeStruct for &'a mut MySerializer<'b> { ... }
1 Like

Basically what happened is that reborrowing with &mut **self you create a borrow of the original reference, possibly shortening the lifetime. In order to be able to pass it to serialize, you want the lifetime to be very short.

However the reborrow doesn't change the second lifetime in the type. The generic lifetime 'a can be shortened, but you'd have to manually shorten every field.

The thing is, your functions are written in a way that reuses the lifetime for both positions. This requires them to be the same lifetime, so since the generic lifetime is unchanged, the reference lifetime cannot be shortened.

1 Like

Awesome, thank you!