简体   繁体   中英

Rust: borrow checker in infinite loop

I'm currently building an application with a main loop. Settings are added to the struct as references to avoid boxing. The problem is, even though it seems perfectly valid, the borrow checker does not validate infinite loops. As an example, this does not compile:

struct Demo<'a> {
    data: Vec<&'a u8>,
}

impl<'a> Demo<'a> {
    fn new(data: Vec<&'a u8>) -> Self {
        Demo { data }
    }

    fn bug(mut self) -> ! {
        let a = 8;
        {
            self.data.push(&a);
            {
                self.forever();
            }
        }
    }

    fn forever(self) -> ! {
        loop {
            for dat in &self.data {
                println!("{}", dat);
            }
        }
    }
}

fn main() {
    let v = vec![&1, &1, &2, &3];
    Demo::new(v).bug();
}

My question is: how could I refactor the code above to avoid boxing the data, but still being able to use a main loop.

Within an impl<'a> Demo<'a> , all the self s have the exact same type, for the exact same 'a . But in your case, you are trying to shorten the lifetime. You can do this by rebinding self :

let mut this = self;
// the compiler infers that `this` must have a shorter lifetime:
this.data.push(&a);
this.forever();

( link to the playground )

Your other example can be fixed in a similar way .

The problem here is not so much that the borrow checker can't see the infinite loop but that you are actively lying to the compiler. When constructing the Demo<'a> in main() , the lifetime 'a is a distinct lifetime (bound to the scope of main() ). Within bug() you now push a new reference which has to last as long as the lifetime 'a has already been established to be . There is no way out of this.

You can, however, create references which are guaranteed to live at least as long as any lifetime:

fn bug(mut self) -> ! {
    let a: &'static u8 = &8;
    {
        self.data.push(a);
        {
            self.forever();
        }
    }
}

This will work, because no matter what 'a is, 'static will live at least as long.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM