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

[WIP] Add no_std + alloc support #1438

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
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
8 changes: 8 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,14 @@ matrix:
- cargo build --manifest-path futures-sink/Cargo.toml --no-default-features
- cargo build --manifest-path futures-util/Cargo.toml --no-default-features

- name: cargo build (alloc)
rust: nightly
script:
- cargo build --manifest-path futures/Cargo.toml --no-default-features --features=alloc,nightly
- cargo build --manifest-path futures-core/Cargo.toml --no-default-features --features=alloc,nightly
- cargo build --manifest-path futures-sink/Cargo.toml --no-default-features --features=alloc,nightly
- cargo build --manifest-path futures-util/Cargo.toml --no-default-features --features=alloc,nightly

- name: cargo build (default features)
rust: nightly
script:
Expand Down
4 changes: 3 additions & 1 deletion futures-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,13 @@ name = "futures_core"

[features]
default = ["std"]
std = ["either/use_std"]
std = ["alloc", "either/use_std", "alloc-shim/std"]
nightly = []
alloc = ["alloc-shim/alloc"]

[dependencies]
either = { version = "1.4", default-features = false, optional = true }
alloc-shim = { version = "0.3.0", features = ["futures"], optional = true }

[dev-dependencies]
futures-preview = { path = "../futures", version = "=0.3.0-alpha.12" }
7 changes: 4 additions & 3 deletions futures-core/src/future/future_obj.rs
Original file line number Diff line number Diff line change
Expand Up @@ -185,10 +185,11 @@ where
unsafe fn drop(_ptr: *mut ()) {}
}

#[cfg(feature = "std")]
mod if_std {
#[cfg(feature = "alloc")]
mod if_alloc {
use super::*;
use std::mem;
use core::mem;
use alloc::boxed::Box;

unsafe impl<'a, T, F> UnsafeFutureObj<'a, T> for Box<F>
where F: Future<Output = T> + 'a
Expand Down
7 changes: 5 additions & 2 deletions futures-core/src/future/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,11 @@ impl<F: FusedFuture + ?Sized> FusedFuture for &mut F {
}
}

#[cfg(feature = "std")]
mod if_std {
#[cfg(feature = "alloc")]
mod if_alloc {
use alloc::boxed::Box;
use super::*;

impl<F: FusedFuture + ?Sized> FusedFuture for Box<F> {
fn is_terminated(&self) -> bool {
<F as FusedFuture>::is_terminated(&**self)
Expand All @@ -48,6 +50,7 @@ mod if_std {
}
}

#[cfg(feature = "std")]
impl<F: FusedFuture> FusedFuture for std::panic::AssertUnwindSafe<F> {
fn is_terminated(&self) -> bool {
<F as FusedFuture>::is_terminated(&**self)
Expand Down
4 changes: 4 additions & 0 deletions futures-core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#![feature(futures_api)]
#![cfg_attr(feature = "nightly", feature(cfg_target_has_atomic))]
#![cfg_attr(all(feature = "alloc", not(feature = "std")), feature(alloc))]

#![cfg_attr(not(feature = "std"), no_std)]

Expand All @@ -10,6 +11,9 @@

#![doc(html_root_url = "https://rust-lang-nursery.github.io/futures-api-docs/0.3.0-alpha.12/futures_core")]

#[cfg(all(feature = "alloc", not(any(feature = "std", feature = "nightly"))))]
compile_error!("The `alloc` feature without `std` requires the `nightly` feature active to explicitly opt-in to unstable features");

pub mod future;
#[doc(hidden)] pub use self::future::{Future, FusedFuture, TryFuture};

Expand Down
9 changes: 5 additions & 4 deletions futures-core/src/stream/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -145,9 +145,9 @@ impl<S, T, E> TryStream for S
}
}

#[cfg(feature = "std")]
mod if_std {
use std::boxed::Box;
#[cfg(feature = "alloc")]
mod if_alloc {
use alloc::boxed::Box;
use super::*;

impl<S: ?Sized + Stream + Unpin> Stream for Box<S> {
Expand All @@ -161,6 +161,7 @@ mod if_std {
}
}

#[cfg(feature = "std")]
impl<S: Stream> Stream for ::std::panic::AssertUnwindSafe<S> {
type Item = S::Item;

Expand All @@ -172,7 +173,7 @@ mod if_std {
}
}

impl<T: Unpin> Stream for ::std::collections::VecDeque<T> {
impl<T: Unpin> Stream for ::alloc::collections::VecDeque<T> {
type Item = T;

fn poll_next(
Expand Down
8 changes: 4 additions & 4 deletions futures-core/src/stream/stream_obj.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ use super::Stream;
use crate::task::{LocalWaker, Poll};
use core::fmt;
use core::marker::PhantomData;
use core::mem;
use core::pin::Pin;

/// A custom trait object for polling streams, roughly akin to
Expand Down Expand Up @@ -188,10 +187,11 @@ where
unsafe fn drop(_ptr: *mut ()) {}
}

#[cfg(feature = "std")]
mod if_std {
use std::boxed::Box;
#[cfg(feature = "alloc")]
mod if_alloc {
use super::*;
use core::mem;
use alloc::boxed::Box;

unsafe impl<'a, T, F> UnsafeStreamObj<'a, T> for Box<F>
where F: Stream<Item = T> + 'a
Expand Down
4 changes: 2 additions & 2 deletions futures-core/src/task/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,5 @@ pub mod __internal;
pub use self::spawn::{Spawn, LocalSpawn, SpawnError};

pub use core::task::{Poll, Waker, LocalWaker, UnsafeWake};
#[cfg(feature = "std")]
pub use std::task::{Wake, local_waker, local_waker_from_nonlocal};
#[cfg(feature = "alloc")]
pub use alloc::task::{Wake, local_waker, local_waker_from_nonlocal};
5 changes: 4 additions & 1 deletion futures-sink/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,13 @@ The asynchronous `Sink` trait for the futures-rs library.
name = "futures_sink"

[features]
std = ["either/use_std", "futures-core-preview/std", "futures-channel-preview/std"]
std = ["alloc", "either/use_std", "futures-core-preview/std", "futures-channel-preview/std", "alloc-shim/std"]
default = ["std"]
nightly = ["futures-core-preview/nightly"]
alloc = ["futures-core-preview/alloc", "alloc-shim/alloc"]

[dependencies]
either = { version = "1.4", default-features = false, optional = true }
futures-core-preview = { path = "../futures-core", version = "=0.3.0-alpha.12", default-features = false }
futures-channel-preview = { path = "../futures-channel", version = "=0.3.0-alpha.12", default-features = false }
alloc-shim = { version = "0.3.0", features = ["futures"], optional = true }
18 changes: 11 additions & 7 deletions futures-sink/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@
#![doc(html_root_url = "https://rust-lang-nursery.github.io/futures-api-docs/0.3.0-alpha.12/futures_sink")]

#![feature(futures_api)]
#![cfg_attr(all(feature = "alloc", not(feature = "std")), feature(alloc))]

#[cfg(all(feature = "alloc", not(any(feature = "std", feature = "nightly"))))]
compile_error!("The `alloc` feature without `std` requires the `nightly` feature active to explicitly opt-in to unstable features");

use futures_core::task::{LocalWaker, Poll};
use core::pin::Pin;
Expand Down Expand Up @@ -155,16 +159,16 @@ impl<'a, S: ?Sized + Sink> Sink for Pin<&'a mut S> {
#[cfg(feature = "std")]
mod channel_impls;

#[cfg(feature = "std")]
mod if_std {
#[cfg(feature = "alloc")]
mod if_alloc {
use super::*;

/// The error type for `Vec` and `VecDequeue` when used as `Sink`s.
/// Values of this type can never be created.
#[derive(Copy, Clone, Debug)]
pub enum VecSinkError {}

impl<T> Sink for ::std::vec::Vec<T> {
impl<T> Sink for ::alloc::vec::Vec<T> {
type SinkItem = T;
type SinkError = VecSinkError;

Expand All @@ -187,7 +191,7 @@ mod if_std {
}
}

impl<T> Sink for ::std::collections::VecDeque<T> {
impl<T> Sink for ::alloc::collections::VecDeque<T> {
type SinkItem = T;
type SinkError = VecSinkError;

Expand All @@ -210,7 +214,7 @@ mod if_std {
}
}

impl<S: ?Sized + Sink + Unpin> Sink for ::std::boxed::Box<S> {
impl<S: ?Sized + Sink + Unpin> Sink for ::alloc::boxed::Box<S> {
type SinkItem = S::SinkItem;
type SinkError = S::SinkError;

Expand All @@ -232,8 +236,8 @@ mod if_std {
}
}

#[cfg(feature = "std")]
pub use self::if_std::*;
#[cfg(feature = "alloc")]
pub use self::if_alloc::*;

#[cfg(feature = "either")]
use either::Either;
Expand Down
6 changes: 4 additions & 2 deletions futures-util/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,13 @@ Common utilities and extension traits for the futures-rs library.
name = "futures_util"

[features]
std = ["futures-core-preview/std", "futures-io-preview/std", "futures-sink-preview/std", "futures-select-macro-preview/std", "either/use_std", "rand", "rand_core", "slab"]
std = ["alloc", "futures-core-preview/std", "futures-io-preview/std", "futures-sink-preview/std", "futures-select-macro-preview/std", "either/use_std", "rand", "rand_core", "slab", "alloc-shim/std"]
default = ["std", "futures-core-preview/either", "futures-sink-preview/either"]
compat = ["std", "futures_01"]
io-compat = ["compat", "tokio-io"]
bench = []
nightly = []
nightly = ["futures-core-preview/nightly", "futures-sink-preview/nightly"]
alloc = ["futures-core-preview/alloc", "futures-sink-preview/alloc", "alloc-shim/alloc"]

[dependencies]
futures-core-preview = { path = "../futures-core", version = "=0.3.0-alpha.12", default-features = false }
Expand All @@ -37,6 +38,7 @@ slab = { version = "0.4", optional = true }
futures_01 = { version = "0.1.25", optional = true, package = "futures" }
tokio-io = { version = "0.1.9", optional = true }
pin-utils = "0.1.0-alpha.4"
alloc-shim = { version = "0.3.0", features = ["futures"], optional = true }

[dev-dependencies]
futures-preview = { path = "../futures", version = "=0.3.0-alpha.12" }
Expand Down
6 changes: 3 additions & 3 deletions futures-util/src/future/abortable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ use crate::task::AtomicWaker;
use futures_core::future::Future;
use futures_core::task::{LocalWaker, Poll};
use pin_utils::unsafe_pinned;
use std::pin::Pin;
use std::sync::Arc;
use std::sync::atomic::{AtomicBool, Ordering};
use core::pin::Pin;
use core::sync::atomic::{AtomicBool, Ordering};
use alloc::sync::Arc;

/// A future which can be remotely short-circuited using an `AbortHandle`.
#[derive(Debug, Clone)]
Expand Down
16 changes: 8 additions & 8 deletions futures-util/src/future/join_all.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
//! Definition of the `JoinAll` combinator, waiting for all of a list of futures
//! to finish.

use std::fmt;
use std::future::Future;
use std::iter::FromIterator;
use std::mem;
use std::pin::Pin;
use std::prelude::v1::*;
use std::task::Poll;
use core::fmt;
use core::future::Future;
use core::iter::FromIterator;
use core::mem;
use core::pin::Pin;
use alloc::prelude::*;
use alloc::task::Poll;

#[derive(Debug)]
enum ElemState<F>
Expand Down Expand Up @@ -129,7 +129,7 @@ where

fn poll(
mut self: Pin<&mut Self>,
lw: &::std::task::LocalWaker,
lw: &::alloc::task::LocalWaker,
) -> Poll<Self::Output> {
let mut all_done = true;

Expand Down
12 changes: 7 additions & 5 deletions futures-util/src/future/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ use core::pin::Pin;
use futures_core::future::Future;
use futures_core::stream::Stream;
use futures_core::task::{LocalWaker, Poll};
#[cfg(feature = "alloc")]
use alloc::prelude::*;

// re-export for `select!`
#[doc(hidden)]
Expand Down Expand Up @@ -67,9 +69,9 @@ pub use self::unit_error::UnitError;
mod chain;
pub(crate) use self::chain::Chain;

#[cfg(feature = "std")]
#[cfg(feature = "alloc")]
mod abortable;
#[cfg(feature = "std")]
#[cfg(feature = "alloc")]
pub use self::abortable::{abortable, Abortable, AbortHandle, AbortRegistration, Aborted};

#[cfg(feature = "std")]
Expand All @@ -82,10 +84,10 @@ mod remote_handle;
#[cfg(feature = "std")]
pub use self::remote_handle::{Remote, RemoteHandle};

#[cfg(feature = "std")]
#[cfg(feature = "alloc")]
mod join_all;

#[cfg(feature = "std")]
#[cfg(feature = "alloc")]
pub use self::join_all::{join_all, JoinAll};

// #[cfg(feature = "std")]
Expand Down Expand Up @@ -653,7 +655,7 @@ pub trait FutureExt: Future {
}

/// Wrap the future in a Box, pinning it.
#[cfg(feature = "std")]
#[cfg(feature = "alloc")]
fn boxed(self) -> Pin<Box<Self>>
where Self: Sized
{
Expand Down
6 changes: 5 additions & 1 deletion futures-util/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,17 @@
#![feature(futures_api, box_into_pin)]
#![cfg_attr(feature = "std", feature(async_await, await_macro))]
#![cfg_attr(feature = "nightly", feature(cfg_target_has_atomic))]
#![cfg_attr(all(feature = "alloc", not(feature = "std")), feature(alloc))]

#![cfg_attr(not(feature = "std"), no_std)]
#![warn(missing_docs, missing_debug_implementations)]
#![deny(bare_trait_objects)]

#![doc(html_root_url = "https://rust-lang-nursery.github.io/futures-api-docs/0.3.0-alpha.12/futures_util")]

#[cfg(all(feature = "alloc", not(any(feature = "std", feature = "nightly"))))]
compile_error!("The `alloc` feature without `std` requires the `nightly` feature active to explicitly opt-in to unstable features");

#[macro_use]
mod macros;

Expand Down Expand Up @@ -89,5 +93,5 @@ pub mod io;
#[cfg(feature = "std")]
#[doc(hidden)] pub use crate::io::{AsyncReadExt, AsyncWriteExt};

#[cfg(feature = "std")]
#[cfg(feature = "alloc")]
pub mod lock;
21 changes: 12 additions & 9 deletions futures-util/src/lock/bilock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,19 @@

use futures_core::future::Future;
use futures_core::task::{LocalWaker, Poll, Waker};
use core::cell::UnsafeCell;
use core::fmt;
use core::mem;
use core::ops::{Deref, DerefMut};
use core::pin::Pin;
use core::sync::atomic::AtomicUsize;
use core::sync::atomic::Ordering::SeqCst;
use alloc::boxed::Box;
use alloc::sync::Arc;
#[cfg(feature = "std")]
use std::any::Any;
use std::boxed::Box;
use std::cell::UnsafeCell;
#[cfg(feature = "std")]
use std::error::Error;
use std::fmt;
use std::mem;
use std::ops::{Deref, DerefMut};
use std::pin::Pin;
use std::sync::Arc;
use std::sync::atomic::AtomicUsize;
use std::sync::atomic::Ordering::SeqCst;

/// A type of futures-powered synchronization primitive which is a mutex between
/// two possible owners.
Expand Down Expand Up @@ -210,6 +212,7 @@ impl<T> fmt::Display for ReuniteError<T> {
}
}

#[cfg(feature = "std")]
impl<T: Any> Error for ReuniteError<T> {
fn description(&self) -> &str {
"tried to reunite two BiLocks that don't form a pair"
Expand Down
Loading