Skip to content

Commit

Permalink
Remove StreamObj, caution against using FutureObj
Browse files Browse the repository at this point in the history
  • Loading branch information
Nemo157 authored and cramertj committed Apr 24, 2019
1 parent ee37fdc commit 3b67140
Show file tree
Hide file tree
Showing 10 changed files with 47 additions and 293 deletions.
21 changes: 10 additions & 11 deletions futures-core/src/future/future_obj.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ use core::{
/// A custom trait object for polling futures, roughly akin to
/// `Box<dyn Future<Output = T> + 'a>`.
///
/// This custom trait object was introduced for two reasons:
/// - Currently it is not possible to take `dyn Trait` by value and
/// `Box<dyn Trait>` is not available in no_std contexts.
/// This custom trait object was introduced as currently it is not possible to
/// take `dyn Trait` by value and `Box<dyn Trait>` is not available in no_std
/// contexts.
pub struct LocalFutureObj<'a, T> {
ptr: *mut (),
poll_fn: unsafe fn(*mut (), &mut Context<'_>) -> Poll<T>,
Expand Down Expand Up @@ -79,14 +79,13 @@ impl<T> Drop for LocalFutureObj<'_, T> {
/// A custom trait object for polling futures, roughly akin to
/// `Box<dyn Future<Output = T> + Send + 'a>`.
///
/// This custom trait object was introduced for two reasons:
/// - Currently it is not possible to take `dyn Trait` by value and
/// `Box<dyn Trait>` is not available in no_std contexts.
/// - The `Future` trait is currently not object safe: The `Future::poll`
/// method makes uses the arbitrary self types feature and traits in which
/// this feature is used are currently not object safe due to current compiler
/// limitations. (See tracking issue for arbitrary self types for more
/// information #44874)
/// This custom trait object was introduced as currently it is not possible to
/// take `dyn Trait` by value and `Box<dyn Trait>` is not available in no_std
/// contexts.
///
/// You should generally not need to use this type outside of `no_std` or when
/// implementing `Spawn`, consider using [`BoxFuture`](crate::future::BoxFuture)
/// instead.
pub struct FutureObj<'a, T>(LocalFutureObj<'a, T>);

impl<T> Unpin for FutureObj<'_, T> {}
Expand Down
5 changes: 5 additions & 0 deletions futures-core/src/future/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@ pub use core::future::Future;
mod future_obj;
pub use self::future_obj::{FutureObj, LocalFutureObj, UnsafeFutureObj};

#[cfg(feature = "alloc")]
/// An owned dynamically typed [`Future`] for use in cases where you can't
/// statically type your result or need to add some indirection.
pub type BoxFuture<'a, T> = Pin<alloc::boxed::Box<dyn Future<Output = T> + Send + 'a>>;

/// A `Future` or `TryFuture` which tracks whether or not the underlying future
/// should no longer be polled.
///
Expand Down
6 changes: 4 additions & 2 deletions futures-core/src/stream/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@ use core::ops::DerefMut;
use core::pin::Pin;
use core::task::{Context, Poll};

mod stream_obj;
pub use self::stream_obj::{StreamObj,LocalStreamObj,UnsafeStreamObj};
#[cfg(feature = "alloc")]
/// An owned dynamically typed [`Stream`] for use in cases where you can't
/// statically type your result or need to add some indirection.
pub type BoxStream<'a, T> = Pin<alloc::boxed::Box<dyn Stream<Item = T> + Send + 'a>>;

/// A stream of values produced asynchronously.
///
Expand Down
258 changes: 0 additions & 258 deletions futures-core/src/stream/stream_obj.rs

This file was deleted.

6 changes: 4 additions & 2 deletions futures-util/src/future/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ use futures_core::stream::Stream;
use futures_core::task::{Context, Poll};
#[cfg(feature = "alloc")]
use alloc::boxed::Box;
#[cfg(feature = "alloc")]
use futures_core::future::BoxFuture;

// re-export for `select!`
#[doc(hidden)]
Expand Down Expand Up @@ -491,8 +493,8 @@ pub trait FutureExt: Future {

/// Wrap the future in a Box, pinning it.
#[cfg(feature = "alloc")]
fn boxed(self) -> Pin<Box<Self>>
where Self: Sized
fn boxed(self) -> BoxFuture<'static, Self::Output>
where Self: Sized + Send + 'static
{
Box::pin(self)
}
Expand Down
7 changes: 6 additions & 1 deletion futures/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,9 @@ pub mod future {
FutureObj, LocalFutureObj, UnsafeFutureObj,
};

#[cfg(feature = "alloc")]
pub use futures_core::future::BoxFuture;

pub use futures_util::future::{
empty, Empty,
lazy, Lazy,
Expand Down Expand Up @@ -338,9 +341,11 @@ pub mod stream {

pub use futures_core::stream::{
Stream, TryStream, FusedStream,
StreamObj, LocalStreamObj, UnsafeStreamObj,
};

#[cfg(feature = "alloc")]
pub use futures_core::stream::BoxStream;

pub use futures_util::stream::{
iter, Iter,
repeat, Repeat,
Expand Down
4 changes: 2 additions & 2 deletions futures/tests/future_obj.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use futures::task::{Context, Poll};

#[test]
fn dropping_does_not_segfault() {
FutureObj::new(async { String::new() }.boxed());
FutureObj::new(Box::new(async { String::new() }));
}

#[test]
Expand All @@ -29,7 +29,7 @@ fn dropping_drops_the_future() {
}
}

FutureObj::new(Inc(&mut times_dropped).boxed());
FutureObj::new(Box::new(Inc(&mut times_dropped)));

assert_eq!(times_dropped, 1);
}
Loading

0 comments on commit 3b67140

Please sign in to comment.