Calling it`self` in a future [duplicate] - rust

I have this piece of code using futures v0.1:
impl ArcService for (Box<MiddleWare<Request>>, Box<ArcService>) {
fn call(&self, req: Request, res: Response) -> Box<Future<Item = Response, Error = Error>> {
box self.0.call(req).and_then(move |req| self.1.call(req, res))
}
}
pub trait ArcService: Send + Sync {
fn call(&self, req: Request, res: Response) -> Box<Future<Item = Response, Error = Error>>;
}
pub trait MiddleWare<T>: Sync + Send {
fn call<'a>(&'a self, param: T) -> Box<Future<Item = T, Error = Error> + 'a>;
}
type MiddleWareFuture<'a, I> = Box<Future<Item = I, Error = Error> + 'a>;
impl MiddleWare<Request> for Vec<Box<MiddleWare<Request>>> {
fn call(&self, request: Request) -> MiddleWareFuture<Request> {
self.iter()
.fold(box Ok(request).into_future(), |request, middleware| {
box request.and_then(move |req| middleware.call(req))
})
}
}
pub struct ArcRouter {
routes: HashMap<Method, Box<ArcService>>,
}
// Service implementation
impl hyper::Server::Service for ArcRouter {
type Response = Response;
type Request = Request;
type Error = hyper::Error;
type Future = Box<Future<Item = Self::Response, Error = Self::Error>>;
fn call(&self, req: Request) -> Box<Future<Item = Self::Response, Error = Self::Error>> {
if let Some(routeMatch) = self.matchRoute(req.path(), req.method()) {
let mut request: ArcRequest = req.into();
request.paramsMap.insert(routeMatch.params);
let response = routeMatch.handler //handler is ArcService
.call(request, ArcResponse::new())
.map(|res| res.into());
return box response;
}
// TODO: this should be handled by a user defined 404 handler
return box Ok(Response::new().with_status(StatusCode::NotFound)).into_future();
}
}
Note the lifetime parameter on Middleware — it is used to avoid lifetime issues.
This does not compile because Box<Future<Item = Response, Error = Error>> is implicitly 'static and therefore causes lifetime issues. hyper::Server::Service requires a 'static Future
Here is an example that aptly describes my problem:
extern crate futures; // v0.1 (old)
use futures::{future, Future};
struct Example {
age: i32,
}
// trait is defined in an external crate. You can't change it's definition
trait MakeFuture {
fn make_a_future(&self) -> Box<Future<Item = i32, Error = ()>>;
}
impl MakeFuture for Example {
fn make_a_future(&self) -> Box<Future<Item = i32, Error = ()>> {
let f = future::ok(self).map(|ex| ex.age + 1);
Box::new(f)
}
}
playground link
which gives the lifetime error:
error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements
--> src/main.rs:16:28
|
16 | let f = future::ok(self).map(|ex| ex.age + 1);
| ^^^^
|
note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the method body at 15:5...
--> src/main.rs:15:5
|
15 | / fn make_a_future(&self) -> Box<Future<Item = i32, Error = ()>> {
16 | | let f = future::ok(self).map(|ex| ex.age + 1);
17 | | Box::new(f)
18 | | }
| |_____^
note: ...so that expression is assignable (expected &Example, found &Example)
--> src/main.rs:16:28
|
16 | let f = future::ok(self).map(|ex| ex.age + 1);
| ^^^^
= note: but, the lifetime must be valid for the static lifetime...
note: ...so that expression is assignable (expected std::boxed::Box<futures::Future<Item=i32, Error=()> + 'static>, found std::boxed::Box<futures::Future<Item=i32, Error=()>>)
--> src/main.rs:17:9
|
17 | Box::new(f)
| ^^^^^^^^^^^
Is there a way to get around this? I'm building with hyper::Service and using Rust v1.25.0 (nightly)

How to return a future combinator with &self
You return a future that refers to self like this:
use futures::future::{self, FutureResult}; // 0.1.28
struct Example {
age: i32,
}
impl Example {
fn make_a_future(&self) -> FutureResult<&Example, ()> {
future::ok(self)
}
}
As discussed in the Tokio documentation on returning futures, the easiest stable solution to returning a complicated future is a impl Trait. Note that we assign an explicit lifetime to self and use that in the returned value (via + 'a):
use futures::{future, Future}; // 0.1.28
struct Example {
age: i32,
}
impl Example {
fn make_a_future<'a>(&'a self) -> impl Future<Item = i32, Error = ()> + 'a {
future::ok(self).map(|ex| ex.age + 1)
}
}
Your real question is "how can I lie to the compiler and attempt to introduce memory unsafety into my program?"
Box<SomeTrait + 'static> (or Box<SomeTrait> by itself) means that the trait object must not contain any references that do not last for the entire program. By definition, your Example struct has a shorter lifetime than that.
This has nothing to do with futures. This is a fundamental Rust concept.
There are many questions that ask the same thing in regards to threads, which have similar restrictions. A small sampling:
Lifetime of variables passed to a new thread
How do I use static lifetimes with threads?
The compiler suggests I add a 'static lifetime because the parameter type may not live long enough, but I don't think that's what I want
Lifetime troubles sharing references between threads
Like in those cases, you are attempting to share a reference to a variable with something that may exist after the variable is destroyed. Languages such as C or C++ would let you do this, only to have your program crash at a seemingly random point in time in the future when that variable is accessed after being freed. The crash is the good case, by the way; information leaks or code execution is also possible.
Like the case for threads, you have to ensure that this doesn't happen. The easiest way is to move the variable into the future, not sharing it at all. Another option is to use something like an Arc around your variable, clone the Arc and hand the clone to the future.

Related

Rust Dummy Future Value?

I have a use case where I need to specify a dummy Future to make a type concrete. The use case is I have a struct which takes a generic parameter, which is a Future:
let thing = Thing<Fut>::some_method().await?;
some_method is a method on Thing which does not use the Fut at all, but the compiler complains because of the compiler limitations such that the type can't be inferred and is necessary because of the async block.
Since I need a concrete sized thing for Fut, I was hoping there was something in futures_util that I could use. Right now, this is my very bad approach:
use futures::Future;
use std::pin::Pin;
struct Thing<Fut>
where
for<'b> Fut: Future<Output = ()> + Send + 'b,
{
callback: dyn Fn() -> Fut + Send + Sync,
}
impl<Fut> Thing<Fut> where for<'b> Fut: Future<Output = ()> + Send + 'b {
async fn some_method(a: i32) -> Result<(), Box<dyn std::error::Error>> {
println!("I am some_method with value {}", a);
Ok(())
}
}
struct Dummy {
}
impl Future for Dummy {
type Output = ();
fn poll(
self: Pin<&mut Self>,
cx: &mut std::task::Context<'_>,
) -> std::task::Poll<Self::Output> {
unimplemented!()
}
}
#[tokio::main]
async fn main() {
// this fails
Thing::some_method(3).await.unwrap();
// this works
//Thing::<Dummy>::some_method(3).await.unwrap();
}
Is there something I can leverage here to make such a dummy value available?
Here is a minimal playground example:
playground link
The error:
error[E0698]: type inside `async` block must be known in this context
--> src/main.rs:33:5
|
33 | Thing::some_method(3).await.unwrap();
| ^^^^^^^^^^^^^^^^^^ cannot infer type for type parameter `Fut`
|
note: the type is part of the `async` block because of this `await`
--> src/main.rs:33:26
|
33 | Thing::some_method(3).await.unwrap();
| ^^^^^^
If you uncomment the success line, it will remove the error.
You can use std::future::Ready (or probably Pending alternatively). This is the type returned by the std::future::ready function.
use std::future::Ready;
type Dummy = Ready<()>;
#[tokio::main]
async fn main() {
Thing::<Dummy>::some_method(3).await.unwrap();
}
But if this function has no dependence on Fut, then I'd question why it's an associated function on Thing in the first place. Maybe it should be a free-standing function instead.

hyper : implementation of `FnOnce` is not general enough

I'm trying to refactor code by moving the hyper server out of main and allow the struct function to accept a function as below:
// main.rs
#[tokio::main]
async fn main() {
let listener = Listener::new(String::from("127.0.0.1"), String::from("3000"));
listener.start(request_handler);
}
async fn request_handler(req: Request<Body>) -> ConfigResult<Response<Body>> {
match req.method() {
&Method::GET => get(req.body()),
_ => Ok(Response::builder()
.status(StatusCode::NOT_FOUND)
.body("NOT FOUND".into())
.unwrap())
}
}
// lib.rs
pub type ConfigError = Box<dyn Error + Send + Sync>;
pub type ConfigResult<T> = Result<T, Box<dyn Error + Send + Sync>>;
#[derive(Debug, Clone)]
pub struct Listener(pub SocketAddr);
impl<'a> Listener {
pub fn new(addr: String, port:String) -> Self {
let ip = IpAddr::from_str(addr.as_str()).unwrap();
let address = SocketAddr::new(ip, port.parse::<u16>().unwrap());
Listener(address)
}
pub async fn start<F>(&'a self, request_handler: F ) -> ConfigResult<()>
where F: Fn(Request<Body>) -> ConfigResult<Response<Body>> + Sync + 'a
{
let mut service_closure = move |req| {
async {
request_handler(req)
}
};
let mut make_service_closure = move |_| {
async {
Ok::<_, ConfigError>(service_fn(&service_closure))
}
};
let service = make_service_fn(make_service_closure);
let server = Server::bind(&self.0).serve(service);
server.await?;
Ok(())
}
}
Im getting the error:
error: implementation of `FnOnce` is not general enough
--> src/config/server.rs:36:15
|
36 | server.await?;
| ^^^^^^ implementation of `FnOnce` is not general enough
|
= note: closure with signature `fn(&'2 AddrStream) -> impl Future<Output = Result<hyper::service::util::ServiceFn<&[closure#src/config/serva.rs:23:35: 27:10], Body>, Box<dyn StdError + Send + Sync>>>` must implement `FnOnce<(&'1 AddrStream,)>`, for any lifetime `'1`...
= note: ...but it actually implements `FnOnce<(&'2 AddrStream,)>`, for some specific lifetime `'2`
Looking at the error above, my conclusion is its a lifetime error, where let make_service_closure = move |_| {...} requires lifetime of '1 but when i try let make_service_closure = move | a: &'a AddrStream| {...} i get lifetime mismatch error
expected type `for<'r> FnMut<(&'r AddrStream,)>`
found type `FnMut<(&'a AddrStream,)>`
plus the error implementation of FnOnce is not general enough. Please help understand which lifetime should i use for the hyper service function and why is FnOnce is not general enough.

Pass a Struct<'a>::method as a `for<'a> Fn(&Foo<'a>)` for use in a closure

In my tests I had a helper function that runs a given method on differently configured objects, with a simplified version looking like this:
fn run_method<F>(f: F)
where
F: Fn(&Foo),
{
let to_test = vec![0i32];
to_test
.iter()
.map(|param| {
let foo = Foo(*param);
f(&foo);
})
.for_each(drop);
}
// run_method(Foo::run);
This worked fine until I added references to the tested struct, making it "lifetime-annotated" (for lack of a proper term, I mean Foo<'a>).
Now I get an error indicating, I think, that Rust doesn't want to accept a Foo::method as a function that can be used with any given lifetime (i.e. F: for<'a> Fn(&Foo<'a>)), as required by the closure:
error[E0631]: type mismatch in function arguments
--> src/main.rs:54:5
|
3 | fn run(&self) {
| ------------- found signature of `for<'r> fn(&'r Foo<'_>) -> _`
...
54 | run_method(Foo::run);
| ^^^^^^^^^^ expected signature of `for<'r, 's> fn(&'r Foo<'s>) -> _`
|
note: required by `run_method`
--> src/main.rs:44:1
|
44 | fn run_method<F>(f: F) where F: Fn(&Foo) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0271]: type mismatch resolving `for<'r, 's> <for<'t0> fn(&'t0 Foo<'_>) {Foo::<'_>::run} as std::ops::FnOnce<(&'r Foo<'s>,)>>::Output == ()`
--> src/main.rs:54:5
|
54 | run_method(Foo::run);
| ^^^^^^^^^^ expected bound lifetime parameter, found concrete lifetime
|
note: required by `run_method`
--> src/main.rs:44:1
|
44 | fn run_method<F>(f: F) where F: Fn(&Foo) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
I can work around the problem by avoiding closures (though I don't really understand how 'a gets constrained to be local to run_method - isn't the lifetime parameter supposed to be chosen by the caller?):
fn run_method<'a, F>(f: F)
where
F: Fn(&Foo<'a>),
{
let to_test = vec![&0i32];
for param in to_test {
let foo = Foo(param);
f(&foo);
}
}
Can I fix this without rewriting? If not - is there a reason why this shouldn't work?
Complete code:
struct Foo<'a>(&'a i32);
impl<'a> Foo<'a> {
fn run(&self) {
println!("Hello {}", self.0);
}
}
fn run_method<F>(f: F)
where
F: Fn(&Foo),
{
//same as F: for<'a> Fn(&Foo<'a>) {
let to_test = vec![0i32];
to_test
.iter()
.map(|param| {
let foo = Foo(param);
f(&foo);
})
.for_each(drop);
}
fn main() {
run_method(Foo::run);
}
// This works:
// fn run_method<'a, F>(f: F)
// where
// F: Fn(&Foo<'a>),
// {
// let to_test = vec![&0i32];
// for param in to_test {
// let foo = Foo(param);
// f(&foo);
// }
// }
// The lifetime-less version:
// struct Foo(i32);
// impl Foo {
// fn run(&self) {
// println!("Hello {}", self.0);
// }
// }
//
// fn run_parser_method<F>(f: F)
// where
// F: Fn(&Foo),
// {
// let to_test = vec![0i32];
// to_test
// .iter()
// .map(|param| {
// let foo = Foo(*param);
// f(&foo);
// })
// .for_each(drop);
// }
//
// fn main() {
// run_parser_method(Foo::run);
// }
playground
An overview of other questions about the same error code:
Expected bound lifetime parameter, found concrete lifetime is about mismatch between trait definition and implementation (trait { fn handle<'a>(); } vs impl<'a> { fn handle() {} })
Function references: expected bound lifetime parameter , found concrete lifetime [E0271] as well as Expected bound lifetime parameter, found concrete lifetime [E0271] is about a closure |args| {...} without explicit type annotations (|args: &[&str]|) not being accepted as a Fn(&[&str]) -> (); the answers don't explain why (the latter hints that it was not implemented in 2015)
Type mismatch "bound lifetime parameter" vs "concrete lifetime" when filling a collection from a closure is again about a closure without explicit type annotations specifying that it accepts a reference (let mut insert = |k| seq.insert(k); (1..10).cycle().take_while(insert)), which masks a more useful "borrowed data cannot be stored outside of its closure" error.
I can work around the problem by avoiding closures (though I don't really understand how 'a gets constrained to be local to run_method - isn't the lifetime parameter supposed to be chosen by the caller?)
It is. But when you rewrite it without closures, you have also put the reference inside the vec! invocation, so it is no longer constructed at runtime. Instead, the compiler can infer that to_test has type Vec<&'static i32>, and as 'static outlives any caller-chosen lifetime, there's no violation.
This fails to compile as you expect:
let to_test = vec![0i32];
for param in to_test.iter() {
let foo = Foo(param);
f(&foo);
}
is there a reason why this shouldn't work?
Yes, because the type of run is constrained by the type of Foo. More specifically, you have a lifetime decided by the caller (implicitly, in the type for Foo), so you have to construct a Foo of that lifetime to invoke the given run reference on it.
Can I fix this without rewriting?
That depends.
If all your test values are literals, you can make 'static references.
If you're able and willing to rewrite run, it's possible to make it unconstrained by the type of Foo
impl<'a> Foo<'a> {
fn run<'s>(_self: &Foo<'s>) {
println!("Hello {}", _self.0);
}
}
But then it doesn't need to go in an impl block at all.
I think the solution provided in the comments is your best bet, because given that you don't care about your concrete Foo<'a> type, there's no need to give the method reference for that type.

"explicit lifetime required" when using a reference variable in a boxed future

I'm trying to use a struct created in main() and pass it on to a function that returns a boxed Future. However, I run into lifetime and borrowing issues and can't seem to resolve this cleanly.
Here is my struct and functions:
extern crate futures; // 0.1.21
extern crate tokio_core; // 0.1.17
use futures::{future::ok, Future};
pub struct SomeStruct {
some_val: u32,
}
impl SomeStruct {
pub fn do_something(&self, value: u32) -> u32 {
// Do some work
return self.some_val + value;
}
}
fn main() {
let core = tokio_core::reactor::Core::new().unwrap();
let my_struct = SomeStruct { some_val: 10 };
let future = get_future(&my_struct);
core.run(future);
let future2 = get_future(&my_struct);
core.run(future2);
}
fn get_future(some_struct: &SomeStruct) -> Box<Future<Item = u32, Error = ()>> {
let fut = ok(20).and_then(|val| {
let result = some_struct.do_something(val);
ok(result)
});
Box::new(fut)
}
On compiling, the following error occurs:
error[E0621]: explicit lifetime required in the type of `some_struct`
--> src/main.rs:33:5
|
28 | fn get_future(some_struct: &SomeStruct) -> Box<Future<Item = u32, Error = ()>> {
| ----------- consider changing the type of `some_struct` to `&'static SomeStruct`
...
33 | Box::new(fut)
| ^^^^^^^^^^^^^ lifetime `'static` required
I suppose the error occurs because SomeStruct is used in the Future and might be used outside of main()s scope, hence the compiler asks me to change the lifetime to 'static. Here is what I tried so far (unsuccessfully):
Changing the lifetime to 'static as suggested by the compiler, which creates borrowing issues in main().
Moving val by adding ok(20).and_then(move |val| { as suggested by the compiler, which creates issues in the second invocation of get_future().
Use the lazy_static crate to explicitly initialize SomeStruct as static (as suggested here), however I run into macro errors when trying that.
The whole example can be found here. I have omitted some details to create an minimal example. The issues occur using tokio-core and futures = "0.1". Migrating to version "0.2" is not an option unfortunately, due to a dependency of another library.
Returning a boxed trait object has a 'static bound by default. Do as the compiler suggests and provide an explicit lifetime, but not 'static:
fn get_future<'a>(some_struct: &'a SomeStruct) -> Box<dyn Future<Item = u32, Error = ()> + 'a> {
let fut = future::ok(20).and_then(move |val| {
let result = some_struct.do_something(val);
future::ok(result)
});
Box::new(fut)
}
You also have to use move to transfer ownership of some_struct to the closure and change core to be mutable. You should also handle potential errors resulting from core.run.
For the example provided, you could also return impl Future:
fn get_future<'a>(some_struct: &'a SomeStruct) -> impl Future<Item = u32, Error = ()> +'a {
future::ok(20).and_then(move |val| {
let result = some_struct.do_something(val);
future::ok(result)
})
}
See also:
How do I return a boxed closure from a method that has a reference to the struct?
Why is adding a lifetime to a trait with the plus operator (Iterator<Item = &Foo> + 'a) needed?
What is the correct way to return an Iterator (or any other trait)?

How to return a future combinator with `&self`

I have this piece of code using futures v0.1:
impl ArcService for (Box<MiddleWare<Request>>, Box<ArcService>) {
fn call(&self, req: Request, res: Response) -> Box<Future<Item = Response, Error = Error>> {
box self.0.call(req).and_then(move |req| self.1.call(req, res))
}
}
pub trait ArcService: Send + Sync {
fn call(&self, req: Request, res: Response) -> Box<Future<Item = Response, Error = Error>>;
}
pub trait MiddleWare<T>: Sync + Send {
fn call<'a>(&'a self, param: T) -> Box<Future<Item = T, Error = Error> + 'a>;
}
type MiddleWareFuture<'a, I> = Box<Future<Item = I, Error = Error> + 'a>;
impl MiddleWare<Request> for Vec<Box<MiddleWare<Request>>> {
fn call(&self, request: Request) -> MiddleWareFuture<Request> {
self.iter()
.fold(box Ok(request).into_future(), |request, middleware| {
box request.and_then(move |req| middleware.call(req))
})
}
}
pub struct ArcRouter {
routes: HashMap<Method, Box<ArcService>>,
}
// Service implementation
impl hyper::Server::Service for ArcRouter {
type Response = Response;
type Request = Request;
type Error = hyper::Error;
type Future = Box<Future<Item = Self::Response, Error = Self::Error>>;
fn call(&self, req: Request) -> Box<Future<Item = Self::Response, Error = Self::Error>> {
if let Some(routeMatch) = self.matchRoute(req.path(), req.method()) {
let mut request: ArcRequest = req.into();
request.paramsMap.insert(routeMatch.params);
let response = routeMatch.handler //handler is ArcService
.call(request, ArcResponse::new())
.map(|res| res.into());
return box response;
}
// TODO: this should be handled by a user defined 404 handler
return box Ok(Response::new().with_status(StatusCode::NotFound)).into_future();
}
}
Note the lifetime parameter on Middleware — it is used to avoid lifetime issues.
This does not compile because Box<Future<Item = Response, Error = Error>> is implicitly 'static and therefore causes lifetime issues. hyper::Server::Service requires a 'static Future
Here is an example that aptly describes my problem:
extern crate futures; // v0.1 (old)
use futures::{future, Future};
struct Example {
age: i32,
}
// trait is defined in an external crate. You can't change it's definition
trait MakeFuture {
fn make_a_future(&self) -> Box<Future<Item = i32, Error = ()>>;
}
impl MakeFuture for Example {
fn make_a_future(&self) -> Box<Future<Item = i32, Error = ()>> {
let f = future::ok(self).map(|ex| ex.age + 1);
Box::new(f)
}
}
playground link
which gives the lifetime error:
error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements
--> src/main.rs:16:28
|
16 | let f = future::ok(self).map(|ex| ex.age + 1);
| ^^^^
|
note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the method body at 15:5...
--> src/main.rs:15:5
|
15 | / fn make_a_future(&self) -> Box<Future<Item = i32, Error = ()>> {
16 | | let f = future::ok(self).map(|ex| ex.age + 1);
17 | | Box::new(f)
18 | | }
| |_____^
note: ...so that expression is assignable (expected &Example, found &Example)
--> src/main.rs:16:28
|
16 | let f = future::ok(self).map(|ex| ex.age + 1);
| ^^^^
= note: but, the lifetime must be valid for the static lifetime...
note: ...so that expression is assignable (expected std::boxed::Box<futures::Future<Item=i32, Error=()> + 'static>, found std::boxed::Box<futures::Future<Item=i32, Error=()>>)
--> src/main.rs:17:9
|
17 | Box::new(f)
| ^^^^^^^^^^^
Is there a way to get around this? I'm building with hyper::Service and using Rust v1.25.0 (nightly)
How to return a future combinator with &self
You return a future that refers to self like this:
use futures::future::{self, FutureResult}; // 0.1.28
struct Example {
age: i32,
}
impl Example {
fn make_a_future(&self) -> FutureResult<&Example, ()> {
future::ok(self)
}
}
As discussed in the Tokio documentation on returning futures, the easiest stable solution to returning a complicated future is a impl Trait. Note that we assign an explicit lifetime to self and use that in the returned value (via + 'a):
use futures::{future, Future}; // 0.1.28
struct Example {
age: i32,
}
impl Example {
fn make_a_future<'a>(&'a self) -> impl Future<Item = i32, Error = ()> + 'a {
future::ok(self).map(|ex| ex.age + 1)
}
}
Your real question is "how can I lie to the compiler and attempt to introduce memory unsafety into my program?"
Box<SomeTrait + 'static> (or Box<SomeTrait> by itself) means that the trait object must not contain any references that do not last for the entire program. By definition, your Example struct has a shorter lifetime than that.
This has nothing to do with futures. This is a fundamental Rust concept.
There are many questions that ask the same thing in regards to threads, which have similar restrictions. A small sampling:
Lifetime of variables passed to a new thread
How do I use static lifetimes with threads?
The compiler suggests I add a 'static lifetime because the parameter type may not live long enough, but I don't think that's what I want
Lifetime troubles sharing references between threads
Like in those cases, you are attempting to share a reference to a variable with something that may exist after the variable is destroyed. Languages such as C or C++ would let you do this, only to have your program crash at a seemingly random point in time in the future when that variable is accessed after being freed. The crash is the good case, by the way; information leaks or code execution is also possible.
Like the case for threads, you have to ensure that this doesn't happen. The easiest way is to move the variable into the future, not sharing it at all. Another option is to use something like an Arc around your variable, clone the Arc and hand the clone to the future.

Resources