Misunderstanding about why a borrowed value does not live long enough


#1

I am facing an error in Rust and I do not understand why I face it.

I have a custom Reader object that owns a Vec of some IFD objects and one HashMap whose objects are references to some IFDEntry elements owned by the IFD elements inside the first vector:

// `IFD` owns some `IFDEntry`
pub struct IFD {
    pub entries: Vec<IFDEntry>,
    pub next: usize,
}

pub struct Reader<'a, R> {
    inner: R,
    order: Endian,
    ifds: Vec<IFD>, // Reader owns the list of `IFD` here
    entries_map: HashMap<Tag, &'a IFDEntry>,
}

This object defines a new function charging of filling those elements accordin to some std::io::BufRead element. At the end of this function :

let mut map = HashMap::<Tag, &IFDEntry>::new();

// ifds owns the differents values here
let ifds: Vec<IFD> = IFDIterator::new(&mut reader, order, offset as usize).collect();

// We fill the map with references
for ifd in &ifds {
    for entry in &ifd.entries {
        map.insert(entry.tag, entry);
    }
}

// Move from both `map` and `ifds` inside the `Reader`
Ok(Reader {
    inner: reader,
    order: order,
    ifds: ifds,
    entries_map: map,
})

The compiler complains that ifds does not live long enough (line 68 corresponds to the return of Ok(Reader)):

error[E0597]: `ifds` does not live long enough
  --> src/reader.rs:56:21
   |
56 |         for ifd in &ifds {
   |                     ^^^^ borrowed value does not live long enough
...
68 |     }
   |     - borrowed value only lives until here
   |
note: borrowed value must be valid for the lifetime 'a as defined on the impl at 16:6...

From my understanding, ifds is moved inside Reader at the end of the function. So why is it considered not living long enough?

The whole file can be found here: https://github.com/yageek/tiff/blob/develop/src/reader.rs


#2

Your Reader struct is self-referential (i.e. it contains references to its own other fields). Rust won’t let you do that easily. There are some ways to work around this issue (such as rental), but it’s easier to redesign the struct so that it’s not self-referential.


#4

Thanks for the information. It is quite clear now :slight_smile: