Is there any way to represent the extraction function being allowed but not required to return a reference into the T? If you were adding that function today, would you do it this way or bake the idea of returning a self-reference into the conversion function (F: for<'a> FnMut(&'a T) -> &'a K) and tell computed comparisons to use sort_by?
Unfortunately not, since you'd get lease for the elements for the whole duration of the sort call that way, and since they are borrowed, they can't move (can't be sorted).
Since sort by key is just sugar for sort_by, were really not losing much because of this missing.
Doesn't lifetime subtyping already do this? If it allows you to return something with 'a lifetime, then you will implicitly be allowed to return 'static.
which requires the returned value to be a reference. For lifetime subtyping to handle it and get the "proper" declaration I think the best declaration would probably be something like
fn sort_by_key<K, F>(&self, mut f: F)
where
F: for<'a> FnMut(&'a T) -> K
where K: 'a;
K: Ord,
Nice, it looks like we can turn that into a useful(?) implementation of sort_by_key. Though I gave up getting it to work for closures, they were not callable normally under the IsValid bound.
error: lifetime may not live long enough
--> src/main.rs:43:13
|
36 | |element: &String| -> &str {
| - ---- return type of closure is &'2 str
| |
| let's call the lifetime of this reference `'1`
...
43 | &element[bounds]
| ^^^^^^^^^^^^^^^^ returning this value requires that `'1` must outlive `'2`
It seems that the lifetime elision rules are different for closures? Or something weird is going on here. Why is '2 === '1 not implied here?
This is because rust infers the wrong lifetimes for the closure, it infers fn(&'a &str) -> &'a str instead of fn(&&'a str) -> &str. Creating a function with the correct signature removes the warning.