The goal: Allow bounded universal quantification;
The core problem current form has is that when inference tries to select a lifetime that'd fit for<'a> ...
bound it always ends up with 'static
, which is very limiting.
The imagined syntax:
for<%list_of_introduced_parameters; %list_of contraints> %bound
An example
for<'c; 's: 'c> F: Fn(&'c Connection,&'s SqlStr) // 's is defined in containing scope
Semantics
This construct signifies that its following bound is generic over all lifetimes that statisfy a %list_of_constraints - the bold is the difference with current form.
EDIT: Two ways of reading this:
First one is left to right: "for all 'c
, 's
shall outlive 'c
" => from this 's
= 'static
and 'c
still has no constraint of it. This way doesn't fit us.
Second way is right to left: "exists 's
=> exists a set of lifetimes A
, such that for any 'a
є A
holds the following: 's : 'a
". This is the intended semantics.
Example motivation:
Sabrina's recent post - it has great example in the very beginning:
fn print_items<I>(mut iter: I)
where
I: LendingIterator,
for<'a> I::Item<'a>: Debug, //(1)
{
while let Some(item) = iter.next() {
println!("{item:?}");
}
}
With this extension, we could write it correctly:
fn print_items<'i,I>(mut iter: I)
where
I: LendingIterator + 'i,
for<'a; 'i: 'a> I::Item<'a>: Debug, //(2)
//this means that for every lifetime that doesn't outlive the iterator,
//`Item: Debug` is true.
{
while let Some(item) = iter.next() {
println!("{item:?}");
}
}
The core point is that in this line:
print_items::<WindowsMut<'_, _, 2>>(windows_mut(&mut [1, 2, 3]));
the argument's associated lifetime isn't infered (and forced) to be 'static
by (1) and instead is only forced to be 'i
by (2).
Also, there are examples of APIs that are otherwise impossible here.