From d8bf2223672973f9d86f6c173793bcfce7890cd8 Mon Sep 17 00:00:00 2001 From: Josef Reinhard Brandl Date: Sat, 30 Jun 2018 21:16:44 +0200 Subject: [PATCH] Add lifetime to `FutureObj` --- src/liballoc/boxed.rs | 17 +++++----- src/libcore/{ => future}/future.rs | 2 -- src/libcore/{task => future}/future_obj.rs | 38 ++++++++++++---------- src/libcore/future/mod.rs | 21 ++++++++++++ src/libcore/task/executor.rs | 8 ++--- src/libcore/task/mod.rs | 3 -- src/test/run-pass/async-await.rs | 5 +-- src/test/run-pass/futures-api.rs | 5 +-- 8 files changed, 60 insertions(+), 39 deletions(-) rename src/libcore/{ => future}/future.rs (99%) rename src/libcore/{task => future}/future_obj.rs (79%) create mode 100644 src/libcore/future/mod.rs diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index 918ad657be9..5984a992afc 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -66,7 +66,8 @@ use core::marker::{Unpin, Unsize}; 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, U: ?Sized> CoerceUnsized> for PinBox {} impl Unpin for PinBox {} #[unstable(feature = "futures_api", issue = "50547")] -impl<'a, F: ?Sized + Future + Unpin> Future for Box { +impl Future for Box { type Output = F::Output; fn poll(mut self: PinMut, cx: &mut Context) -> Poll { @@ -924,7 +925,7 @@ impl<'a, F: ?Sized + Future + Unpin> Future for Box { } #[unstable(feature = "futures_api", issue = "50547")] -impl<'a, F: ?Sized + Future> Future for PinBox { +impl Future for PinBox { type Output = F::Output; fn poll(mut self: PinMut, cx: &mut Context) -> Poll { @@ -933,7 +934,7 @@ impl<'a, F: ?Sized + Future> Future for PinBox { } #[unstable(feature = "futures_api", issue = "50547")] -unsafe impl + 'static> UnsafeFutureObj for PinBox { +unsafe impl<'a, T, F: Future + 'a> UnsafeFutureObj<'a, T> for PinBox { fn into_raw(self) -> *mut () { PinBox::into_raw(self) as *mut () } @@ -950,28 +951,28 @@ unsafe impl + 'static> UnsafeFutureObj for PinBox } #[unstable(feature = "futures_api", issue = "50547")] -impl + Send + 'static> From> for FutureObj<()> { +impl<'a, F: Future + Send + 'a> From> for FutureObj<'a, ()> { fn from(boxed: PinBox) -> Self { FutureObj::new(boxed) } } #[unstable(feature = "futures_api", issue = "50547")] -impl + Send + 'static> From> for FutureObj<()> { +impl<'a, F: Future + Send + 'a> From> for FutureObj<'a, ()> { fn from(boxed: Box) -> Self { FutureObj::new(PinBox::from(boxed)) } } #[unstable(feature = "futures_api", issue = "50547")] -impl + 'static> From> for LocalFutureObj<()> { +impl<'a, F: Future + 'a> From> for LocalFutureObj<'a, ()> { fn from(boxed: PinBox) -> Self { LocalFutureObj::new(boxed) } } #[unstable(feature = "futures_api", issue = "50547")] -impl + 'static> From> for LocalFutureObj<()> { +impl<'a, F: Future + 'a> From> for LocalFutureObj<'a, ()> { fn from(boxed: Box) -> Self { LocalFutureObj::new(PinBox::from(boxed)) } diff --git a/src/libcore/future.rs b/src/libcore/future/future.rs similarity index 99% rename from src/libcore/future.rs rename to src/libcore/future/future.rs index 153cd6c0724..10b4ca9b0b2 100644 --- a/src/libcore/future.rs +++ b/src/libcore/future/future.rs @@ -12,8 +12,6 @@ reason = "futures in libcore are unstable", issue = "50547")] -//! Asynchronous values. - use mem::PinMut; use marker::Unpin; use task::{self, Poll}; diff --git a/src/libcore/task/future_obj.rs b/src/libcore/future/future_obj.rs similarity index 79% rename from src/libcore/task/future_obj.rs rename to src/libcore/future/future_obj.rs index 3ed3bd51cf6..c60b8b97d34 100644 --- a/src/libcore/task/future_obj.rs +++ b/src/libcore/future/future_obj.rs @@ -21,22 +21,24 @@ use task::{Context, Poll}; /// A custom trait object for polling futures, roughly akin to /// `Box>`. /// Contrary to `FutureObj`, `LocalFutureObj` does not have a `Send` bound. -pub struct LocalFutureObj { +pub struct LocalFutureObj<'a, T> { ptr: *mut (), poll_fn: unsafe fn(*mut (), &mut Context) -> Poll, drop_fn: unsafe fn(*mut ()), - _marker: PhantomData, + _marker1: PhantomData, + _marker2: PhantomData<&'a ()>, } -impl LocalFutureObj { +impl<'a, T> LocalFutureObj<'a, T> { /// Create a `LocalFutureObj` from a custom trait object representation. #[inline] - pub fn new>(f: F) -> LocalFutureObj { + pub fn new + 'a>(f: F) -> LocalFutureObj<'a, T> { LocalFutureObj { ptr: f.into_raw(), poll_fn: F::poll, drop_fn: F::drop, - _marker: PhantomData, + _marker1: PhantomData, + _marker2: PhantomData, } } @@ -45,26 +47,26 @@ impl LocalFutureObj { /// instance from which this `LocalFutureObj` was created actually /// implements `Send`. #[inline] - pub unsafe fn as_future_obj(self) -> FutureObj { + pub unsafe fn as_future_obj(self) -> FutureObj<'a, T> { FutureObj(self) } } -impl fmt::Debug for LocalFutureObj { +impl<'a, T> fmt::Debug for LocalFutureObj<'a, T> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.debug_struct("LocalFutureObj") .finish() } } -impl From> for LocalFutureObj { +impl<'a, T> From> for LocalFutureObj<'a, T> { #[inline] - fn from(f: FutureObj) -> LocalFutureObj { + fn from(f: FutureObj<'a, T>) -> LocalFutureObj<'a, T> { f.0 } } -impl Future for LocalFutureObj { +impl<'a, T> Future for LocalFutureObj<'a, T> { type Output = T; #[inline] @@ -75,7 +77,7 @@ impl Future for LocalFutureObj { } } -impl Drop for LocalFutureObj { +impl<'a, T> Drop for LocalFutureObj<'a, T> { fn drop(&mut self) { unsafe { (self.drop_fn)(self.ptr) @@ -85,26 +87,26 @@ impl Drop for LocalFutureObj { /// A custom trait object for polling futures, roughly akin to /// `Box> + Send`. -pub struct FutureObj(LocalFutureObj); +pub struct FutureObj<'a, T>(LocalFutureObj<'a, T>); -unsafe impl Send for FutureObj {} +unsafe impl<'a, T> Send for FutureObj<'a, T> {} -impl FutureObj { +impl<'a, T> FutureObj<'a, T> { /// Create a `FutureObj` from a custom trait object representation. #[inline] - pub fn new + Send>(f: F) -> FutureObj { + pub fn new + Send>(f: F) -> FutureObj<'a, T> { FutureObj(LocalFutureObj::new(f)) } } -impl fmt::Debug for FutureObj { +impl<'a, T> fmt::Debug for FutureObj<'a, T> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.debug_struct("FutureObj") .finish() } } -impl Future for FutureObj { +impl<'a, T> Future for FutureObj<'a, T> { type Output = T; #[inline] @@ -123,7 +125,7 @@ impl Future for FutureObj { /// 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: 'static { +pub unsafe trait UnsafeFutureObj<'a, T>: 'a { /// Convert a owned instance into a (conceptually owned) void pointer. fn into_raw(self) -> *mut (); diff --git a/src/libcore/future/mod.rs b/src/libcore/future/mod.rs new file mode 100644 index 00000000000..f9361a0f4e7 --- /dev/null +++ b/src/libcore/future/mod.rs @@ -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 or the MIT license +// , 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}; diff --git a/src/libcore/task/executor.rs b/src/libcore/task/executor.rs index 55ea5e724c1..f1db5093e98 100644 --- a/src/libcore/task/executor.rs +++ b/src/libcore/task/executor.rs @@ -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/mod.rs b/src/libcore/task/mod.rs index 06cd7a9dd77..c4f07536164 100644 --- a/src/libcore/task/mod.rs +++ b/src/libcore/task/mod.rs @@ -25,8 +25,5 @@ pub use self::executor::{ 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}; diff --git a/src/test/run-pass/async-await.rs b/src/test/run-pass/async-await.rs index 3a67750e77e..0ac37485d3d 100644 --- a/src/test/run-pass/async-await.rs +++ b/src/test/run-pass/async-await.rs @@ -19,9 +19,10 @@ use std::sync::{ 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 @@ impl Wake for Counter { struct NoopExecutor; impl Executor for NoopExecutor { - fn spawn_obj(&mut self, _: FutureObj) -> Result<(), SpawnObjError> { + fn spawn_obj(&mut self, _: FutureObj<'static, ()>) -> Result<(), SpawnObjError> { Ok(()) } } diff --git a/src/test/run-pass/futures-api.rs b/src/test/run-pass/futures-api.rs index a427b82af6a..6cb975a9560 100644 --- a/src/test/run-pass/futures-api.rs +++ b/src/test/run-pass/futures-api.rs @@ -19,10 +19,11 @@ use std::sync::{ 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 @@ impl Wake for Counter { struct NoopExecutor; impl Executor for NoopExecutor { - fn spawn_obj(&mut self, _: FutureObj<()>) -> Result<(), SpawnObjError> { + fn spawn_obj(&mut self, _: FutureObj<'static, ()>) -> Result<(), SpawnObjError> { Ok(()) } }