Skip to content

Commit

Permalink
Stabilize futures_api
Browse files Browse the repository at this point in the history
  • Loading branch information
cramertj committed Apr 23, 2019
1 parent e617025 commit 3f966dc
Show file tree
Hide file tree
Showing 32 changed files with 86 additions and 66 deletions.
2 changes: 1 addition & 1 deletion src/liballoc/boxed.rs
Expand Up @@ -911,7 +911,7 @@ impl<G: ?Sized + Generator> Generator for Pin<Box<G>> {
}
}

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

Expand Down
1 change: 0 additions & 1 deletion src/liballoc/lib.rs
Expand Up @@ -85,7 +85,6 @@
#![feature(fmt_internals)]
#![feature(fn_traits)]
#![feature(fundamental)]
#![feature(futures_api)]
#![feature(lang_items)]
#![feature(libc)]
#![feature(needs_allocator)]
Expand Down
9 changes: 6 additions & 3 deletions src/libcore/future/future.rs
@@ -1,6 +1,4 @@
#![unstable(feature = "futures_api",
reason = "futures in libcore are unstable",
issue = "50547")]
#![stable(feature = "futures_api", since = "1.36.0")]

use crate::marker::Unpin;
use crate::ops;
Expand All @@ -26,8 +24,10 @@ use crate::task::{Context, Poll};
/// `await!` the value.
#[doc(spotlight)]
#[must_use = "futures do nothing unless polled"]
#[stable(feature = "futures_api", since = "1.36.0")]
pub trait Future {
/// The type of value produced on completion.
#[stable(feature = "futures_api", since = "1.36.0")]
type Output;

/// Attempt to resolve the future to a final value, registering
Expand Down Expand Up @@ -92,9 +92,11 @@ pub trait Future {
/// [`Context`]: ../task/struct.Context.html
/// [`Waker`]: ../task/struct.Waker.html
/// [`Waker::wake`]: ../task/struct.Waker.html#method.wake
#[stable(feature = "futures_api", since = "1.36.0")]
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output>;
}

#[stable(feature = "futures_api", since = "1.36.0")]
impl<F: ?Sized + Future + Unpin> Future for &mut F {
type Output = F::Output;

Expand All @@ -103,6 +105,7 @@ impl<F: ?Sized + Future + Unpin> Future for &mut F {
}
}

#[stable(feature = "futures_api", since = "1.36.0")]
impl<P> Future for Pin<P>
where
P: Unpin + ops::DerefMut,
Expand Down
5 changes: 2 additions & 3 deletions src/libcore/future/mod.rs
@@ -1,8 +1,7 @@
#![unstable(feature = "futures_api",
reason = "futures in libcore are unstable",
issue = "50547")]
#![stable(feature = "futures_api", since = "1.36.0")]

//! Asynchronous values.

mod future;
#[stable(feature = "futures_api", since = "1.36.0")]
pub use self::future::Future;
6 changes: 3 additions & 3 deletions src/libcore/task/mod.rs
@@ -1,11 +1,11 @@
#![unstable(feature = "futures_api",
reason = "futures in libcore are unstable",
issue = "50547")]
#![stable(feature = "futures_api", since = "1.36.0")]

//! Types and Traits for working with asynchronous tasks.

mod poll;
#[stable(feature = "futures_api", since = "1.36.0")]
pub use self::poll::Poll;

mod wake;
#[stable(feature = "futures_api", since = "1.36.0")]
pub use self::wake::{Context, Waker, RawWaker, RawWakerVTable};
20 changes: 16 additions & 4 deletions src/libcore/task/poll.rs
@@ -1,6 +1,4 @@
#![unstable(feature = "futures_api",
reason = "futures in libcore are unstable",
issue = "50547")]
#![stable(feature = "futures_api", since = "1.36.0")]

use crate::ops::Try;
use crate::result::Result;
Expand All @@ -9,20 +7,27 @@ use crate::result::Result;
/// scheduled to receive a wakeup instead.
#[must_use = "this `Poll` may be a `Pending` variant, which should be handled"]
#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
#[stable(feature = "futures_api", since = "1.36.0")]
pub enum Poll<T> {
/// Represents that a value is immediately ready.
Ready(T),
#[stable(feature = "futures_api", since = "1.36.0")]
Ready(
#[stable(feature = "futures_api", since = "1.36.0")]
T
),

/// Represents that a value is not ready yet.
///
/// When a function returns `Pending`, the function *must* also
/// ensure that the current task is scheduled to be awoken when
/// progress can be made.
#[stable(feature = "futures_api", since = "1.36.0")]
Pending,
}

impl<T> Poll<T> {
/// Changes the ready value of this `Poll` with the closure provided.
#[stable(feature = "futures_api", since = "1.36.0")]
pub fn map<U, F>(self, f: F) -> Poll<U>
where F: FnOnce(T) -> U
{
Expand All @@ -34,6 +39,7 @@ impl<T> Poll<T> {

/// Returns `true` if this is `Poll::Ready`
#[inline]
#[stable(feature = "futures_api", since = "1.36.0")]
pub fn is_ready(&self) -> bool {
match *self {
Poll::Ready(_) => true,
Expand All @@ -43,13 +49,15 @@ impl<T> Poll<T> {

/// Returns `true` if this is `Poll::Pending`
#[inline]
#[stable(feature = "futures_api", since = "1.36.0")]
pub fn is_pending(&self) -> bool {
!self.is_ready()
}
}

impl<T, E> Poll<Result<T, E>> {
/// Changes the success value of this `Poll` with the closure provided.
#[stable(feature = "futures_api", since = "1.36.0")]
pub fn map_ok<U, F>(self, f: F) -> Poll<Result<U, E>>
where F: FnOnce(T) -> U
{
Expand All @@ -61,6 +69,7 @@ impl<T, E> Poll<Result<T, E>> {
}

/// Changes the error value of this `Poll` with the closure provided.
#[stable(feature = "futures_api", since = "1.36.0")]
pub fn map_err<U, F>(self, f: F) -> Poll<Result<T, U>>
where F: FnOnce(E) -> U
{
Expand All @@ -72,12 +81,14 @@ impl<T, E> Poll<Result<T, E>> {
}
}

#[stable(feature = "futures_api", since = "1.36.0")]
impl<T> From<T> for Poll<T> {
fn from(t: T) -> Poll<T> {
Poll::Ready(t)
}
}

#[stable(feature = "futures_api", since = "1.36.0")]
impl<T, E> Try for Poll<Result<T, E>> {
type Ok = Poll<T>;
type Error = E;
Expand All @@ -102,6 +113,7 @@ impl<T, E> Try for Poll<Result<T, E>> {
}
}

#[stable(feature = "futures_api", since = "1.36.0")]
impl<T, E> Try for Poll<Option<Result<T, E>>> {
type Ok = Poll<Option<T>>;
type Error = E;
Expand Down
36 changes: 27 additions & 9 deletions src/libcore/task/wake.rs
@@ -1,6 +1,4 @@
#![unstable(feature = "futures_api",
reason = "futures in libcore are unstable",
issue = "50547")]
#![stable(feature = "futures_api", since = "1.36.0")]

use crate::fmt;
use crate::marker::{PhantomData, Unpin};
Expand All @@ -13,6 +11,7 @@ use crate::marker::{PhantomData, Unpin};
/// It consists of a data pointer and a [virtual function pointer table (vtable)][vtable] that
/// customizes the behavior of the `RawWaker`.
#[derive(PartialEq, Debug)]
#[stable(feature = "futures_api", since = "1.36.0")]
pub struct RawWaker {
/// A data pointer, which can be used to store arbitrary data as required
/// by the executor. This could be e.g. a type-erased pointer to an `Arc`
Expand All @@ -37,9 +36,7 @@ impl RawWaker {
/// from a `RawWaker`. For each operation on the `Waker`, the associated
/// function in the `vtable` of the underlying `RawWaker` will be called.
#[rustc_promotable]
#[unstable(feature = "futures_api",
reason = "futures in libcore are unstable",
issue = "50547")]
#[stable(feature = "futures_api", since = "1.36.0")]
pub const fn new(data: *const (), vtable: &'static RawWakerVTable) -> RawWaker {
RawWaker {
data,
Expand All @@ -58,6 +55,7 @@ impl RawWaker {
/// pointer of a properly constructed [`RawWaker`] object from inside the
/// [`RawWaker`] implementation. Calling one of the contained functions using
/// any other `data` pointer will cause undefined behavior.
#[stable(feature = "futures_api", since = "1.36.0")]
#[derive(PartialEq, Copy, Clone, Debug)]
pub struct RawWakerVTable {
/// This function will be called when the [`RawWaker`] gets cloned, e.g. when
Expand Down Expand Up @@ -131,9 +129,14 @@ impl RawWakerVTable {
/// resources that are associated with this instance of a [`RawWaker`] and
/// associated task.
#[rustc_promotable]
#[unstable(feature = "futures_api",
reason = "futures in libcore are unstable",
issue = "50547")]
#[cfg_attr(stage0, unstable(feature = "futures_api_const_fn_ptr", issue = "50547"))]
#[cfg_attr(not(stage0), stable(feature = "futures_api", since = "1.36.0"))]
// `rustc_allow_const_fn_ptr` is a hack that should not be used anywhere else
// without first consulting with T-Lang.
//
// FIXME: remove whenever we have a stable way to accept fn pointers from const fn
// (see https://github.com/rust-rfcs/const-eval/issues/19#issuecomment-472799062)
#[cfg_attr(not(stage0), rustc_allow_const_fn_ptr)]
pub const fn new(
clone: unsafe fn(*const ()) -> RawWaker,
wake: unsafe fn(*const ()),
Expand All @@ -153,6 +156,7 @@ impl RawWakerVTable {
///
/// Currently, `Context` only serves to provide access to a `&Waker`
/// which can be used to wake the current task.
#[stable(feature = "futures_api", since = "1.36.0")]
pub struct Context<'a> {
waker: &'a Waker,
// Ensure we future-proof against variance changes by forcing
Expand All @@ -164,6 +168,7 @@ pub struct Context<'a> {

impl<'a> Context<'a> {
/// Create a new `Context` from a `&Waker`.
#[stable(feature = "futures_api", since = "1.36.0")]
#[inline]
pub fn from_waker(waker: &'a Waker) -> Self {
Context {
Expand All @@ -173,12 +178,14 @@ impl<'a> Context<'a> {
}

/// Returns a reference to the `Waker` for the current task.
#[stable(feature = "futures_api", since = "1.36.0")]
#[inline]
pub fn waker(&self) -> &'a Waker {
&self.waker
}
}

#[stable(feature = "futures_api", since = "1.36.0")]
impl fmt::Debug for Context<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Context")
Expand All @@ -195,17 +202,22 @@ impl fmt::Debug for Context<'_> {
///
/// Implements [`Clone`], [`Send`], and [`Sync`].
#[repr(transparent)]
#[stable(feature = "futures_api", since = "1.36.0")]
pub struct Waker {
waker: RawWaker,
}

#[stable(feature = "futures_api", since = "1.36.0")]
impl Unpin for Waker {}
#[stable(feature = "futures_api", since = "1.36.0")]
unsafe impl Send for Waker {}
#[stable(feature = "futures_api", since = "1.36.0")]
unsafe impl Sync for Waker {}

impl Waker {
/// Wake up the task associated with this `Waker`.
#[inline]
#[stable(feature = "futures_api", since = "1.36.0")]
pub fn wake(self) {
// The actual wakeup call is delegated through a virtual function call
// to the implementation which is defined by the executor.
Expand All @@ -227,6 +239,7 @@ impl Waker {
/// where an owned `Waker` is available. This method should be preferred to
/// calling `waker.clone().wake()`.
#[inline]
#[stable(feature = "futures_api", since = "1.36.0")]
pub fn wake_by_ref(&self) {
// The actual wakeup call is delegated through a virtual function call
// to the implementation which is defined by the executor.
Expand All @@ -243,6 +256,7 @@ impl Waker {
///
/// This function is primarily used for optimization purposes.
#[inline]
#[stable(feature = "futures_api", since = "1.36.0")]
pub fn will_wake(&self, other: &Waker) -> bool {
self.waker == other.waker
}
Expand All @@ -253,13 +267,15 @@ impl Waker {
/// in [`RawWaker`]'s and [`RawWakerVTable`]'s documentation is not upheld.
/// Therefore this method is unsafe.
#[inline]
#[stable(feature = "futures_api", since = "1.36.0")]
pub unsafe fn from_raw(waker: RawWaker) -> Waker {
Waker {
waker,
}
}
}

#[stable(feature = "futures_api", since = "1.36.0")]
impl Clone for Waker {
#[inline]
fn clone(&self) -> Self {
Expand All @@ -272,6 +288,7 @@ impl Clone for Waker {
}
}

#[stable(feature = "futures_api", since = "1.36.0")]
impl Drop for Waker {
#[inline]
fn drop(&mut self) {
Expand All @@ -282,6 +299,7 @@ impl Drop for Waker {
}
}

#[stable(feature = "futures_api", since = "1.36.0")]
impl fmt::Debug for Waker {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let vtable_ptr = self.waker.vtable as *const RawWakerVTable;
Expand Down
1 change: 1 addition & 0 deletions src/libstd/future.rs
Expand Up @@ -9,6 +9,7 @@ use core::task::{Context, Poll};
use core::ops::{Drop, Generator, GeneratorState};

#[doc(inline)]
#[stable(feature = "futures_api", since = "1.36.0")]
pub use core::future::*;

/// Wrap a generator in a future.
Expand Down
10 changes: 3 additions & 7 deletions src/libstd/lib.rs
Expand Up @@ -263,7 +263,6 @@
#![feature(fixed_size_array)]
#![feature(fn_traits)]
#![feature(fnbox)]
#![feature(futures_api)]
#![feature(generator_trait)]
#![feature(hash_raw_entry)]
#![feature(hashmap_internals)]
Expand Down Expand Up @@ -458,18 +457,15 @@ pub mod process;
pub mod sync;
pub mod time;

#[unstable(feature = "futures_api",
reason = "futures in libcore are unstable",
issue = "50547")]
#[stable(feature = "futures_api", since = "1.36.0")]
pub mod task {
//! Types and Traits for working with asynchronous tasks.
#[doc(inline)]
#[stable(feature = "futures_api", since = "1.36.0")]
pub use core::task::*;
}

#[unstable(feature = "futures_api",
reason = "futures in libcore are unstable",
issue = "50547")]
#[stable(feature = "futures_api", since = "1.36.0")]
pub mod future;

// Platform-abstraction modules
Expand Down
2 changes: 1 addition & 1 deletion src/libstd/panic.rs
Expand Up @@ -319,7 +319,7 @@ impl<T: fmt::Debug> fmt::Debug for AssertUnwindSafe<T> {
}
}

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

Expand Down
2 changes: 1 addition & 1 deletion src/test/compile-fail/must_use-in-stdlib-traits.rs
@@ -1,5 +1,5 @@
#![deny(unused_must_use)]
#![feature(arbitrary_self_types, futures_api)]
#![feature(arbitrary_self_types)]

use std::iter::Iterator;
use std::future::Future;
Expand Down
2 changes: 1 addition & 1 deletion src/test/run-pass/async-await.rs
@@ -1,7 +1,7 @@
// edition:2018
// aux-build:arc_wake.rs

#![feature(async_await, await_macro, futures_api)]
#![feature(async_await, await_macro)]

extern crate arc_wake;

Expand Down
2 changes: 0 additions & 2 deletions src/test/run-pass/auxiliary/arc_wake.rs
@@ -1,7 +1,5 @@
// edition:2018

#![feature(futures_api)]

use std::sync::Arc;
use std::task::{
Waker, RawWaker, RawWakerVTable,
Expand Down

0 comments on commit 3f966dc

Please sign in to comment.