Why do I need to specify lifetime while declaring T:From<&Other>

I am trying to write a function to get my app setting from postgres database and I am using tokio_postgres

my function signature is async fn get_setting<T:From<&postgres::Row>>(&self,k:T)->Result<Option<T>...>
And in the end of my execution which returns a Option I do

...
            .map(|r| r.map(|ref rw| rw.into()))

As far as my reasoning can go compiler should really not care about the lifetime of the Row (rw) since It only should exists up to the moment I call into
I am not passing it around or something So why my function does not compile and asks for the lifetime
and How can I declare lifetime for that ?

The thing is that From<&'a Other> and From<&'b Other> are different traits when 'a ≠ 'b, and you really want T to implement infinitely many traits. Luckily there's a syntax for this:

T: for<'a> From<&'a postgres::Row>

This is known as a higher-ranked trait bound, and it allows you to implement a trait for all choices of lifetime.

Wow that is something I have seen for the first time but I am trying to understand the reasoning behind this I dont really care at this example how long the &Row will be alive
Can you give me an example case where the lifetime of the Row is important ? I just need something that cant be created from a &Row any &Row

Well a type might be From<&'static postgres::Row> without being From<&'a postgres::row> for some 'a ≠ 'static.

Isnt it logical to assume unless theres an explicit lifetime parameter it contains all possible lifetimes ?

Maybe, and you can elide it in some cases, e.g. this compiles:

T: Fn(&str) -> u32,

But you can't elide it in your case.

I am just trying to understand reasoning behind that syntax and why borrow checker assumes in case of from it is a specific lifetime but not in a bare function case as you shown above it doesnt make sense at first glance for me but I am sure they had their reasons for this decision

I'm not familiar with the reasoning, but I assume it has to do with helping avoid mistakes in your generic bounds. References not in a closure like that should very often be one of the generic lifetimes on the surrounding impl block and not a for-all clause.

Thanks again saved a lot of pain :slight_smile: @alice

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.