]> git.lizzy.rs Git - rust.git/commitdiff
Add lifetime to `FutureObj`
authorJosef Reinhard Brandl <mail@josefbrandl.de>
Sat, 30 Jun 2018 19:16:44 +0000 (21:16 +0200)
committerJosef Reinhard Brandl <mail@josefbrandl.de>
Mon, 2 Jul 2018 11:59:40 +0000 (13:59 +0200)
src/liballoc/boxed.rs
src/libcore/future.rs [deleted file]
src/libcore/future/future.rs [new file with mode: 0644]
src/libcore/future/future_obj.rs [new file with mode: 0644]
src/libcore/future/mod.rs [new file with mode: 0644]
src/libcore/task/executor.rs
src/libcore/task/future_obj.rs [deleted file]
src/libcore/task/mod.rs
src/test/run-pass/async-await.rs
src/test/run-pass/futures-api.rs

index 918ad657be909142d18b20861837857960ab3445..5984a992afc6371a9850fd8e7059979d8ff14c22 100644 (file)
@@ -66,7 +66,8 @@
 use core::mem::{self, PinMut};
 use core::ops::{CoerceUnsized, Deref, DerefMut, Generator, GeneratorState};
 use core::ptr::{self, NonNull, Unique};
-use core::task::{Context, Poll, UnsafeFutureObj, FutureObj, LocalFutureObj};
+use core::future::{FutureObj, LocalFutureObj, UnsafeFutureObj};
+use core::task::{Context, Poll};
 use core::convert::From;
 
 use raw_vec::RawVec;
@@ -915,7 +916,7 @@ impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<PinBox<U>> for PinBox<T> {}
 impl<T: ?Sized> Unpin for PinBox<T> {}
 
 #[unstable(feature = "futures_api", issue = "50547")]
-impl<'a, F: ?Sized + Future + Unpin> Future for Box<F> {
+impl<F: ?Sized + Future + Unpin> Future for Box<F> {
     type Output = F::Output;
 
     fn poll(mut self: PinMut<Self>, cx: &mut Context) -> Poll<Self::Output> {
@@ -924,7 +925,7 @@ fn poll(mut self: PinMut<Self>, cx: &mut Context) -> Poll<Self::Output> {
 }
 
 #[unstable(feature = "futures_api", issue = "50547")]
-impl<'a, F: ?Sized + Future> Future for PinBox<F> {
+impl<F: ?Sized + Future> Future for PinBox<F> {
     type Output = F::Output;
 
     fn poll(mut self: PinMut<Self>, cx: &mut Context) -> Poll<Self::Output> {
@@ -933,7 +934,7 @@ fn poll(mut self: PinMut<Self>, cx: &mut Context) -> Poll<Self::Output> {
 }
 
 #[unstable(feature = "futures_api", issue = "50547")]
-unsafe impl<T, F: Future<Output = T> + 'static> UnsafeFutureObj<T> for PinBox<F> {
+unsafe impl<'a, T, F: Future<Output = T> + 'a> UnsafeFutureObj<'a, T> for PinBox<F> {
     fn into_raw(self) -> *mut () {
         PinBox::into_raw(self) as *mut ()
     }
@@ -950,28 +951,28 @@ unsafe fn drop(task: *mut ()) {
 }
 
 #[unstable(feature = "futures_api", issue = "50547")]
-impl<F: Future<Output = ()> + Send + 'static> From<PinBox<F>> for FutureObj<()> {
+impl<'a, F: Future<Output = ()> + Send + 'a> From<PinBox<F>> for FutureObj<'a, ()> {
     fn from(boxed: PinBox<F>) -> Self {
         FutureObj::new(boxed)
     }
 }
 
 #[unstable(feature = "futures_api", issue = "50547")]
-impl<F: Future<Output = ()> + Send + 'static> From<Box<F>> for FutureObj<()> {
+impl<'a, F: Future<Output = ()> + Send + 'a> From<Box<F>> for FutureObj<'a, ()> {
     fn from(boxed: Box<F>) -> Self {
         FutureObj::new(PinBox::from(boxed))
     }
 }
 
 #[unstable(feature = "futures_api", issue = "50547")]
-impl<F: Future<Output = ()> + 'static> From<PinBox<F>> for LocalFutureObj<()> {
+impl<'a, F: Future<Output = ()> + 'a> From<PinBox<F>> for LocalFutureObj<'a, ()> {
     fn from(boxed: PinBox<F>) -> Self {
         LocalFutureObj::new(boxed)
     }
 }
 
 #[unstable(feature = "futures_api", issue = "50547")]
-impl<F: Future<Output = ()> + 'static> From<Box<F>> for LocalFutureObj<()> {
+impl<'a, F: Future<Output = ()> + 'a> From<Box<F>> for LocalFutureObj<'a, ()> {
     fn from(boxed: Box<F>) -> Self {
         LocalFutureObj::new(PinBox::from(boxed))
     }
diff --git a/src/libcore/future.rs b/src/libcore/future.rs
deleted file mode 100644 (file)
index 153cd6c..0000000
+++ /dev/null
@@ -1,114 +0,0 @@
-// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#![unstable(feature = "futures_api",
-            reason = "futures in libcore are unstable",
-            issue = "50547")]
-
-//! Asynchronous values.
-
-use mem::PinMut;
-use marker::Unpin;
-use task::{self, Poll};
-
-/// A future represents an asychronous computation.
-///
-/// A future is a value that may not have finished computing yet. This kind of
-/// "asynchronous value" makes it possible for a thread to continue doing useful
-/// work while it waits for the value to become available.
-///
-/// # The `poll` method
-///
-/// The core method of future, `poll`, *attempts* to resolve the future into a
-/// final value. This method does not block if the value is not ready. Instead,
-/// the current task is scheduled to be woken up when it's possible to make
-/// further progress by `poll`ing again. The wake up is performed using
-/// `cx.waker()`, a handle for waking up the current task.
-///
-/// When using a future, you generally won't call `poll` directly, but instead
-/// `await!` the value.
-pub trait Future {
-    /// The result of the `Future`.
-    type Output;
-
-    /// Attempt to resolve the future to a final value, registering
-    /// the current task for wakeup if the value is not yet available.
-    ///
-    /// # Return value
-    ///
-    /// This function returns:
-    ///
-    /// - [`Poll::Pending`] if the future is not ready yet
-    /// - [`Poll::Ready(val)`] with the result `val` of this future if it
-    ///   finished successfully.
-    ///
-    /// Once a future has finished, clients should not `poll` it again.
-    ///
-    /// When a future is not ready yet, `poll` returns
-    /// `Poll::Pending`. The future will *also* register the
-    /// interest of the current task in the value being produced. For example,
-    /// if the future represents the availability of data on a socket, then the
-    /// task is recorded so that when data arrives, it is woken up (via
-    /// [`cx.waker()`]). Once a task has been woken up,
-    /// it should attempt to `poll` the future again, which may or may not
-    /// produce a final value.
-    ///
-    /// Note that if `Pending` is returned it only means that the *current* task
-    /// (represented by the argument `cx`) will receive a notification. Tasks
-    /// from previous calls to `poll` will *not* receive notifications.
-    ///
-    /// # Runtime characteristics
-    ///
-    /// Futures alone are *inert*; they must be *actively* `poll`ed to make
-    /// progress, meaning that each time the current task is woken up, it should
-    /// actively re-`poll` pending futures that it still has an interest in.
-    ///
-    /// The `poll` function is not called repeatedly in a tight loop for
-    /// futures, but only whenever the future itself is ready, as signaled via
-    /// the `Waker` inside `task::Context`. If you're familiar with the
-    /// `poll(2)` or `select(2)` syscalls on Unix it's worth noting that futures
-    /// typically do *not* suffer the same problems of "all wakeups must poll
-    /// all events"; they are more like `epoll(4)`.
-    ///
-    /// An implementation of `poll` should strive to return quickly, and must
-    /// *never* block. Returning quickly prevents unnecessarily clogging up
-    /// threads or event loops. If it is known ahead of time that a call to
-    /// `poll` may end up taking awhile, the work should be offloaded to a
-    /// thread pool (or something similar) to ensure that `poll` can return
-    /// quickly.
-    ///
-    /// # Panics
-    ///
-    /// Once a future has completed (returned `Ready` from `poll`),
-    /// then any future calls to `poll` may panic, block forever, or otherwise
-    /// cause bad behavior. The `Future` trait itself provides no guarantees
-    /// about the behavior of `poll` after a future has completed.
-    ///
-    /// [`Poll::Pending`]: ../task/enum.Poll.html#variant.Pending
-    /// [`Poll::Ready(val)`]: ../task/enum.Poll.html#variant.Ready
-    /// [`cx.waker()`]: ../task/struct.Context.html#method.waker
-    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)
-    }
-}
diff --git a/src/libcore/future/future.rs b/src/libcore/future/future.rs
new file mode 100644 (file)
index 0000000..10b4ca9
--- /dev/null
@@ -0,0 +1,112 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![unstable(feature = "futures_api",
+            reason = "futures in libcore are unstable",
+            issue = "50547")]
+
+use mem::PinMut;
+use marker::Unpin;
+use task::{self, Poll};
+
+/// A future represents an asychronous computation.
+///
+/// A future is a value that may not have finished computing yet. This kind of
+/// "asynchronous value" makes it possible for a thread to continue doing useful
+/// work while it waits for the value to become available.
+///
+/// # The `poll` method
+///
+/// The core method of future, `poll`, *attempts* to resolve the future into a
+/// final value. This method does not block if the value is not ready. Instead,
+/// the current task is scheduled to be woken up when it's possible to make
+/// further progress by `poll`ing again. The wake up is performed using
+/// `cx.waker()`, a handle for waking up the current task.
+///
+/// When using a future, you generally won't call `poll` directly, but instead
+/// `await!` the value.
+pub trait Future {
+    /// The result of the `Future`.
+    type Output;
+
+    /// Attempt to resolve the future to a final value, registering
+    /// the current task for wakeup if the value is not yet available.
+    ///
+    /// # Return value
+    ///
+    /// This function returns:
+    ///
+    /// - [`Poll::Pending`] if the future is not ready yet
+    /// - [`Poll::Ready(val)`] with the result `val` of this future if it
+    ///   finished successfully.
+    ///
+    /// Once a future has finished, clients should not `poll` it again.
+    ///
+    /// When a future is not ready yet, `poll` returns
+    /// `Poll::Pending`. The future will *also* register the
+    /// interest of the current task in the value being produced. For example,
+    /// if the future represents the availability of data on a socket, then the
+    /// task is recorded so that when data arrives, it is woken up (via
+    /// [`cx.waker()`]). Once a task has been woken up,
+    /// it should attempt to `poll` the future again, which may or may not
+    /// produce a final value.
+    ///
+    /// Note that if `Pending` is returned it only means that the *current* task
+    /// (represented by the argument `cx`) will receive a notification. Tasks
+    /// from previous calls to `poll` will *not* receive notifications.
+    ///
+    /// # Runtime characteristics
+    ///
+    /// Futures alone are *inert*; they must be *actively* `poll`ed to make
+    /// progress, meaning that each time the current task is woken up, it should
+    /// actively re-`poll` pending futures that it still has an interest in.
+    ///
+    /// The `poll` function is not called repeatedly in a tight loop for
+    /// futures, but only whenever the future itself is ready, as signaled via
+    /// the `Waker` inside `task::Context`. If you're familiar with the
+    /// `poll(2)` or `select(2)` syscalls on Unix it's worth noting that futures
+    /// typically do *not* suffer the same problems of "all wakeups must poll
+    /// all events"; they are more like `epoll(4)`.
+    ///
+    /// An implementation of `poll` should strive to return quickly, and must
+    /// *never* block. Returning quickly prevents unnecessarily clogging up
+    /// threads or event loops. If it is known ahead of time that a call to
+    /// `poll` may end up taking awhile, the work should be offloaded to a
+    /// thread pool (or something similar) to ensure that `poll` can return
+    /// quickly.
+    ///
+    /// # Panics
+    ///
+    /// Once a future has completed (returned `Ready` from `poll`),
+    /// then any future calls to `poll` may panic, block forever, or otherwise
+    /// cause bad behavior. The `Future` trait itself provides no guarantees
+    /// about the behavior of `poll` after a future has completed.
+    ///
+    /// [`Poll::Pending`]: ../task/enum.Poll.html#variant.Pending
+    /// [`Poll::Ready(val)`]: ../task/enum.Poll.html#variant.Ready
+    /// [`cx.waker()`]: ../task/struct.Context.html#method.waker
+    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)
+    }
+}
diff --git a/src/libcore/future/future_obj.rs b/src/libcore/future/future_obj.rs
new file mode 100644 (file)
index 0000000..c60b8b9
--- /dev/null
@@ -0,0 +1,149 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![unstable(feature = "futures_api",
+            reason = "futures in libcore are unstable",
+            issue = "50547")]
+
+use fmt;
+use future::Future;
+use marker::PhantomData;
+use mem::PinMut;
+use task::{Context, Poll};
+
+/// A custom trait object for polling futures, roughly akin to
+/// `Box<dyn Future<Output = T>>`.
+/// Contrary to `FutureObj`, `LocalFutureObj` does not have a `Send` bound.
+pub struct LocalFutureObj<'a, T> {
+    ptr: *mut (),
+    poll_fn: unsafe fn(*mut (), &mut Context) -> Poll<T>,
+    drop_fn: unsafe fn(*mut ()),
+    _marker1: PhantomData<T>,
+    _marker2: PhantomData<&'a ()>,
+}
+
+impl<'a, T> LocalFutureObj<'a, T> {
+    /// Create a `LocalFutureObj` from a custom trait object representation.
+    #[inline]
+    pub fn new<F: UnsafeFutureObj<'a, T> + 'a>(f: F) -> LocalFutureObj<'a, T> {
+        LocalFutureObj {
+            ptr: f.into_raw(),
+            poll_fn: F::poll,
+            drop_fn: F::drop,
+            _marker1: PhantomData,
+            _marker2: PhantomData,
+        }
+    }
+
+    /// Converts the `LocalFutureObj` into a `FutureObj`
+    /// To make this operation safe one has to ensure that the `UnsafeFutureObj`
+    /// instance from which this `LocalFutureObj` was created actually
+    /// implements `Send`.
+    #[inline]
+    pub unsafe fn as_future_obj(self) -> FutureObj<'a, T> {
+        FutureObj(self)
+    }
+}
+
+impl<'a, T> fmt::Debug for LocalFutureObj<'a, T> {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.debug_struct("LocalFutureObj")
+            .finish()
+    }
+}
+
+impl<'a, T> From<FutureObj<'a, T>> for LocalFutureObj<'a, T> {
+    #[inline]
+    fn from(f: FutureObj<'a, T>) -> LocalFutureObj<'a, T> {
+        f.0
+    }
+}
+
+impl<'a, T> Future for LocalFutureObj<'a, T> {
+    type Output = T;
+
+    #[inline]
+    fn poll(self: PinMut<Self>, cx: &mut Context) -> Poll<T> {
+        unsafe {
+            (self.poll_fn)(self.ptr, cx)
+        }
+    }
+}
+
+impl<'a, T> Drop for LocalFutureObj<'a, T> {
+    fn drop(&mut self) {
+        unsafe {
+            (self.drop_fn)(self.ptr)
+        }
+    }
+}
+
+/// A custom trait object for polling futures, roughly akin to
+/// `Box<dyn Future<Output = T>> + Send`.
+pub struct FutureObj<'a, T>(LocalFutureObj<'a, T>);
+
+unsafe impl<'a, T> Send for FutureObj<'a, T> {}
+
+impl<'a, T> FutureObj<'a, T> {
+    /// Create a `FutureObj` from a custom trait object representation.
+    #[inline]
+    pub fn new<F: UnsafeFutureObj<'a, T> + Send>(f: F) -> FutureObj<'a, T> {
+        FutureObj(LocalFutureObj::new(f))
+    }
+}
+
+impl<'a, T> fmt::Debug for FutureObj<'a, T> {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.debug_struct("FutureObj")
+            .finish()
+    }
+}
+
+impl<'a, T> Future for FutureObj<'a, T> {
+    type Output = T;
+
+    #[inline]
+    fn poll(self: PinMut<Self>, cx: &mut Context) -> Poll<T> {
+        let pinned_field = unsafe { PinMut::map_unchecked(self, |x| &mut x.0) };
+        pinned_field.poll(cx)
+    }
+}
+
+/// A custom implementation of a future trait object for `FutureObj`, providing
+/// a hand-rolled vtable.
+///
+/// This custom representation is typically used only in `no_std` contexts,
+/// where the default `Box`-based implementation is not available.
+///
+/// The implementor must guarantee that it is safe to call `poll` repeatedly (in
+/// a non-concurrent fashion) with the result of `into_raw` until `drop` is
+/// called.
+pub unsafe trait UnsafeFutureObj<'a, T>: 'a {
+    /// Convert a owned instance into a (conceptually owned) void pointer.
+    fn into_raw(self) -> *mut ();
+
+    /// Poll the future represented by the given void pointer.
+    ///
+    /// # Safety
+    ///
+    /// The trait implementor must guarantee that it is safe to repeatedly call
+    /// `poll` with the result of `into_raw` until `drop` is called; such calls
+    /// are not, however, allowed to race with each other or with calls to `drop`.
+    unsafe fn poll(future: *mut (), cx: &mut Context) -> Poll<T>;
+
+    /// Drops the future represented by the given void pointer.
+    ///
+    /// # Safety
+    ///
+    /// The trait implementor must guarantee that it is safe to call this
+    /// function once per `into_raw` invocation; that call cannot race with
+    /// other calls to `drop` or `poll`.
+    unsafe fn drop(future: *mut ());
+}
diff --git a/src/libcore/future/mod.rs b/src/libcore/future/mod.rs
new file mode 100644 (file)
index 0000000..f9361a0
--- /dev/null
@@ -0,0 +1,21 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![unstable(feature = "futures_api",
+            reason = "futures in libcore are unstable",
+            issue = "50547")]
+
+//! Asynchronous values.
+
+mod future;
+pub use self::future::Future;
+
+mod future_obj;
+pub use self::future_obj::{FutureObj, LocalFutureObj, UnsafeFutureObj};
index 55ea5e724c1cc883d94df78f1a0ffde332b8d8bb..f1db5093e9880ab84fe4940c455bbd893700d073 100644 (file)
@@ -13,7 +13,7 @@
             issue = "50547")]
 
 use fmt;
-use super::{FutureObj, LocalFutureObj};
+use future::{FutureObj, LocalFutureObj};
 
 /// A task executor.
 ///
@@ -29,7 +29,7 @@ pub trait Executor {
     ///
     /// The executor may be unable to spawn tasks, either because it has
     /// been shut down or is resource-constrained.
-    fn spawn_obj(&mut self, task: FutureObj<()>) -> Result<(), SpawnObjError>;
+    fn spawn_obj(&mut self, task: FutureObj<'static, ()>) -> Result<(), SpawnObjError>;
 
     /// Determine whether the executor is able to spawn new tasks.
     ///
@@ -76,7 +76,7 @@ pub struct SpawnObjError {
     pub kind: SpawnErrorKind,
 
     /// The task for which spawning was attempted
-    pub task: FutureObj<()>,
+    pub task: FutureObj<'static, ()>,
 }
 
 /// The result of a failed spawn
@@ -86,5 +86,5 @@ pub struct SpawnLocalObjError {
     pub kind: SpawnErrorKind,
 
     /// The task for which spawning was attempted
-    pub task: LocalFutureObj<()>,
+    pub task: LocalFutureObj<'static, ()>,
 }
diff --git a/src/libcore/task/future_obj.rs b/src/libcore/task/future_obj.rs
deleted file mode 100644 (file)
index 3ed3bd5..0000000
+++ /dev/null
@@ -1,147 +0,0 @@
-// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#![unstable(feature = "futures_api",
-            reason = "futures in libcore are unstable",
-            issue = "50547")]
-
-use fmt;
-use future::Future;
-use marker::PhantomData;
-use mem::PinMut;
-use task::{Context, Poll};
-
-/// A custom trait object for polling futures, roughly akin to
-/// `Box<dyn Future<Output = T>>`.
-/// Contrary to `FutureObj`, `LocalFutureObj` does not have a `Send` bound.
-pub struct LocalFutureObj<T> {
-    ptr: *mut (),
-    poll_fn: unsafe fn(*mut (), &mut Context) -> Poll<T>,
-    drop_fn: unsafe fn(*mut ()),
-    _marker: PhantomData<T>,
-}
-
-impl<T> LocalFutureObj<T> {
-    /// Create a `LocalFutureObj` from a custom trait object representation.
-    #[inline]
-    pub fn new<F: UnsafeFutureObj<T>>(f: F) -> LocalFutureObj<T> {
-        LocalFutureObj {
-            ptr: f.into_raw(),
-            poll_fn: F::poll,
-            drop_fn: F::drop,
-            _marker: PhantomData,
-        }
-    }
-
-    /// Converts the `LocalFutureObj` into a `FutureObj`
-    /// To make this operation safe one has to ensure that the `UnsafeFutureObj`
-    /// instance from which this `LocalFutureObj` was created actually
-    /// implements `Send`.
-    #[inline]
-    pub unsafe fn as_future_obj(self) -> FutureObj<T> {
-        FutureObj(self)
-    }
-}
-
-impl<T> fmt::Debug for LocalFutureObj<T> {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        f.debug_struct("LocalFutureObj")
-            .finish()
-    }
-}
-
-impl<T> From<FutureObj<T>> for LocalFutureObj<T> {
-    #[inline]
-    fn from(f: FutureObj<T>) -> LocalFutureObj<T> {
-        f.0
-    }
-}
-
-impl<T> Future for LocalFutureObj<T> {
-    type Output = T;
-
-    #[inline]
-    fn poll(self: PinMut<Self>, cx: &mut Context) -> Poll<T> {
-        unsafe {
-            (self.poll_fn)(self.ptr, cx)
-        }
-    }
-}
-
-impl<T> Drop for LocalFutureObj<T> {
-    fn drop(&mut self) {
-        unsafe {
-            (self.drop_fn)(self.ptr)
-        }
-    }
-}
-
-/// A custom trait object for polling futures, roughly akin to
-/// `Box<dyn Future<Output = T>> + Send`.
-pub struct FutureObj<T>(LocalFutureObj<T>);
-
-unsafe impl<T> Send for FutureObj<T> {}
-
-impl<T> FutureObj<T> {
-    /// Create a `FutureObj` from a custom trait object representation.
-    #[inline]
-    pub fn new<F: UnsafeFutureObj<T> + Send>(f: F) -> FutureObj<T> {
-        FutureObj(LocalFutureObj::new(f))
-    }
-}
-
-impl<T> fmt::Debug for FutureObj<T> {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        f.debug_struct("FutureObj")
-            .finish()
-    }
-}
-
-impl<T> Future for FutureObj<T> {
-    type Output = T;
-
-    #[inline]
-    fn poll(self: PinMut<Self>, cx: &mut Context) -> Poll<T> {
-        let pinned_field = unsafe { PinMut::map_unchecked(self, |x| &mut x.0) };
-        pinned_field.poll(cx)
-    }
-}
-
-/// A custom implementation of a future trait object for `FutureObj`, providing
-/// a hand-rolled vtable.
-///
-/// This custom representation is typically used only in `no_std` contexts,
-/// where the default `Box`-based implementation is not available.
-///
-/// The implementor must guarantee that it is safe to call `poll` repeatedly (in
-/// a non-concurrent fashion) with the result of `into_raw` until `drop` is
-/// called.
-pub unsafe trait UnsafeFutureObj<T>: 'static {
-    /// Convert a owned instance into a (conceptually owned) void pointer.
-    fn into_raw(self) -> *mut ();
-
-    /// Poll the future represented by the given void pointer.
-    ///
-    /// # Safety
-    ///
-    /// The trait implementor must guarantee that it is safe to repeatedly call
-    /// `poll` with the result of `into_raw` until `drop` is called; such calls
-    /// are not, however, allowed to race with each other or with calls to `drop`.
-    unsafe fn poll(future: *mut (), cx: &mut Context) -> Poll<T>;
-
-    /// Drops the future represented by the given void pointer.
-    ///
-    /// # Safety
-    ///
-    /// The trait implementor must guarantee that it is safe to call this
-    /// function once per `into_raw` invocation; that call cannot race with
-    /// other calls to `drop` or `poll`.
-    unsafe fn drop(future: *mut ());
-}
index 06cd7a9dd773ed648c06aca972008b685605f178..c4f075361640f1b887e099b8c797b0ded7082265 100644 (file)
@@ -25,8 +25,5 @@
 mod poll;
 pub use self::poll::Poll;
 
-mod future_obj;
-pub use self::future_obj::{FutureObj, LocalFutureObj, UnsafeFutureObj};
-
 mod wake;
 pub use self::wake::{Waker, LocalWaker, UnsafeWake};
index 3a67750e77e6bc91e458098b3d29dd4339491cf0..0ac37485d3dc81df976de0d747b979be4c3e0592 100644 (file)
     Arc,
     atomic::{self, AtomicUsize},
 };
+use std::future::FutureObj;
 use std::task::{
     Context, Poll, Wake,
-    Executor, FutureObj, SpawnObjError,
+    Executor, SpawnObjError,
     local_waker_from_nonlocal,
 };
 
@@ -37,7 +38,7 @@ fn wake(this: &Arc<Self>) {
 
 struct NoopExecutor;
 impl Executor for NoopExecutor {
-    fn spawn_obj(&mut self, _: FutureObj<T>) -> Result<(), SpawnObjError> {
+    fn spawn_obj(&mut self, _: FutureObj<'static, ()>) -> Result<(), SpawnObjError> {
         Ok(())
     }
 }
index a427b82af6a6b625cb2060aca346acb924e0b5b9..6cb975a9560b9403cb726ea043dee7744eaf7bb9 100644 (file)
     Arc,
     atomic::{self, AtomicUsize},
 };
+use std::future::FutureObj;
 use std::task::{
     Context, Poll,
     Wake, Waker, LocalWaker,
-    Executor, FutureObj, SpawnObjError,
+    Executor, SpawnObjError,
     local_waker, local_waker_from_nonlocal,
 };
 
@@ -44,7 +45,7 @@ unsafe fn wake_local(this: &Arc<Self>) {
 struct NoopExecutor;
 
 impl Executor for NoopExecutor {
-    fn spawn_obj(&mut self, _: FutureObj<()>) -> Result<(), SpawnObjError> {
+    fn spawn_obj(&mut self, _: FutureObj<'static, ()>) -> Result<(), SpawnObjError> {
         Ok(())
     }
 }