- Feature Name:
extended_hrtb
- Start Date: 2022-05-08
- RFC PR: rust-lang/rfcs#0000
- Rust Issue: rust-lang/rust#0000
This feature add a way to bound universal quantification of higher ranked trait bounds (HRTB) to allow more APIs.
The HRTB construct has allowed us to talk about closures that are generic over lifetimes. However, initially this has not included a way to restrict these generic lifetimes, thus, in practice, it turned out to be useful in only a handful of scenarios.
Currently, the existing higher-rank trait bounds functionality allows generalizing bounds that outlive a given lifetime, but do not allow generalizing bounds that are outlived by other lifetimes, the goal of the proposal is to allow such generalizations.
The new syntax looks like this:
for<'a where 'b: 'a>
- it's called extended HRTB
This construct reads as "for all lifetimes that 'b
outlives".
This form of HRTB allow you to make the following interface:
(The example is taken from Sabrina's post, see Prior Art)
fn print_items<'i,I>(mut iter: I)
where
I: LendingIterator + 'i,
for<'a where 'i: 'a> I::Item<'a>: Debug,
//this means that for every lifetime that doesn't outlive the iterator, `Item: Debug` is true.
{
while let Some(item) = iter.next() {
println!("{item:?}");
}
}
This function is otherwise very limited as it can only take 'static
data - see prior art.
The difference between extended HRTB and what we'd have with plain form is that:
If we use the plain HRTB, then inference would require the associated lifetime of I
in the example to be outlive all lifetimes <=> be 'static
.
Instead, with this feature, we add the bound restricting the part "all lifetimes" to "lifetimes lesser than 'i
", so the inference no longer requires the associated lifetime of I
to be 'static
but just 'i
.
Syntax:
for<$list_of_lifetimes where $list_of_lifetime_bounds>
Any bound put inside of $list_of_lifetime_bounds
have to refer to at least one lifetime introduced within $list_of_lifetimes
. This way, we keep bounds of parent context separate from bounds of extended HRTB.
In eHRTB, we have two lifetimes: lesser and greater bounds.
Variance is the following:
- eHRTB constructs are covariant in greater
- and contravariant in lesser bounds.
For example:
for<'a: 'l where 'r1: 'a> T
is a sub type offor<'a: 'l where 'r2: 'a> T
if'r1: 'r2
;for<'a: 'l> T
is a sub type offor<'a: 'r> T
if'l: 'r
.
We may not do this if we want another form for this capability.
There were other variants of syntax:
for<'a> where<'i: 'a> ...
for<'a> where 'i: 'a ...
for<'a; 'i: 'a> ... //the original one
They were not chosen because of:
- Result of poll;
- Most likely ambiguos;
- Less clear.
Internals thread - prior discussion and bikesheding.
None
I don't believe we want HRTB to carry even more than proposed here, at least for now.