Following is my code( I made a playground for it), if can not compile.

``````struct DataSave {
n: Vec<i32>,
m: Vec<f32>,
}

trait PlusNumber {
type A<'a>: where Self: 'a;
type B;
fn a_func_existed<'c, 'a>(&'c self, v: &'a DataSave) -> Self::A<'a>;
fn plus_number<'c, 'a>(&'c self, v: Self::A<'a>) -> Self::B;
}

struct PlusOne;
struct PlusTwo;

impl PlusNumber for PlusOne {
type A<'a> = &'a Vec<i32>;
type B = Vec<i32>;

fn a_func_existed<'c, 'a>(&'c self, v: &'a DataSave) -> Self::A<'a> {
&v.n
}

fn plus_number<'c, 'a>(&'c self, v: Self::A<'a>) -> Self::B {
v.iter().map(|x| x + 1).collect()
}
}

struct DataFunc<'a, T, N> {
data: &'a Vec<T>,
func: N
}

trait SelectCalc {
fn select_calc<'a, 'b, 'k, T, N, K>(&self, v: &DataFunc<'b, T, N>) -> Vec<K>
where
T: Clone + 'k,
N: PlusNumber<A<'a> = &'k Vec<T>, B = Vec<K>> + 'static,
;
}

fn select_calc<'a, 'b, 'k, T, N, K>(&self, v: &DataFunc<'b, T, N>) -> Vec<K>
where
T: Clone + 'k,
N: PlusNumber<A<'a> = &'k Vec<T>, B = Vec<K>> + 'static,
{
let mut res = Vec::new();
let data_part = v.data[..10].to_vec();
let res_part1 = &mut v.func.plus_number(&data_part);
res.append(res_part1);
res
}
}
``````

Here is the compile error:

``````[E0597] Error: `data_part` does not live long enough
โญโ[command_6:1:1]
โ
4 โ     fn select_calc<'a, 'b, 'k, T, N, K>(&self, v: &DataFunc<'b, T, N>) -> Vec<K>
ยท                            โโฌ
ยท                             โฐโโ lifetime `'k` defined here
ยท
11 โ         let res_part1 = &mut v.func.plus_number(&data_part);
ยท                              โโโโโโโโโโโโโโโโฌโโโโโโโโโฌโโโโโ
ยท                                             โฐโโโโโโโโโโโโโโโโ argument requires that `data_part` is borrowed for `'k`
ยท                                                      โ
ยท                                                      โฐโโโโโโโ borrowed value does not live long enough
ยท
14 โ     }
ยท     โฌ
ยท     โฐโโ `data_part` dropped here while still borrowed
โโโโโฏ
``````

How can I make it right?

You are using more than 2 explicit lifetimes; this is likely a sign of abuse, way too convoluted, and almost always unnecessary (on a single function at least).

By removing all the excessive lifetimes, one can see more clearly that the compiler complains about the local variable not satisfying some arbitrary lifetime parameter.

Your misunderstanding is that you think you can use a generic lifetime parameter here. You can't, because generic parameters are chosen by the caller. Here, there's no way a caller can specify a short enough lifetime that can be satisfied by a reference to a local variable inside the callee. That's impossible by definition. (The callee necessarily has a shorter lifetime/narrower scope than its caller.)

What you want instead is to tell the compiler that the given type must work for all lifetimes, which is a HRTB (since it's another level of universal quantification up from a simple generic parameter). Accordingly, the annotation `for<'b> PlusNumber<A<'b> = &'b Vec<T>, โฆ>` compiles as expected.

5 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.