How to fix "borrowed value does not live long enough" issue in rust

121 views Asked by At

I have been writing a brainf*ck interpreter in rust, and was stupid enough to not use a lexer. I use recursion to tackle loops.

let mut ret = exec(i, file, tape, ptr);
i = &(ret.0);
file = &mut (ret.1);
tape = &mut (ret.2);
ptr = &(ret.3);
...
return (nw_i, (*file).to_owned(), (*tape).to_owned(), nw_ptr);

This is the function declaration:

pub fn exec(mut i: &usize, mut file: &mut Vec<u8>, mut tape: &mut Vec<i32>, mut ptr: &usize) -> (usize, Vec<u8>, Vec<i32>, usize) {

I get this error:

error[E0597]: `ret.0` does not live long enough
  --> src/lib.rs:19:10
   |
4  |     pub fn exec(mut i: &usize, mut file: &mut Vec<u8>, tape: &mut Vec<i32>, mut ptr: &usize) -> (usize, Vec<u8>, Vec<i32>, usize) {
   |                        - let's call the lifetime of this reference `'1`
...
19 |                     i = &(ret.0);
   |                     ----^^^^^^^^
   |                     |   |
   |                     |   borrowed value does not live long enough
   |                     assignment requires that `ret.0` is borrowed for `'1`
...
23 |                 }
   |     

How do i make the borrowed value live long enough for me to copy it.

Full code:

pub fn exec(
    mut i: &usize,
    mut file: &mut Vec<u8>,
    mut tape: &mut Vec<i32>,
    mut ptr: &usize,
) -> (usize, Vec<u8>, Vec<i32>, usize) {
    let char = file[*i];
    let mut nw_ptr: usize = *ptr;
    let mut nw_i: usize = *i;
    if char == ("[".as_bytes()[0]) {
        let mut j = 1;
        let mut lcl_char = file[*i];
        while tape[*ptr] != 0 {
            while j <= 0 {
                if lcl_char == ("]".as_bytes()[0]) {
                    j = j - 1;
                } else if lcl_char == ("]".as_bytes()[0]) {
                    j = j + 1;
                }
                let mut ret = exec(i, file, tape, ptr);
                i = &(ret.0);
                file = &mut (ret.1);
                tape = &mut (ret.2);
                ptr = &(ret.3);
            }
        }
    } else if char == (">".as_bytes()[0]) {
        nw_ptr = ptr + 1;
        if ptr > &(tape.len() - 1) {
            tape.push(0);
        }
    } else if char == ("<".as_bytes()[0]) {
        nw_ptr = ptr - 1;
    } else if char == (".".as_bytes()[0]) {
        let crnt = tape[*ptr];
        let out = ascii_converter::decimals_to_string(&vec![crnt.try_into().unwrap()]).unwrap();
        println!("{}", out);
    } else if char == ("+".as_bytes()[0]) {
        tape[*ptr] += 1;
    } else if char == ("-".as_bytes()[0]) {
        tape[*ptr] = tape[*ptr] - 1;
    }
    nw_i = i + 1;
    (nw_i, (*file).to_owned(), (*tape).to_owned(), nw_ptr)
}

I already tried dereferencing it as i saw people online using it:

let mut *ret = exec(i, file, tape, ptr);
i = &(ret.0);
file = &mut (ret.1);
tape = &mut (ret.2);
ptr = &(ret.3);

But this gave this error:

error: expected identifier, found `*`
  --> src/lib.rs:18:13
   |
18 |                 let mut *ret = exec(i, file, tape, ptr);
   |                         ^ expected identifier
0

There are 0 answers