Lifetime management with Scratchpad Crate using Rust


#1

Hi there,

We’re running into some issues with lifetimes in Rust and need your help.

Conceptually, we’re looking to create multiple memory pools, with each pool individually acting as a stack. Within each stack, we allocate objects of varying sizes and free them up in a stack-like fashion. We also want to be able to allocate memory from the stacks in an ad-hoc fashion, and not iteratively visit each stack in order.

We found the crate called Scratchpad (https://docs.rs/scratchpad/1.0.0/scratchpad/index.html), which will do the stack allocation and freeing.

The problem is that an allocation is statically bound to the lifetime of the Marker and the Marker is statically bound to the lifetime of the Scratchpad. While we obviously don’t want allocations to outlive the corresponding allocated memory, the lifetime check makes it difficult (or perhaps impossible?) to put the scratchpad, markers and allocations in one object. In particular we see the error Error: Borrowed value does not live long enough

In the simple example shown, this can be worked around by including the Scratchpad by reference, but I’m not sure that this can be generalized to the use case that we want where multiple markers and allocations are stored together.

Here is the sample code (does not compile):

extern crate scratchpad;
use scratchpad::{Scratchpad,MarkerFront};

#[derive(Debug)]
struct Stuff<'sp:'a,'a> {
                scratchpad: Scratchpad<&'sp mut[u8], &'sp mut[usize]>,
                marker: Option<MarkerFront<'a, &'sp mut[u8], &'sp mut[usize]>>,
}

fn main() {
    let pool0:&mut[u8] = &mut[0;1024];
    let pool1:&mut[usize] = &mut[0;64];

    let sp = Scratchpad::new(pool0,pool1);
    let mut stuff = Stuff{scratchpad: sp, marker:None};
    stuff.marker = Some(stuff.scratchpad.mark_front().unwrap());
                println!("{:?}", stuff);
    stuff.marker = None;
                println!("{:?}", stuff);
}

Sample code again (does compile):

extern crate scratchpad;
use scratchpad::{Scratchpad,MarkerFront};

#[derive(Debug)]
struct Stuff<'sp:'a,'a> {
                scratchpad: &'sp Scratchpad<&'sp mut[u8], &'sp mut[usize]>,
                marker: Option<MarkerFront<'a, &'sp mut[u8], &'sp mut[usize]>>,
}

fn main() {
    let pool0:&mut[u8] = &mut[0;1024];
    let pool1:&mut[usize] = &mut[0;64];

    let sp = Scratchpad::new(pool0,pool1);
    let mut stuff = Stuff{scratchpad: &sp, marker:None};
    stuff.marker = Some(stuff.scratchpad.mark_front().unwrap());
                println!("{:?}", stuff);
    stuff.marker = None;
                println!("{:?}", stuff);
}