Hi, I've run into a bit of a lifetime pickle - first up, here's some (slightly contrived-looking, but representative) code:
struct Opaque(usize);
struct MyStruct<'a>(Vec<&'a Opaque>);
impl<'a> MyStruct<'a> {
pub fn get_func_for_index(
&'a self,
n: usize,
) -> Option<impl for<'inner> Fn(&'inner [u8]) -> &'inner [u8] + 'a> {
let opaque: &'a Opaque = *self.0.get(n)?;
Some(move |i: &[u8]| &i[opaque.0..])
}
}
fn main() {
let o1 = Opaque(1);
let o5 = Opaque(5);
let o7 = Opaque(7);
let x = MyStruct(vec![&o1, &o5, &o7]);
let drop_five = x.get_func_for_index(1 /*Opaque(5)*/).unwrap();
let data: Vec<u8> = Vec::from(&b"testing"[..]);
assert_eq!(drop_five(&data[..]), b"ng");
}
And here's the error (rustc 1.54.0 (a178d0322 2021-07-26)
):
error[E0495]: cannot infer an appropriate lifetime for lifetime parameter in function call due to conflicting requirements
--> /tmp/lifetimes.rs:13:31
|
13 | Some(move |i: &[u8]| &i[opaque.0..])
| ^^^^^^^^^^^^^
|
note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the body at 13:14...
--> /tmp/lifetimes.rs:13:14
|
13 | Some(move |i: &[u8]| &i[opaque.0..])
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...so that reference does not outlive borrowed content
--> /tmp/lifetimes.rs:13:31
|
13 | Some(move |i: &[u8]| &i[opaque.0..])
| ^
note: but, the lifetime must be valid for the lifetime `'a` as defined on the impl at 6:6...
--> /tmp/lifetimes.rs:6:6
|
6 | impl<'a> MyStruct<'a> {
| ^^
note: ...so that return value is valid for the call
--> /tmp/lifetimes.rs:10:17
|
10 | ) -> Option<impl for<'inner> Fn(&'inner [u8]) -> &'inner [u8] + 'a> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: higher-ranked subtype error
--> /tmp/lifetimes.rs:7:5
|
7 | / pub fn get_func_for_index(
8 | | &'a self,
9 | | n: usize,
10 | | ) -> Option<impl for<'inner> Fn(&'inner [u8]) -> &'inner [u8] + 'a> {
| |_______________________________________________________________________^
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0495`.
What I'm trying to do is to return a function/closure from get_func_for_index
that in itself is valid for 'a
(because it captures &'a self
), but can receive a byte slice of any lifetime 'inner
as its argument. I think the signature of get_func_for_index
should already reflect that, but somehow the lifetimes don't add up.
Is there any way to change this code to do what I want, or is this just not a supported contraption at the moment?