3

I realize this might be a duplicate question, but I'm unable to find a satisfactory answer.

Let's say I borrow something locally and try to use it for something that has a declared lifetime:

extern crate serde;
extern crate serde_json;

use serde::Deserialize;

pub trait Item: {}

fn transform<'de, ITM: Deserialize<'de> + Item>(item_json: String) -> ITM {
    let item_typed: ITM = ::serde_json::from_str(&item_json).unwrap();
    item_typed
}

This fails with the following error:

error[E0597]: `item_json` does not live long enough
  --> src/main.rs:9:50
   |
8  | fn transform<'de, ITM: Deserialize<'de> + Item>(item_json: String) -> ITM {
   |              --- lifetime `'de` defined here
9  |     let item_typed: ITM = ::serde_json::from_str(&item_json).unwrap();
   |                           -----------------------^^^^^^^^^^-
   |                           |                      |
   |                           |                      borrowed value does not live long enough
   |                           argument requires that `item_json` is borrowed for `'de`
10 |     item_typed
11 | }
   | - `item_json` dropped here while still borrowed

Digging in, from_str wants a reference that lives as long as the lifetime declared for Deserialize

pub fn from_str<'a, T>(s: &'a str) -> Result<T>
where
    T: de::Deserialize<'a>, {
    from_trait(read::StrRead::new(s))
}

Understandable.

Ok, but how to resolve this?

Changing the signature of the function so it uses a lifetimed &str just kicks the can down the road:

fn transform_str<'de, ITM: Deserialize<'de> + Item + Clone>(item_json: &'de str) -> ITM {
    ::serde_json::from_str(item_json).unwrap()
}
fn transform<'de, ITM: Deserialize<'de> + Item>(item_json: String) -> ITM {
    transform_str(&item_json)  //error
}
marathon
  • 7,881
  • 17
  • 74
  • 137
  • 1
    I think you need ` Deserialize<'de> + Item>` instead of `<'de, ITM: Deserialize<'de> + Item>`. – Sven Marnach Feb 12 '20 at 21:32
  • 1
    See also https://stackoverflow.com/questions/60131425/trouble-with-rust-lifetime-in-generic-function. – Sven Marnach Feb 12 '20 at 21:35
  • @SvenMarnach - yup, that's it. The higher ranked bound did the trick. If you add an answer I'll mark it accepted so you can get the credit (though it doesn't look like you need the points :) – marathon Feb 12 '20 at 21:37
  • 1
    Shepmaster found an even better dupe – make sure to take a look at dtolnay's answer there. – Sven Marnach Feb 12 '20 at 21:46

0 Answers0