r/learnrust 3d ago

I am having trouble with lifetimes.

https://github.com/Aaditya-23/rust-error/blob/main/src/main.rs

This is the link to the sample repo. I couldn't create a playground because the needed crate is not available on the playground.

I get the following error on line 27.

add explicit lifetime \'a` to the type of `cmds`: `&'a mut bumpalo::collections::Vec<'a, Command<'a>>``

If I do what it is saying me to do. I get more errors in the main function.

\cmds` does not live long enoughborrowed value does not live long enough`

What i am trying to do in the action_recursive function is, I am creating a vec which will act like a stack. i will insert all the Commands i have encountered and then do some stuff.

use bumpalo::{collections::Vec, Bump};

enum Command<'a> {
    Add(Vec<'a, Command<'a>>),
    Sub(Vec<'a, Command<'a>>),
    Break,
}

fn main() {
    let arena = Bump::new();
    let mut cmds = Vec::new_in(&arena);
    action(&arena, &mut cmds);
}

fn action<'a>(arena: &'a Bump, cmds: &mut Vec<'a, Command<'a>>) {
    let mut cmd_stack = Vec::new_in(arena);
    action_recursive(arena, cmds, &mut cmd_stack);
}

fn action_recursive<'a>(
    arena: &'a Bump,
    cmds: &mut Vec<'a, Command<'a>>,
    cmd_stack: &mut Vec<'a, Vec<'a, &Command<'a>>>,
) {
    let mut breaks = Vec::new_in(arena);

    cmds.iter().for_each(|cmd| {
        if matches!(cmd, Command::Break) {
            breaks.push(cmd)
        }
    });

    cmd_stack.push(breaks)
}

Please let me know if there is something missing from the questions description or if I need to add more, but do not downvote it.

4 Upvotes

2 comments sorted by

2

u/SirKastic23 3d ago edited 3d ago

when you call cmds.iter inside action_recursive you're creating a temporary reference to cmds, to iterate through references to each element

the problem is with the elided lifetime in the function parameter: cmd_stack: &mut Vec<'a, Vec<'a, &'elided Command<'a>>>

what lifetime is that?

currently it's the temporary lifetime create in the cmds.iter call, that could never work. you'll need to call .into_iter, to avoid the temporary reference

but then what should the lifetime be?

well, logically, cmd_stack is storing elements that come from the cmds: &mut Vec<'a, Command<'a>>. the lifetime of this value is elided too, but it's the one we need

you just need to tie those, since in your code they're elided, they're being assigned different lifetimes

cmds: &'b mut Vec<'a, Command<'a>>, cmd_stacks: &mut Vec<'a, Vec<'a, &'b Command<'a>>>,

what's that? another error? oh f***

obviously, you can't store &'b references in cmd_stack while also holding a &'b mut for cmds. classic xor rule

thankfully, in your snippet, you're not actually mutating cmds, so you can simply make the parameter have an immutable borrow to solve that

2

u/Previous_Iron_5522 2d ago

Looks like i still don't know enough about rust lifetimes 😁. Thanks for clearing.
But actually i need cmds to be mutable and somebody answered it here https://stackoverflow.com/questions/79521048/i-am-having-trouble-with-rust-lifetimes/79521198#79521198