Extending `for<'a>` construct

I wonder, which use cases this can have? Because the two major patterns it has are:

  • for<'a where 'a: 'l> which talk about all lifetimes that outlive a certain one (up to 'static, at which point 'a is useless)
  • for<'a where 'a: 'l, 'r: 'a> which:
    • implies 'r: 'l.
    • ???

This isn't true in general. E.g. for<'a: 'outer> Fn(&'a _) -> &'a _ is useful for the same reason fn f<'a: 'outer>(&'a _) -> &'a _) is useful. "It could require 'static" makes a bound useless if it's only used as an output lifetime, and pure output lifetimes generally want 'context: 'output. (With covariance, this is just 'context.) Input lifetimes, however, do want 'input: 'context.

Wouldn't it be much more succinct to introduce a "must be outlived by" syntax, i.e., a reversed form of 'a: 'b ? Using :< here (exact operator very much open for bikeshedding ofc.), the examples in this thread would become much shorter:

for<'c :< 's> F: Fn(&'c Connection, &'s SqlStr)
for<'a :< 'i> I::Item<'a>: Debug
impl<'b, T: for<'a :< 'b > Trait<'a>>

Probably no, because:

  • It's not more readable than the original syntax with ; here;
  • Where else would this operator be used? In most (all?) other contexts one can simply reverse the plain bound (from 'a: 'b to 'b: 'a) to get the (almost) opposoite meaning.

What functionality will fit for such operator is making it to express "it's strictly less then the other" lifetime constraint.

However, even then it has one pattern of use I can mind of:
Forbid the output lifetime to be the same as input one, this allow closures that cannot return borrows from their arguments.
See my comments in linked diesel's issue to find out when such thing may be needed.

P.S. Maybe :|?

I think this should be in its own rfc, the for<... where ...> syntax could easily be extended in this way, if it is needed (it would then also make sense to allow it everywhere else). So feel free to open a new topic for that, but for this rfc it feels out of scope.

(side note: I think it would actually be rather confusing to list them in the opposite order, because we already allow 'a: 'b, so unless the operator really speaks to me, I would be against such an addition)

Got my hands on subtyping:

Variance is the following:

  • eHRTB constructs are covariant in greater
  • and contravariant in lesser bounds.

So, for example:

  • for<'a: 'l> is a sub type of for<'a: 'l where 'r: 'a> - the former can always be cast to the latter;
  • for<'a: 'l> is a sub type of for<'a: 'r> if 'l: 'r.

I'm not sure how these would interact with lifetimes shortening.