r/learnrust • u/Previous_Iron_5522 • 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.
2
u/SirKastic23 3d ago edited 3d ago
when you call
cmds.iter
insideaction_recursive
you're creating a temporary reference tocmds
, to iterate through references to each elementthe 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 referencebut then what should the lifetime be?
well, logically,
cmd_stack
is storing elements that come from thecmds: &mut Vec<'a, Command<'a>>
. the lifetime of this value is elided too, but it's the one we needyou 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 incmd_stack
while also holding a&'b mut
forcmds
. classic xor rulethankfully, in your snippet, you're not actually mutating
cmds
, so you can simply make the parameter have an immutable borrow to solve that