.boxed() has to be hard coded to either be Send + 'static or not. Where as calling Box::new is able to infer which it should be. Given this, when a user tries to call boxed() but the future is not Send, a compilation error happens. I've noticed that this often causes confusion and it seems to be one of the more common questions that is asked in the gitter channel.
I propose to remove boxed in favor of explicitly calling Box::new.
Agreed we should consider, but I don't think this should block the 0.2 release, we can deprecate and message at any time.
I think the problem becomes a problem when a function needs to return some _futures_. Say I have a function which could do async job A, B or C, and return one of them. Using a Box to wrap the future is the only way I could see as a function must return only ONE implementation of trait in Rust.
As the tuturial suggests using .boxed(), it is very easy for a newbie (like me) to box futures here and there. Encountering Send problem later.
And it's not so obvious as a fact that tokio-core is running on a single thread. The idea of "Oh I don't need Send, maybe there is a way to remove that bound" is not a thought that could easily come to my head.
Here's an example of someone getting tripped up by this: https://github.com/hyperium/hyper/issues/1082
I once had an issue when the combined future type was too big and rustc refused to compile it with some strange "the size of ... cannot be statically determined" message. Boxing in the middle fixed it, and I really liked being able to put .to_box(); putting Box::new(..) around it would have made it much more unreadable. (to_box() is a local trait extension which doesn't require Send).
So I'd like to point out that if you don't provide boxing methods others will probably extend it locally anyway.
Maybe some of the current work on impl (default, specializiation?) would allow to provide a trait extending future based on whether the future was Send, Sync and automatically using an appropriate box type?
As an alternative I'd really like to see a boxed_unsync() method :)
I've also hit this issue and as a Rust newbie it took me a really lot of time to understand and solve the problem. The errors about the Send trait are absolutely misleading when it's otherwise not required for your use case and the solution is to simply ignore the builtin boxed() function and use Box::new().
I noticed MaidSafe uses an extension trait with an into_box method that works as a non-Send version of boxed. Maybe instead of removing boxed, it could be split into two methods, into_box and into_sendable_box (names to be bikeshed, of course) to provide both versions and make the distinction more clear.
I think to me it's relatively clear at this point that we'll be removing this method. If there's pretty solid agreement on that point we could go ahead and add a #[deprecated] tag to it, and maybe recommend, if it's used, to have a local extension trait and/or local method.
I've opened a PR for their removal in https://github.com/alexcrichton/futures-rs/pull/556
Most helpful comment
I think the problem becomes a problem when a function needs to return some _futures_. Say I have a function which could do async job A, B or C, and return one of them. Using a
Boxto wrap the future is the only way I could see as a function must return only ONE implementation of trait in Rust.As the tuturial suggests using
.boxed(), it is very easy for a newbie (like me) to box futures here and there. EncounteringSendproblem later.And it's not so obvious as a fact that
tokio-coreis running on a single thread. The idea of "Oh I don't needSend, maybe there is a way to remove that bound" is not a thought that could easily come to my head.