Borrowed value does not live long enough when using functions with lifetime specifier

(Also on stackoverflow: rust - Borrowed value does not live long enough when using functions with lifetime specifier - Stack Overflow)
I am fairly unfamiliar with Rust lifetime. Here is the code I wrote:

pub fn from_reader<'de, T, R>(reader: &'de mut R) -> Result<T>
where
    T: Deserialize<'de>,
    R: Read,
{
    let mut reader = BufReader::new(reader);
    from_buf_reader(&mut reader)
}

pub fn from_buf_reader<'de, T, R>(reader: &'de mut R) -> Result<T>
where
    T: Deserialize<'de>,
    R: BufRead,
{
    //...
}

I got the following error:

error[E0597]: `reader` does not live long enough
  --> src/de.rs:34:21
   |
28 | pub fn from_reader<'de, T, R>(reader: &'de mut R) -> Result<T>
   |                    --- lifetime `'de` defined here
...
34 |     from_buf_reader(&mut reader)
   |     ----------------^^^^^^^^^^^-
   |     |               |
   |     |               borrowed value does not live long enough
   |     argument requires that `reader` is borrowed for `'de`
35 | }
   | - `reader` dropped here while still borrowed

From my understanding, the newly created reader needs to have 'de lifetime, which is not possible because 'de begins before this function is even called. Is this the correct interpretation?

Is there a way around this issue without directly taking ownership of the parameter?

So as to your understanding of the error message

this is correct.


As to solving your problem: it doesn’t make any sense to tie the 'de lifetime parameter to the lifetime of the &mut R reference. Actually, caring about the lifetime of Deserialize doesn’t really make any sense at all here since you’re not going to be able to use zero-copy deserialization on a reader anyways.

You might want to try to read this page from the serde docs:
Deserializer lifetimes · Serde

Anyways, the best approach here then is probably to switch to using the DeserializeOwned trait.

- pub fn from_reader<T, R>(reader: &'de mut R) -> Result<T>
+ pub fn from_reader<T, R>(reader: &mut R) -> Result<T>
  where
-     T: Deserialize<'de>,
+     T: DeserializeOwned,
      R: Read,
  {
      let mut reader = BufReader::new(reader);
      from_buf_reader(&mut reader)
  }

- pub fn from_buf_reader<T, R>(reader: &'de mut R) -> Result<T>
+ pub fn from_buf_reader<T, R>(reader: &mut R) -> Result<T>
  where
-     T: Deserialize<'de>,
+     T: DeserializeOwned,
      R: BufRead,
  {
      //...
  }

See if with this change from_buf_reader this still works for you and if it solves your problem.

3 Likes