I need help on E0521 Error

This is stripped down version of what its I am doing but I don't know how to solve it, I am not good at lifetimes but also keeps saying '1 error with E0521

There this clue with

but I don’t how to implement since I need to return a function pointer in a struct in a function

I have reached reply limit so I am going edit.

It worked like a charm also help me understand how this work and why does for<‘a> doesn’t work here and also help me understand bit more about lifetime does adding T: ‘a work or too excessive

Can you add a lifetime parameter to A?

struct A<'a, T, E> {
    pointer: fn(arg: &'a str, extra: T) -> E,
}

fn exmple<'b, 'c, E>() -> A<'b, E, ()>
where
    'b: 'c,
    E: ExactSizeIterator<Item = &'c mut Option<&'b [u8]>>,
{
    let fn_pointer = |string: &'b str, mut buffer: E| {
        //  do work
        if let Some(mutable_pointer) = buffer.next() {
            mutable_pointer.replace(string.as_bytes());
        }
    };
    A {
        pointer: fn_pointer,
    }
}


fn main() {
    let mut x = [Some("test".as_bytes())];
    
    println!("{}", std::str::from_utf8(x[0].unwrap()).unwrap());
    
    let a = exmple();
    (a.pointer)("hello", x.iter_mut());
    
    println!("{}", std::str::from_utf8(x[0].unwrap()).unwrap());
}

Playground.

1 Like

Discussing what the erorr means:

struct A<T, E> {
    pointer: for<'a> fn(arg: &'a str, extra: T) -> E,
}

T can't contain 'a because 'a doesn't exist where T is introduced (on struct A<T, E>). That 'a isn't introduced until the for<'a> ....


Let's get away from lifetimes for a minute:

trait Example<T> {
    fn to_vec<NotALifetime>(&self, arg: NotALifetime) -> Vec<T>;
}

impl Example<What> for () {
    fn to_vec<NotALifetime>(&self, arg: NotALifetime) -> Vec<What> {
        vec![arg]
    }
}

What do you put in place of What? You can't put something like String there -- you're trying to return a Vec<NotALifetime>. You can't use impl<T> Example<T> either, because calls to say <() as Example<String>>::to_vec::<u32> return a Vec<String> and not a Vec<u32>.

There's no way for T to depend on the NotALifetime parameter that was introduced later. Within a given implementation block, the T parameter must resolve to a single type, not something that can be different based on NotALifetime. Rephrased: T can't contain NotALifetime because NotALifetime doesn't exist where T is introduced.

And it works the same way in the OP, as I mentioned above: T can't contain 'a because 'a doesn't exist where T is introduced.


struct A<'a, T, E> {
    pointer: fn(arg: &'a str, extra: T) -> E,
}

fn exmple<'b, 'c, E>() -> A<'b, E, ()>
where
    'b: 'c,
    E: ExactSizeIterator<Item = &'c mut Option<&'b [u8]>>,

Now 'a and T (or in the exmple, 'b and E)[1] are introduced at the same time, so the type can contain the lifetime.

(There's a good chance you're overusing lifetimes/lifetime-carrying structs.)


  1. somewhat confusing ↩︎

1 Like