Skip to content
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

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

Merged
merged 3 commits into from
Jun 11, 2018
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
39 changes: 39 additions & 0 deletions src/liballoc/boxed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -914,6 +914,45 @@ 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 Box<F> {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this impl is needed anymore-- I think people should prefer to use PInBox, as it offers the same functionality in a safer way.

fn into_raw(self) -> *mut () {
unsafe {
mem::transmute(self)
}
}

unsafe fn poll(task: *mut (), cx: &mut Context) -> Poll<()> {
let ptr: *mut F = mem::transmute(task);
let pin: PinMut<F> = PinMut::new_unchecked(&mut *ptr);
pin.poll(cx)
}

unsafe fn drop(task: *mut ()) {
let ptr: *mut F = mem::transmute(task);
let boxed = Box::from_raw(ptr);
drop(boxed)
}
}

#[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)
}
}
6 changes: 6 additions & 0 deletions src/libcore/task.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,12 @@ pub enum Poll<T> {
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