-
Notifications
You must be signed in to change notification settings - Fork 633
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Convert basic futures combinators to futures-core 0.3 #980
Conversation
@@ -11,14 +12,13 @@ use super::chain::Chain; | |||
/// | |||
/// This is created by the `Future::flatten` method. | |||
#[must_use = "futures do nothing unless polled"] | |||
pub struct Flatten<A> where A: Future, A::Item: IntoFuture { | |||
state: Chain<A, <A::Item as IntoFuture>::Future, ()>, | |||
pub struct Flatten<A> where A: Future, A::Output: Future { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we also have Result-y versions of this and FlattenStream
? Or maybe we just make impl<T> Future for Result<T, E> where T: Future
(and the same for Stream
)?
This commit includes the introduction of a `FutureResult` trait along the lines of the RFC (with some slight revisions). It tackles all the "basic" combinators, but leaves off `shared`, `select`, and `join` for the moment.
Second(R), | ||
Moved, | ||
} | ||
// safe because we never generate `Pin<F>` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice!
|
||
/// A convenience for futures that return `Result` values that includes | ||
/// a variety of adapters tailored to such futures. | ||
pub trait FutureResult { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't see the into_future
method that was brought up in the RFC thread-- are you still planning to add it? Also, I think that this should probably live in futures-core and have a FutureResultExt
here, since folks will use FutureResult
as a bound.
LGTM aside from |
/// This method is a stopgap for a compiler limitation that prevents us from | ||
/// directly inheriting from the `Future` trait; in the future it won't be | ||
/// needed. | ||
fn poll_result(self: Pin<Self>, cx: &mut task::Context) -> Poll<Result<Self::Item, Self::Error>>; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this method needed? Is it an error to leave this method off and just call poll
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This type doesn't have the Future
trait as a bound, so you can't call Future
methods directly without into_future
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(unless you know that your type is both a Future and a FutureResult)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah right of course, poll()
is returning Self::Output
, and there's no way to define that Output
is a Result
in the trait definition. 😢
I must admit, that situation is rather unfortunate... (while this doesn't fix it, separately: what about try_poll
?)
(self.inner)(cx) | ||
fn poll(mut self: Pin<Self>, cx: &mut task::Context) -> Poll<T> { | ||
// safe because we never expose a Pin<F> | ||
(unsafe { Pin::get_mut(&mut self) }.inner)(cx) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's a few places where you get mutable references to Unpin
fields (well, in this case a field that could be Unpin
without affecting it since FnMut
already implies it must be Unpin
). I have been using an additional macro when doing this to reduce the number of unsafe
patterns needed to check:
macro_rules! unpinned_field {
($pin:expr, $field:ident) => {
&mut *pinned_field!($pin, $field)
};
}
(although, I'm still also using a "safe" pinned_field
macro that relies on me not doing anything stupid in Drop
, so I'm not sure how much benefit this gives when your pinned_field
macro is unsafe to call).
I'm going to go ahead and merge this, then open a follow-up PR that tracks the new RFC proposal. |
This PR was removing If it was just forgotten I could send a PR for adding it back in the next days. |
@sdroege It certainly can be implemented, but it's pretty redundant with |
Sure, but the same could be said about many of the existing combinators too :) Would you consider adding it back if I created a PR? |
I just hit this while converting a medium size crate from 0.1 to 0.3. I'm doing so since the futures library parts are being stabilised, but I want to avoid async/await until that is stable (I'm assuming this migration will make the later one easier). Anyway, I think it would be good for to make some equivalent of |
I'd be happy to accept things like this under a separate feature (e.g. I'd prefer not to include these types in the default feature set or in the normal locations as those namespaces are already quite crowded, and I'd like to avoid suggesting combinators to users which are essentially useless post-async/await. |
That sounds good to me. I agree we don't want to recommend such combinators given async/await but purely for migrating code they seem pretty useful |
Yup! Sounds good. |
My workaround so far was to build something around |
This commit includes the introduction of a
FutureResult
trait along the lines of the RFC (with some slight revisions).It tackles all the "basic" combinators, but leaves off
shared
,select
, andjoin
for the moment.