Naming a lifetime local to a called function

⚓ Rust    📅 2025-07-11    👤 surdeus    👁️ 3      

surdeus

As shown below, I would like to pass a closure Fn(T) to a function generic over T, which will deserialize a T from stack-local data, possibly sharing structure, and then call the closure on it. But when T is a borrow like &str, I can't work out how to name the lifetime. Thank you for any tips!

use serde::*;
use std::fmt::Debug;

// Obtain some input, deserialize it, and then
// call the given function on it.
fn map_deserialized<T, F>(f: F)
where
    T: for<'de> Deserialize<'de> + Debug,
    F: Fn(T),
{
    // Obtain some data and store it locally
    let data: String = r#"   "hello"   "#.to_owned();

    // Decode it to `x`, sharing where possible
    let x: T = serde_json::from_str(&data).unwrap();

    f(x);
}

pub fn main() {
    map_deserialized(|s: String| println!("string: {:?}", s));

    // map_deserialized(|s: &str| println!("str: {:?}", s));
    //
    // error: implementation of `serde::Deserialize` is not general enough
    //   note: `&str` must implement `serde::Deserialize<'0>`, for any lifetime `'0`...
    //   note: ...but `&str` actually implements `serde::Deserialize<'1>`, for some specific lifetime `'1`
}

// And this signature doesn't work at all:
//     error[E0597]: `data` does not live long enough
//
// fn map_deserialized_wrong<'de, T, F>(f: F)
// where
//     T: Deserialize<'de> + Debug,
//     F: Fn(T)

(Playground)

2 posts - 2 participants

Read full topic

🏷️ rust_feed