The trait bound `futures::Future<Item=Arc<T>, Error=Box<Error + Send>>: Send` is not satisfied

匿名 (未验证) 提交于 2019-12-03 01:42:02

问题:

I have the following (simplified) code snippet and I'm trying to run a future on a CpuPool:

use futures::{self, Future, IntoFuture}; use std::error; use futures_cpupool::CpuPool;  pub struct Store<T: 'static + Send + Sync> {     inner: Arc<StoreInner<T, C, SerDe, P>>, }  struct StoreInner<T: 'static + Send + Sync> {     read_thread_pool: CpuPool, }  impl<T: 'static + Send + Sync> Store<T> {     pub fn get(self, obj_id: String) -> Box<Future<Item = Arc<T>, Error = Box<error::Error + Send>>>     where         T: for<'de> BinaryDeserialize<'de>,     {         let latest_version_id =             futures::future::ok(()).and_then(move |_| self.get_latest_version_id(&obj_id));         let latest_version = latest_version_id.and_then(             move |version_id| -> Box<Future<Item = Arc<T>, Error = Box<error::Error + Send>>> {                 self.get_version(&obj_id, version_id)             },         );         Box::new(self.inner.read_thread_pool.spawn(latest_version))     } } 

However, I get the following error when I try to compile.

error[E0277]: the trait bound `futures::Future<Item=std::sync::Arc<T>, Error=std::boxed::Box<std::error::Error + std::marker::Send>>: std::marker::Send` is not satisfied    --> src/store/mod.rs:181:46     | 181 |         Box::new(self.inner.read_thread_pool.spawn(Box::new(latest_version)))     |                                              ^^^^^ `futures::Future<Item=std::sync::Arc<T>, Error=std::boxed::Box<std::error::Error + std::marker::Send>>` cannot be sent between threads safely     |     = help: the trait `std::marker::Send` is not implemented for `futures::Future<Item=std::sync::Arc<T>, Error=std::boxed::Box<std::error::Error + std::marker::Send>>`     = note: required because of the requirements on the impl of `std::marker::Send` for `std::ptr::Unique<futures::Future<Item=std::sync::Arc<T>, Error=std::boxed::Box<std::error::Error + std::marker::Send>>>`     = note: required because it appears within the type `std::boxed::Box<futures::Future<Item=std::sync::Arc<T>, Error=std::boxed::Box<std::error::Error + std::marker::Send>>>`     = note: required because it appears within the type `futures::future::chain::Chain<futures::AndThen<futures::FutureResult<(), std::boxed::Box<std::error::Error + std::marker::Send>>, std::boxed::Box<futures::Future<Item=serde::export::Option<std::string::String>, Error=std::boxed::Box<std::error::Error + std::marker::Send>>>, [closure@src/store/mod.rs:177:67: 177:115 self:_, obj_id:_]>, std::boxed::Box<futures::Future<Item=std::sync::Arc<T>, Error=std::boxed::Box<std::error::Error + std::marker::Send>>>, [closure@src/store/mod.rs:178:56: 180:10 self:_, obj_id:_]>`     = note: required because it appears within the type `futures::AndThen<futures::AndThen<futures::FutureResult<(), std::boxed::Box<std::error::Error + std::marker::Send>>, std::boxed::Box<futures::Future<Item=serde::export::Option<std::string::String>, Error=std::boxed::Box<std::error::Error + std::marker::Send>>>, [closure@src/store/mod.rs:177:67: 177:115 self:_, obj_id:_]>, std::boxed::Box<futures::Future<Item=std::sync::Arc<T>, Error=std::boxed::Box<std::error::Error + std::marker::Send>>>, [closure@src/store/mod.rs:178:56: 180:10 self:_, obj_id:_]>`     = note: required because of the requirements on the impl of `std::marker::Send` for `std::ptr::Unique<futures::AndThen<futures::AndThen<futures::FutureResult<(), std::boxed::Box<std::error::Error + std::marker::Send>>, std::boxed::Box<futures::Future<Item=serde::export::Option<std::string::String>, Error=std::boxed::Box<std::error::Error + std::marker::Send>>>, [closure@src/store/mod.rs:177:67: 177:115 self:_, obj_id:_]>, std::boxed::Box<futures::Future<Item=std::sync::Arc<T>, Error=std::boxed::Box<std::error::Error + std::marker::Send>>>, [closure@src/store/mod.rs:178:56: 180:10 self:_, obj_id:_]>>`     = note: required because it appears within the type `std::boxed::Box<futures::AndThen<futures::AndThen<futures::FutureResult<(), std::boxed::Box<std::error::Error + std::marker::Send>>, std::boxed::Box<futures::Future<Item=serde::export::Option<std::string::String>, Error=std::boxed::Box<std::error::Error + std::marker::Send>>>, [closure@src/store/mod.rs:177:67: 177:115 self:_, obj_id:_]>, std::boxed::Box<futures::Future<Item=std::sync::Arc<T>, Error=std::boxed::Box<std::error::Error + std::marker::Send>>>, [closure@src/store/mod.rs:178:56: 180:10 self:_, obj_id:_]>>` 

The code looks innocent and both Item and Error in the future are Send. I have no idea why I get this error.

回答1:

I think the problem here is that the Future trait is not Send just because its Item and Error are both Send - you have to specify it explicitly.

If Future was a struct, I think the compiler could automatically derive Send, but it's not, so it can't.

I fixed up the compilation errors and added + Send to the the Future types you've defined, and it now compiles (apart from the fact there's no main function):

extern crate futures; extern crate futures_cpupool;  use futures::Future; use std::error; use std::sync::Arc; use futures_cpupool::CpuPool;  pub struct Store {     inner: Arc<StoreInner>, }  struct StoreInner {     read_thread_pool: CpuPool, }  impl Store {     pub fn get<T: 'static + Send + Sync>(         self,         obj_id: String,     ) -> Box<Future<Item = Arc<T>, Error = Box<error::Error + Send>> + Send> {         let latest_version_id =             futures::future::ok(()).and_then(move |_| self.get_latest_version_id(&obj_id));         let latest_version =             latest_version_id                 .and_then(                     move |version_id| -> Box<                         Future<Item = Arc<T>, Error = Box<error::Error + Send>> + Send,                     > { self.get_version(&obj_id, version_id) },                 );         Box::new(self.inner.read_thread_pool.spawn(latest_version))     }      pub fn get_latest_version_id(         &self,         obj_id: &String,     ) -> Box<Future<Item = String, Error = Box<error::Error + Send>> + Send> {         unimplemented!();     }      pub fn get_version<T: 'static + Send + Sync>(         &self,         obj_id: &String,         version_id: String,     ) -> Box<Future<Item = Arc<T>, Error = Box<error::Error + Send>> + Send> {         unimplemented!();     } } 

playground



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!