In Rust is it possible to update a struct from a thread started in one of the structs member functions?
I have an example below and the error I am getting is that you can't use self as a variable name.
use std::time::Duration;
use glib::{clone, Continue, MainContext, PRIORITY_DEFAULT};
use adw::{Application, ApplicationWindow};
use adw::prelude::*;
use std::thread;
const APP_ID: &str = "org.struct_threads";
fn main() {
let app = Application::builder().application_id(APP_ID).build();
app.connect_activate(build_ui);
app.run();
}
pub fn build_ui(app: &Application) {
let window = ApplicationWindow::builder()
.application(app)
.build();
let window_clone = window.clone();
let astruct = aStruct { aString : String::new(), aBool : false };
astruct.update_string();
while true {
println!("aString = {}", astruct.aString);
};
}
struct aStruct {
aString : String,
aBool : bool
}
impl aStruct {
pub fn update_string(&mut self) {
let (sender, receiver) = MainContext::channel(PRIORITY_DEFAULT);
thread::spawn(move || {
loop {
//let thisString = "";
if self.aString == "Value two" {
sender.send("Value one").expect("Could not send through channel");
//thisString = "Value two";
}
else {
sender.send("Value two").expect("Could not send through channel");
//thisString = "Value one";
}
//self.aStinrg = thisString.to_string();
thread::sleep(Duration::from_secs(10));
};
});
receiver.attach(
None,
clone!(#weak self => #default-return Continue(false),
move |reciever_string| {
self.aString = reciever_string;
Continue(true)
}
),
);
}
}
Error:
error: proc macro panicked
--> src/main.rs:99:13
|
99 | / clone!(#weak self => #default-return Continue(false),
100 | | move |reciever_string| {
101 | | self.aString = reciever_string;
102 | | Continue(true)
103 | | }
104 | | ),
| |____________^
|
= help: message: Can't use `self` as variable name. Try storing it in a temporary variable or rename it using `as`.
If I clone self and pass a normal variable name into the receiver I get an error stating that the struct does not implement Downgrade which doesn't seem to be implementable for booleans.
I get the same Downgrade error if I try and move this block into a non member function of the struct and call it separately.
Downgrade error:
error[E0277]: the trait bound `aStruct: Downgrade` is not satisfied
--> src/main.rs:99:13
|
99 | / clone!(#weak self_clone => #default-return Continue(false),
100 | | move |reciever_string| {
101 | | self.aString = reciever_string.to_string();
102 | | Continue(true)
103 | | }
104 | | ),
| |____________^ the trait `Downgrade` is not implemented for `aStruct`
|
= help: the following other types implement trait `Downgrade`:
&T
ATContext
AboutDialog
AboutWindow
Accessible
Action
ActionBar
ActionGroup
and 493 others
= note: required for `&aStruct` to implement `Downgrade`
= note: this error originates in the macro `clone` (in Nightly builds, run with -Z macro-backtrace for more info)
Finally if I just try and update the struct from within the thread using either self or a copy I get an error stating that the value does not live long enough. Is there way to update a struct from a thread?
Related
Returning string state in use_effect_with_deps gives error.
use std::ops::Deref;
use yew::prelude::*;
#[hook]
pub fn use_hook_test() -> String
{
let first_load = use_state(|| true);
let hash_state = use_state(|| "".to_owned());
let hash_state_clone = hash_state.clone();
use_effect_with_deps(move |_| {
if *first_load {
wasm_bindgen_futures::spawn_local(async move {
hash_state_clone.set(format!("{:?}", "Hello"));
});
first_load.set(false);
}
|| {};
}, ());
hash_state_clone.deref().clone()
}
Error:
let hash_state_clone = hash_state.clone();
| ---------------- move occurs because `hash_state_clone` has type `yew::UseStateHandle<std::string::String>`, which does not implement the `Copy` trait
14 | use_effect_with_deps(move |_| {
| -------- value moved into closure here
...
18 | hash_state_clone.set(format!("{:?}", "Hello"));
| ---------------- variable moved due to use in closure
...
27 | hash_state_clone.deref().clone()
| ^^^^^^^^^^^^^^^^^^^^^^^^ value borrowed here after move
Here is a Yew Playground based on your example with some minor changes:
added an explicit scope to isolate the use_effect_with_deps
added a second hash_state.clone() after that scope
The result is somewhat nonsensical but compiles ok.
#[hook]
pub fn use_hook_test() -> String
{
let first_load = use_state(|| true);
let hash_state = use_state(|| "".to_owned());
{
let hash_state_clone = hash_state.clone();
use_effect_with_deps(move |_| {
if *first_load {
wasm_bindgen_futures::spawn_local(async move {
hash_state_clone.set(format!("{:?}", "Hello"));
});
first_load.set(false);
}
|| {};
}, ());
}
let hash_state_clone = hash_state.clone();
hash_state_clone.deref().clone()
}
I have a bi-directional grpc stream that acts as bridge to a kafka cluster. When the stream is first initialised, I was to create the kafka consumer and start using it.
To do so, I thought of initialising an empty consumer, waiting for the first input, then assigning a created consumer to an empty one. I tried to do so by following the pattern here.
https://doc.rust-lang.org/rust-by-example/variable_bindings/declare.html
Rust is throwing a possibly-unitialized variable error, is this because it is being initialised in an asynchronous stream?
use std::pin::Pin;
use futures::{Stream, StreamExt};
use kafka::consumer::{Consumer, FetchOffset, GroupOffsetStorage};
use tonic::transport::Server;
use tonic::{Request, Response, Status};
use bridge::kafka_stream_server::{KafkaStream, KafkaStreamServer};
use bridge::{KafkaResponse, PublishRequest};
pub mod bridge {
tonic::include_proto!("bridge"); // The string specified here must match the proto package name
}
#[derive(Default)]
pub struct KafkaStreamService {}
pub fn create_kafka_consumer(topic: String) -> Consumer {
Consumer::from_hosts(vec!["localhost:9092".to_owned()])
.with_topic(topic.to_owned())
.with_fallback_offset(FetchOffset::Latest)
.with_group("".to_owned())
.with_offset_storage(GroupOffsetStorage::Kafka)
.create()
.unwrap()
}
#[tonic::async_trait]
impl KafkaStream for KafkaStreamService {
type SubscribeStream =
Pin<Box<dyn Stream<Item = Result<KafkaResponse, Status>> + Send + Sync + 'static>>;
async fn subscribe(
&self,
request: Request<tonic::Streaming<PublishRequest>>,
) -> Result<Response<Self::SubscribeStream>, Status> {
println!("Initiated stream!");
let mut stream = request.into_inner();
let mut consumer_created_flag: bool = false;
let consumer: Consumer; //declared here
let output = async_stream::try_stream! {
while let Some(publication) = stream.next().await {
let message = publication?;
let topic = message.topic.clone();
if consumer_created_flag == false {
consumer = create_kafka_consumer(topic); //error occurs here
consumer_created_flag = true;
}
let reply = bridge::KafkaResponse {
content: format!("Hello {}!", "world"),
};
yield reply.clone();
}
};
Ok(Response::new(Box::pin(output) as Self::SubscribeStream))
}
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let addr = "[::1]:50051".parse().unwrap();
println!("KafkaService listening on: {}", addr);
let svc = KafkaStreamServer::new(KafkaStreamService::default());
Server::builder().add_service(svc).serve(addr).await?;
Ok(())
}
EDIT: verbose error as requested:
error[E0381]: use of possibly-uninitialized variable: `consumer`
--> src/server.rs:42:22
|
42 | let output = async_stream::try_stream! {
| ______________________^
43 | | while let Some(publication) = stream.next().await {
44 | | let message = publication?;
45 | | let topic = message.topic.clone();
46 | | if consumer_created_flag == false {
47 | | consumer = create_kafka_consumer(topic);
| | -------- use occurs due to use in generator
... |
54 | | }
55 | | };
| |_________^ use of possibly-uninitialized `consumer`
|
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
The declare first pattern only works with basic control flow (if, match, {}, etc). It falls apart when referenced or moved into another object, like an async block or a closure:
fn main() {
let val: i32;
let func = move || {
val = 5;
};
}
error[E0594]: cannot assign to `val`, as it is not declared as mutable
--> src/main.rs:4:9
|
2 | let val: i32;
| --- help: consider changing this to be mutable: `mut val`
3 | let func = move || {
4 | val = 5;
| ^^^^^^^ cannot assign
error[E0381]: use of possibly-uninitialized variable: `val`
--> src/main.rs:3:16
|
3 | let func = move || {
| ^^^^^^^ use of possibly-uninitialized `val`
4 | val = 5;
| --- use occurs due to use in closure
A potential fix is to move its declaration into the try_stream! macro:
let output = async_stream::try_stream! {
let mut consumer_created_flag: bool = false;
let consumer: Consumer;
while let Some(publication) = stream.next().await {
let message = publication?;
let topic = message.topic.clone();
if consumer_created_flag == false {
consumer = create_kafka_consumer(topic);
consumer_created_flag = true;
}
let reply = KafkaResponse {
content: format!("Hello {}!", "world"),
};
yield reply.clone();
}
};
However, this causes a new error because you're potentially assigning to it twice (the compiler doesn't know that consumer_created_flag is guarding it):
error[E0384]: cannot assign twice to immutable variable `consumer`
--> src\lib.rs:1348:21
|
44 | let consumer: Consumer; //declared here
| -------- help: make this binding mutable: `mut consumer`
...
49 | consumer = create_kafka_consumer(topic); //error occurs here
| ^^^^^^^^ cannot assign twice to immutable variable
Fortunately a quick fix is to simply make consumer mutable. And then the only thing the compiler complains about is that it is unused, but I figure there's a reason you've put it there.
I am trying to create a small web application that will allow the user to drag and drop files onto the window. The files will then be read and their contents printed along with their filenames to the console. In addition, the files will be added to a list.
The equivalent code in JS could look something like:
window.ondragenter = (e) => {
e.preventDefault();
}
window.ondragover = (e) => {
e.preventDefault();
}
const allFiles = [];
const dropCallback = (e) => {
e.preventDefault();
const files = e.dataTransfer.files;
console.log("Got", files.length, "files");
for (let i = 0; i < files.length; i++) {
const file = files.item(i);
const fileName = file.name;
const readCallback = (text) => {
console.log(fileName, text);
allFiles.push({fileName, text});
}
file.text().then(readCallback);
}
};
window.ondrop = dropCallback;
When trying to do this in Rust, I run in to the problem that the outer closure needs to implement FnOnce to move all_files out of its scope again, which breaks the expected signature for Closure::wrap. And Closure::once will not do the trick, since I need to be able to drop multiple files onto the window.
Here is the code that I have tried without luck:
use wasm_bindgen::prelude::*;
use wasm_bindgen::JsCast;
use wasm_bindgen::JsValue;
macro_rules! console_log {
($($t:tt)*) => (web_sys::console::log_1(&JsValue::from(format_args!($($t)*).to_string())))
}
struct File {
name: String,
contents: String,
}
#[wasm_bindgen]
pub fn main() {
let mut all_files = Vec::new();
let drop_callback = Closure::wrap(Box::new(move |event: &web_sys::Event| {
event.prevent_default();
let drag_event_ref: &web_sys::DragEvent = JsCast::unchecked_from_js_ref(event);
let drag_event = drag_event_ref.clone();
match drag_event.data_transfer() {
None => {}
Some(data_transfer) => match data_transfer.files() {
None => {}
Some(files) => {
console_log!("Got {:?} files", files.length());
for i in 0..files.length() {
if let Some(file) = files.item(i) {
let name = file.name();
let read_callback = Closure::wrap(Box::new(move |text: JsValue| {
let contents = text.as_string().unwrap();
console_log!("Contents of {:?} are {:?}", name, contents);
all_files.push(File {
name,
contents
});
}) as Box<dyn FnMut(JsValue)>);
file.text().then(&read_callback);
read_callback.forget();
}
}
}
},
}
}) as Box<dyn FnMut(&web_sys::Event)>);
// These are just necessary to make sure the drop event is sent
let drag_enter = Closure::wrap(Box::new(|event: &web_sys::Event| {
event.prevent_default();
console_log!("Drag enter!");
}) as Box<dyn FnMut(&web_sys::Event)>);
let drag_over = Closure::wrap(Box::new(|event: &web_sys::Event| {
event.prevent_default();
console_log!("Drag over!");
}) as Box<dyn FnMut(&web_sys::Event)>);
// Register all the events on the window
web_sys::window()
.and_then(|win| {
win.set_ondragenter(Some(JsCast::unchecked_from_js_ref(drag_enter.as_ref())));
win.set_ondragover(Some(JsCast::unchecked_from_js_ref(drag_over.as_ref())));
win.set_ondrop(Some(JsCast::unchecked_from_js_ref(drop_callback.as_ref())));
win.document()
})
.expect("Could not find window");
// Make sure our closures outlive this function
drag_enter.forget();
drag_over.forget();
drop_callback.forget();
}
The error I get is
error[E0525]: expected a closure that implements the `FnMut` trait, but this closure only implements `FnOnce`
--> src/lib.rs:33:72
|
33 | ... let read_callback = Closure::wrap(Box::new(move |text: JsValue| {
| - ^^^^^^^^^^^^^^^^^^^^ this closure implements `FnOnce`, not `FnMut`
| _________________________________________________________|
| |
34 | | ... let contents = text.as_string().unwrap();
35 | | ... console_log!("Contents of {:?} are {:?}", name, contents);
36 | | ...
37 | | ... all_files.push(File {
38 | | ... name,
| | ---- closure is `FnOnce` because it moves the variable `name` out of its environment
39 | | ... contents
40 | | ... });
41 | | ... }) as Box<dyn FnMut(JsValue)>);
| |________________________- the requirement to implement `FnMut` derives from here
error[E0525]: expected a closure that implements the `FnMut` trait, but this closure only implements `FnOnce`
--> src/lib.rs:20:48
|
20 | let drop_callback = Closure::wrap(Box::new(move |event: &web_sys::Event| {
| - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this closure implements `FnOnce`, not `FnMut`
| _______________________________________|
| |
21 | | event.prevent_default();
22 | | let drag_event_ref: &web_sys::DragEvent = JsCast::unchecked_from_js_ref(event);
23 | | let drag_event = drag_event_ref.clone();
... |
33 | | let read_callback = Closure::wrap(Box::new(move |text: JsValue| {
| | -------------------- closure is `FnOnce` because it moves the variable `all_files` out of its environment
... |
50 | | }
51 | | }) as Box<dyn FnMut(&web_sys::Event)>);
| |______- the requirement to implement `FnMut` derives from here
error: aborting due to 2 previous errors; 1 warning emitted
For more information about this error, try `rustc --explain E0525`.
error: could not compile `hello_world`.
To learn more, run the command again with --verbose.
In a more complex example that I have not been able to reproduce in a simpler form, I get a more cryptic error, but I expect it to be related to the above:
error[E0277]: expected a `std::ops::FnMut<(&web_sys::Event,)>` closure, found `[closure#src/main.rs:621:52: 649:10 contents:std::option::Option<std::string::String>, drop_proxy:winit::event_loop::EventLoopProxy<CustomEvent>]`
--> src/main.rs:621:43
|
621 | let drop_callback = Closure::wrap(Box::new(move |event: &web_sys::Event| {
| ___________________________________________^
622 | | event.prevent_default();
623 | | let drag_event_ref: &web_sys::DragEvent = JsCast::unchecked_from_js_ref(event);
624 | | let drag_event = drag_event_ref.clone();
... |
648 | | }
649 | | }) as Box<dyn FnMut(&web_sys::Event)>);
| |__________^ expected an `FnMut<(&web_sys::Event,)>` closure, found `[closure#src/main.rs:621:52: 649:10 contents:std::option::Option<std::string::String>, drop_proxy:winit::event_loop::EventLoopProxy<CustomEvent>]`
I tried putting the all_files variable into a RefCell, but I still got a similar error. Are there any tricks or types that I can use to work around this in Rust and achieve what I want?
First, you are trying to copy name into a number of instances of File, but it must be cloned. Second, you need to properly ensure that all_files will be available whenever a closure wants to call it. One way to do so is by using a RefCell to enable multiple closures to write to it, and wrapping that in a Rc to ensure that it stays alive as long as any of the closures are alive.
Try this:
use std::{cell::RefCell, rc::Rc};
use wasm_bindgen::{prelude::*, JsCast, JsValue};
macro_rules! console_log {
($($t:tt)*) => (web_sys::console::log_1(&JsValue::from(format_args!($($t)*).to_string())))
}
struct File {
name: String,
contents: String,
}
#[wasm_bindgen]
pub fn main() {
let all_files = Rc::new(RefCell::new(Vec::new()));
let drop_callback = Closure::wrap(Box::new(move |event: &web_sys::Event| {
event.prevent_default();
let drag_event_ref: &web_sys::DragEvent = event.unchecked_ref();
let drag_event = drag_event_ref.clone();
match drag_event.data_transfer() {
None => {}
Some(data_transfer) => match data_transfer.files() {
None => {}
Some(files) => {
console_log!("Got {:?} files", files.length());
for i in 0..files.length() {
if let Some(file) = files.item(i) {
let name = file.name();
let all_files_ref = Rc::clone(&all_files);
let read_callback = Closure::wrap(Box::new(move |text: JsValue| {
let contents = text.as_string().unwrap();
console_log!("Contents of {:?} are {:?}", &name, contents);
(*all_files_ref).borrow_mut().push(File {
name: name.clone(),
contents,
});
})
as Box<dyn FnMut(JsValue)>);
file.text().then(&read_callback);
read_callback.forget();
}
}
}
},
}
}) as Box<dyn FnMut(&web_sys::Event)>);
// These are just necessary to make sure the drop event is sent
let drag_enter = Closure::wrap(Box::new(|event: &web_sys::Event| {
event.prevent_default();
console_log!("Drag enter!");
}) as Box<dyn FnMut(&web_sys::Event)>);
let drag_over = Closure::wrap(Box::new(|event: &web_sys::Event| {
event.prevent_default();
console_log!("Drag over!");
}) as Box<dyn FnMut(&web_sys::Event)>);
// Register all the events on the window
web_sys::window()
.and_then(|win| {
win.set_ondragenter(Some(drag_enter.as_ref().unchecked_ref()));
win.set_ondragover(Some(drag_over.as_ref().unchecked_ref()));
win.set_ondrop(Some(drop_callback.as_ref().unchecked_ref()));
win.document()
})
.expect("Could not find window");
// Make sure our closures outlive this function
drag_enter.forget();
drag_over.forget();
drop_callback.forget();
}
Note that if you are using multiple threads, you may want something other than RefCell (maybe Mutex instead). Also, I also changed uses of JsCast::unchecked_from_js_ref(x) to the more canonical x.as_ref().unchecked_ref().
struct OverflowError {}
fn test_unwrap() -> Result<String, OverflowError> {
let a: Result<String, u8> = Err(100);
let a: String = a.unwrap_or_else(|err| {
if err < 100 {
String::from("Ok")
} else {
// I want to return from the function (not just the closure)
// This is compile error with error:
// "the ? operator can only be used in a closure that returns Result or Option"
Err(OverflowError {})?
}
});
Ok(a)
}
error[E0277]: the `?` operator can only be used in a closure that returns `Result` or `Option` (or another type that implements `std::ops::Try`)
--> src/lib.rs:13:13
|
6 | let a: String = a.unwrap_or_else(|err| {
| ______________________________________-
7 | | if err < 100 {
8 | | String::from("Ok")
9 | | } else {
... |
13 | | Err(OverflowError {})?
| | ^^^^^^^^^^^^^^^^^^^^^^ cannot use the `?` operator in a closure that returns `std::string::String`
14 | | }
15 | | });
| |_____- this function should return `Result` or `Option` to accept `?`
|
= help: the trait `std::ops::Try` is not implemented for `std::string::String`
= note: required by `std::ops::Try::from_error`
It's the simplified version of my code. Basically inside the unwrap_or_else closure, there might be a conditional error (e.g. IOError). In such cases, I'd like to terminate the function early (using ?). But obviously it doesn't work since it is currently in a closure and the closure doesn't expect a Result type.
What's the best practice to handle this?
What you want is or_else():
struct OverflowError {}
fn test_unwrap() -> Result<String, OverflowError> {
let a: Result<String, u8> = Err(100);
let a: String = a.or_else(|err| {
if err < 100 {
Ok(String::from("Ok"))
} else {
Err(OverflowError {})
}
})?;
Ok(a)
}
Simplified:
struct OverflowError {}
fn test_unwrap() -> Result<String, OverflowError> {
Err(100).or_else(|err| {
if err < 100 {
Ok(String::from("Ok"))
} else {
Err(OverflowError {})
}
})
}
I'm fear about lifetime question. I searched and got so many relative results. I feel so different between of them, and I think it is difficult to get the spirit from them. so I decide to ask.
The error occurred when invoking dao's method inside a Hyper service's call, and I can't fix it!
extern crate futures;
extern crate hyper;
use futures::future::Future;
use futures::Stream;
use hyper::server::{Http, Request, Response, Service};
use hyper::StatusCode;
use std::net::SocketAddr;
trait Dao {
fn input_data(&self, data: &str) -> bool;
}
struct MysqlDao;
impl Dao for MysqlDao {
fn input_data(&self, data: &str) -> bool {
unimplemented!()
}
}
struct HelloWorld<'a> {
dao: &'a Dao,
}
impl<'a> Service for HelloWorld<'a> {
type Request = Request;
type Response = Response;
type Error = hyper::Error;
type Future = Box<Future<Item = Self::Response, Error = Self::Error>>;
fn call(&self, req: Request) -> Self::Future {
Box::new(req.body().concat2().map(|b| {
let rtn = self.dao.input_data(std::str::from_utf8(b.as_ref()).unwrap());
let rtn = true; // line 35 this is ok
match rtn {
true => {
return Response::new()
.with_status(StatusCode::Ok)
.with_body(String::from("ok"));
}
false => {
return Response::new()
.with_status(StatusCode::UnprocessableEntity)
.with_body(String::from("error"));
}
}
}))
}
}
fn main() {
let addr = "127.0.0.1:3000".parse().unwrap();
static DAO: MysqlDao = MysqlDao;
web_startup(&addr, &DAO);
}
fn web_startup<T: Dao>(addr: &SocketAddr, dao: &'static T) {
let server = Http::new()
.bind(addr, move || Ok(HelloWorld { dao }))
.unwrap();
server.run().unwrap();
}
playground
error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements
--> src/main.rs:33:9
|
33 | / Box::new(req.body().concat2().map(|b| {
34 | | let rtn = self.dao.input_data(std::str::from_utf8(b.as_ref()).unwrap());
35 | | let rtn = true; // line 35 this is ok
36 | | match rtn {
... |
47 | | }
48 | | }))
| |___________^
|
note: first, the lifetime cannot outlive the lifetime 'a as defined on the impl at 26:1...
--> src/main.rs:26:1
|
26 | / impl<'a> Service for HelloWorld<'a> {
27 | | type Request = Request;
28 | | type Response = Response;
29 | | type Error = hyper::Error;
... |
49 | | }
50 | | }
| |_^
note: ...so that the type `futures::Map<futures::stream::Concat2<hyper::Body>, [closure#src/main.rs:33:43: 48:10 self:&&HelloWorld<'a>]>` will meet its required lifetime bounds
--> src/main.rs:33:9
|
33 | / Box::new(req.body().concat2().map(|b| {
34 | | let rtn = self.dao.input_data(std::str::from_utf8(b.as_ref()).unwrap());
35 | | let rtn = true; // line 35 this is ok
36 | | match rtn {
... |
47 | | }
48 | | }))
| |___________^
= note: but, the lifetime must be valid for the static lifetime...
note: ...so that expression is assignable (expected std::boxed::Box<futures::Future<Error=hyper::Error, Item=hyper::Response> + 'static>, found std::boxed::Box<futures::Future<Error=hyper::Error, Item=hyper::Response>>)
--> src/main.rs:33:9
|
33 | / Box::new(req.body().concat2().map(|b| {
34 | | let rtn = self.dao.input_data(std::str::from_utf8(b.as_ref()).unwrap());
35 | | let rtn = true; // line 35 this is ok
36 | | match rtn {
... |
47 | | }
48 | | }))
| |___________^
The problem line is 34. When I replace line 34 with line 35, it works.
There's a couple of things going on with lifetimes in this code, and the error message is not that great.
The first thing is that your call function returns a trait object; that is, Box<T> where T is a trait instead of a concrete type. The default lifetime for a trait object is 'static, so Box<Future> is equivalent to Box<Future + 'static>. That explains where this line of the message comes from:
note: ...so that expression is assignable (expected std::boxed::Box<futures::Future<Error=hyper::Error, Item=hyper::Response> + 'static>, found std::boxed::Box<futures::Future<Error=hyper::Error, Item=hyper::Response>>)
In this case, you don't need your returned Future to have the 'static lifetime. Instead, you want it to have the same lifetime as self.dao, so change your type alias as follows:
type Future = Box<'a + Future<Item = Self::Response, Error = Self::Error>>;
The second thing is what variables your closure captures. Your closure refers to self, so it needs to save away that reference. This means the closure can't live past the end of the method - but you've already specified it will live as long as 'a; that is, it will live at least as long as self.dao.
Note that self in this method does not have the lifetime 'a. The instance of HelloWorld might have a shorter lifetime than the dao it has a reference to.
To fix this half of the problem, you need to allow the closure to capture only self.dao without capturing self. So you have to add
let dao = self.dao;
before the closure, and then refer to dao instead of self.dao inside the closure, so that it won't capture self. You also need to make the closure a move closure, otherwise it ends up capturing a reference to the reference, which still ties the lifetime to the scope of the function.
User red75prime, who originally posted this suggestion in a comment, made a playground with these changes. Lines 30, 33, and 34 are the important ones.
I found a way, but I think it's ugly.
Remove dao property from HelloWorld; add Sync to trait Dao; move out DAO to upper scope; invoke DAO directly from fn call.
Code : playground