Skip to content

[futures] add a few blanket impls to std #51442

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

Merged
merged 3 commits into from
Jun 11, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions src/liballoc/boxed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -914,6 +914,24 @@ impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<PinBox<U>> for PinBox<T> {}
#[unstable(feature = "pin", issue = "49150")]
impl<T: ?Sized> Unpin for PinBox<T> {}

#[unstable(feature = "futures_api", issue = "50547")]
impl<'a, F: ?Sized + Future + Unpin> Future for Box<F> {
type Output = F::Output;

fn poll(mut self: PinMut<Self>, cx: &mut Context) -> Poll<Self::Output> {
PinMut::new(&mut **self).poll(cx)
}
}

#[unstable(feature = "futures_api", issue = "50547")]
impl<'a, F: ?Sized + Future> Future for PinBox<F> {
type Output = F::Output;

fn poll(mut self: PinMut<Self>, cx: &mut Context) -> Poll<Self::Output> {
self.as_pin_mut().poll(cx)
}
}

#[unstable(feature = "futures_api", issue = "50547")]
unsafe impl<F: Future<Output = ()> + Send + 'static> UnsafePoll for PinBox<F> {
fn into_raw(self) -> *mut () {
Expand Down
1 change: 1 addition & 0 deletions src/liballoc/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@
#![cfg_attr(test, feature(rand, test))]
#![feature(allocator_api)]
#![feature(allow_internal_unstable)]
#![feature(arbitrary_self_types)]
#![feature(ascii_ctype)]
#![feature(box_into_raw_non_null)]
#![feature(box_patterns)]
Expand Down
17 changes: 17 additions & 0 deletions src/libcore/future.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
//! Asynchronous values.

use mem::PinMut;
use marker::Unpin;
use task::{self, Poll};

/// A future represents an asychronous computation.
Expand Down Expand Up @@ -91,3 +92,19 @@ pub trait Future {
/// about the behavior of `poll` after a future has completed.
fn poll(self: PinMut<Self>, cx: &mut task::Context) -> Poll<Self::Output>;
}

impl<'a, F: ?Sized + Future + Unpin> Future for &'a mut F {
type Output = F::Output;

fn poll(mut self: PinMut<Self>, cx: &mut task::Context) -> Poll<Self::Output> {
F::poll(PinMut::new(&mut **self), cx)
}
}

impl<'a, F: ?Sized + Future> Future for PinMut<'a, F> {
type Output = F::Output;

fn poll(mut self: PinMut<Self>, cx: &mut task::Context) -> Poll<Self::Output> {
F::poll((*self).reborrow(), cx)
}
}
55 changes: 55 additions & 0 deletions src/libcore/task.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,61 @@ pub enum Poll<T> {
Pending,
}

impl<T> Poll<T> {
/// Change the ready value of this `Poll` with the closure provided
pub fn map<U, F>(self, f: F) -> Poll<U>
where F: FnOnce(T) -> U
{
match self {
Poll::Ready(t) => Poll::Ready(f(t)),
Poll::Pending => Poll::Pending,
}
}

/// Returns whether this is `Poll::Ready`
pub fn is_ready(&self) -> bool {
match *self {
Poll::Ready(_) => true,
Poll::Pending => false,
}
}

/// Returns whether this is `Poll::Pending`
pub fn is_pending(&self) -> bool {
!self.is_ready()
}
}

impl<T, E> Poll<Result<T, E>> {
/// Change the success value of this `Poll` with the closure provided
pub fn map_ok<U, F>(self, f: F) -> Poll<Result<U, E>>
where F: FnOnce(T) -> U
{
match self {
Poll::Ready(Ok(t)) => Poll::Ready(Ok(f(t))),
Poll::Ready(Err(e)) => Poll::Ready(Err(e)),
Poll::Pending => Poll::Pending,
}
}

/// Change the error value of this `Poll` with the closure provided
pub fn map_err<U, F>(self, f: F) -> Poll<Result<T, U>>
where F: FnOnce(E) -> U
{
match self {
Poll::Ready(Ok(t)) => Poll::Ready(Ok(t)),
Poll::Ready(Err(e)) => Poll::Ready(Err(f(e))),
Poll::Pending => Poll::Pending,
}
}
}

impl<T> From<T> for Poll<T> {
fn from(t: T) -> Poll<T> {
Poll::Ready(t)
}
}

/// A `Waker` is a handle for waking up a task by notifying its executor that it
/// is ready to be run.
///
Expand Down
1 change: 1 addition & 0 deletions src/libstd/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,7 @@
#![feature(allow_internal_unsafe)]
#![feature(allow_internal_unstable)]
#![feature(align_offset)]
#![feature(arbitrary_self_types)]
#![feature(array_error_internals)]
#![feature(ascii_ctype)]
#![feature(asm)]
Expand Down
18 changes: 18 additions & 0 deletions src/libstd/panic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,14 @@
use any::Any;
use cell::UnsafeCell;
use fmt;
use future::Future;
use mem::PinMut;
use ops::{Deref, DerefMut};
use panicking;
use ptr::{Unique, NonNull};
use rc::Rc;
use sync::{Arc, Mutex, RwLock, atomic};
use task::{self, Poll};
use thread::Result;

#[stable(feature = "panic_hooks", since = "1.10.0")]
Expand Down Expand Up @@ -315,6 +318,21 @@ impl<T: fmt::Debug> fmt::Debug for AssertUnwindSafe<T> {
}
}

#[unstable(feature = "futures_api", issue = "50547")]
impl<'a, F: Future> Future for AssertUnwindSafe<F> {
type Output = F::Output;

fn poll(mut self: PinMut<Self>, cx: &mut task::Context) -> Poll<Self::Output> {
unsafe {
let pinned_field = PinMut::new_unchecked(
&mut PinMut::get_mut(self.reborrow()).0
);

pinned_field.poll(cx)
}
}
}

/// Invokes a closure, capturing the cause of an unwinding panic if one occurs.
///
/// This function will return `Ok` with the closure's result if the closure
Expand Down