Bound lifetime-generic vs named lifetime parameter


I ran into a clippy remark I never saw before and could not find a explaination.

I wanted to write a function using a trait bound on Deserialize for serde.

Apparently a lifetime is required as well. Ok. I learned about lifetime parameters in the Book.

But I go a suggestion "bound lifetime-generic" with a for<'a>... I never saw this in the Book.

Here below are the 2 option clippy will fix my function.

\\ Bound lifetime-generic.
fn decode<T: for<'a> Deserialize<'a>>(&self, data: Bytes) -> T

\\ Named lifetime parameter.
fn decode<'a, T: Deserialize<'a>>(&self, data: Bytes) -> T

Can someone has an explaination on the difference between the two form and what it imply ?
Also, where is learning material that talks about this ?

There is a section on higher-rank trait bounds in the nomicon. I think it describes the use-cases where you need hrtbs and their flexibility compared to named lifetimes very well.


For serde specifically, you want DeserializeOwned in this case. Note how it's effectively just an alias for the HRTB for<'de> Deserialize<'de>.

See also the serde guide to deserializer lifetimes for more discussion.

1 Like

Thank you for your responses !