(Experienced C, C++, Python programmer. New to rust, still trying to wrap my head around lifetimes, borrows, moves, and the ways references are different from C pointers)
I'm trying to represent a list of locations, where each location has a size and offset:
struct FreeLoc {
    size: u64,
    offset: u64
}
These live in and are owned by a Vec in another struct. For lookup performance, I want to maintain this list in two separate orderings -- one sorted by size, and the other by offset. I have the owning Vec (free), and two Vec<&FreeLoc> to store references to the objects in the owning Vec, sorted appropriately:
struct FreeList<'a> {
    free: Vec<FreeLoc>,
    by_size: Vec<&'a FreeLoc>,
    by_offset: Vec<&'a FreeLoc>
}
impl<'a> FreeList<'a> {
    pub fn new(size: u64) -> Self {
        let mut s = Self {
            free: vec![ FreeLoc { size: size, offset: 0 }],
            by_size: Vec::new(),
            by_offset: Vec::new()
        };
        s.by_size.push(&s.free[0]);
        s.by_offset.push(&s.free[0]);
        s
    }
}
I get the following build errors:
error[E0515]: cannot return value referencing local data `s.free`
  --> src/freelist/freelist.rs:31:9
   |
28 |         s.by_size.push(&s.free[0]);
   |                         ------ `s.free` is borrowed here
...
31 |         s
   |         ^ returns a value referencing data owned by the current function
error[E0505]: cannot move out of `s` because it is borrowed
  --> src/freelist/freelist.rs:31:9
   |
21 | impl<'a> VecFreeList<'a> {
   |      -- lifetime `'a` defined here
...
28 |         s.by_size.push(&s.free[0]);
   |                         ------ borrow of `s.free` occurs here
...
31 |         s
   |         ^
   |         |
   |         move out of `s` occurs here
   |         returning this value requires that `s.free` is borrowed for `'a`
error[E0515]: cannot return value referencing local data `s.free`
  --> src/freelist/freelist.rs:31:9
   |
29 |         s.by_offset.push(&s.free[0]);
   |                           ------ `s.free` is borrowed here
30 |
31 |         s
   |         ^ returns a value referencing data owned by the current function
There are several questions here:
- Is the error with line 31 a side effect of sbeing allocated on the stack? When ::new returns, the physical memory location of s moves, and therefore the references in s.by_size and s.by_offset are no longer valid?
31 |         s
   |         ^ returns a value referencing data owned by the current function
- What is the "right" way to get around this problem? Allocate the FreeLocs on the heap using Box? And therefore theFreeListturns into:
struct FreeList<'a> {
    free: Vec<Box<FreeLoc>>,
    by_size: Vec<&'a Box<FreeLoc>>,
    by_offset: Vec<&'a Box<FreeLoc>>
}
- Is this really the right way to handle heap allocation in rust? Seems super clunky.
