how should I read this?
It means that any implementation of Query
also implements QueryDb<'d>
for all possible values of 'd
(i.e. all lifetimes) at once. Therefore, in a generic context, the trait bound T: Query
implies T: for<'d> QueryDb<'d>
.
How is this different from
pub trait Query<'d>: Debug + Default + Sized + QueryDb<'d>
aside from that impls cannot specify 'd
?
By repeating the lifetime parameter on Query
, it means that all trait bounds T: Query
will need to be changed to T: for<'d> Query<'d>
in order to be equivalent to the version where the HRTB is in Query
itself.
This is basically a workaround for the lack of generic associated types. With generic associated types, QueryDb
would instead look like this:
pub trait QueryDb: Sized {
/// Dyn version of the associated trait for this query group.
type DynDb<'d>: ?Sized + Database + HasQueryGroup<Self::Group> + 'd;
/// Associate query group struct.
type Group: plumbing::QueryGroup<GroupStorage = Self::GroupStorage>;
/// Generated struct that contains storage for all queries in a group.
type GroupStorage;
}
Before the pull request that introduced this lifetime parameter, QueryDb
wasn't a separate trait; its members were part of Query
. The generic associated type would allow us to merge QueryDb
back into Query
.
After reading the comments on that pull request, I get the impression that this change didn't yield the expected results. The goal was to allow a bound different from the implied 'static
on associated type DynDb
, but since every Query
implements QueryDb<'d>
for all possible 'd
, that means every Query
implements QueryDb<'static>
. Therefore, in all implementations of QueryDb
, the DynDb
cannot possibly borrow anything with a lifetime shorter than 'static
, otherwise the implementation of Query
wouldn't be allowed (the bound for<'d> QueryDb<'d>
wouldn't be satisfied).