Structure moved into a closure borrows a reference from outside

Viewed 61

I'm trying to develop a pretty simple REST API in Rust, using warp and Rust Reverse Geocoder. I have the following code:

#[tokio::main]
async fn main() -> Result<()> {
    let loc = reverse_geocoder::Locations::from_memory();
    let geocoding = Arc::new(reverse_geocoder::ReverseGeocoder::new(&loc));

    let sample = warp::get()
        .and(warp::path("loc"))
        .map(move || format!("{}", geocoding.search((42.0, 42.0)).unwrap().record));

    warp::serve(sample)
        .run(([127, 0, 0, 1], 3030))
        .await;
    Ok(())
}

The compiler complains about loc being borrowed but living not long enough. I understand why (the value is dropped at the end of the main function, but still referenced in the closure), but I cannot find a way to work around this.

ReverseGeocoder borrows from the Locations field, and is not Clone, so I wrap it inside an Arc to move it properly. There is no way for me to make ReverseGeocoder own Locations.

My question is pretty simple: how can I make loc live long enough to make this code compile?

Thanks in advance!

1 Answers

The three solutions proposed in comments (once_cell, Box::leak and lazy_static) both work. Many thanks to the comments authors! I chose lazy_static at first, then I refactored and finally used another more performant crate (rgeo) which doen't need such a trick.

So the answer to my question is: the general solution here is to increase the lifetime of loc, making it 'static.

Related