Skip to content

Commit a822c5e

Browse files
committed
Add no_std + alloc support
1 parent ebbc6be commit a822c5e

40 files changed

+225
-167
lines changed

.travis.yml

+8
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,14 @@ matrix:
5454
- cargo build --manifest-path futures-sink/Cargo.toml --no-default-features
5555
- cargo build --manifest-path futures-util/Cargo.toml --no-default-features
5656

57+
- name: cargo build (alloc)
58+
rust: nightly
59+
script:
60+
- cargo build --manifest-path futures/Cargo.toml --no-default-features --features=alloc,nightly
61+
- cargo build --manifest-path futures-core/Cargo.toml --no-default-features --features=alloc,nightly
62+
- cargo build --manifest-path futures-sink/Cargo.toml --no-default-features --features=alloc,nightly
63+
- cargo build --manifest-path futures-util/Cargo.toml --no-default-features --features=alloc,nightly
64+
5765
- name: cargo build (default features)
5866
rust: nightly
5967
script:

futures-core/Cargo.toml

+3-1
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,13 @@ name = "futures_core"
1616

1717
[features]
1818
default = ["std"]
19-
std = ["either/use_std"]
19+
std = ["alloc", "either/use_std", "alloc-shim/std"]
2020
nightly = []
21+
alloc = ["alloc-shim/alloc"]
2122

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

2527
[dev-dependencies]
2628
futures-preview = { path = "../futures", version = "=0.3.0-alpha.12" }

futures-core/src/future/future_obj.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -185,10 +185,11 @@ where
185185
unsafe fn drop(_ptr: *mut ()) {}
186186
}
187187

188-
#[cfg(feature = "std")]
189-
mod if_std {
188+
#[cfg(feature = "alloc")]
189+
mod if_alloc {
190190
use super::*;
191-
use std::mem;
191+
use core::mem;
192+
use alloc::boxed::Box;
192193

193194
unsafe impl<'a, T, F> UnsafeFutureObj<'a, T> for Box<F>
194195
where F: Future<Output = T> + 'a

futures-core/src/future/mod.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,11 @@ impl<F: FusedFuture + ?Sized> FusedFuture for &mut F {
3333
}
3434
}
3535

36-
#[cfg(feature = "std")]
37-
mod if_std {
36+
#[cfg(feature = "alloc")]
37+
mod if_alloc {
38+
use alloc::boxed::Box;
3839
use super::*;
40+
3941
impl<F: FusedFuture + ?Sized> FusedFuture for Box<F> {
4042
fn is_terminated(&self) -> bool {
4143
<F as FusedFuture>::is_terminated(&**self)
@@ -48,6 +50,7 @@ mod if_std {
4850
}
4951
}
5052

53+
#[cfg(feature = "std")]
5154
impl<F: FusedFuture> FusedFuture for std::panic::AssertUnwindSafe<F> {
5255
fn is_terminated(&self) -> bool {
5356
<F as FusedFuture>::is_terminated(&**self)

futures-core/src/lib.rs

+4
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
33
#![feature(futures_api)]
44
#![cfg_attr(feature = "nightly", feature(cfg_target_has_atomic))]
5+
#![cfg_attr(all(feature = "alloc", not(feature = "std")), feature(alloc))]
56

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

@@ -10,6 +11,9 @@
1011

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

14+
#[cfg(all(feature = "alloc", not(any(feature = "std", feature = "nightly"))))]
15+
compile_error!("The `alloc` feature without `std` requires the `nightly` feature active to explicitly opt-in to unstable features");
16+
1317
pub mod future;
1418
#[doc(hidden)] pub use self::future::{Future, FusedFuture, TryFuture};
1519

futures-core/src/stream/mod.rs

+5-4
Original file line numberDiff line numberDiff line change
@@ -145,9 +145,9 @@ impl<S, T, E> TryStream for S
145145
}
146146
}
147147

148-
#[cfg(feature = "std")]
149-
mod if_std {
150-
use std::boxed::Box;
148+
#[cfg(feature = "alloc")]
149+
mod if_alloc {
150+
use alloc::boxed::Box;
151151
use super::*;
152152

153153
impl<S: ?Sized + Stream + Unpin> Stream for Box<S> {
@@ -161,6 +161,7 @@ mod if_std {
161161
}
162162
}
163163

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

@@ -172,7 +173,7 @@ mod if_std {
172173
}
173174
}
174175

175-
impl<T: Unpin> Stream for ::std::collections::VecDeque<T> {
176+
impl<T: Unpin> Stream for ::alloc::collections::VecDeque<T> {
176177
type Item = T;
177178

178179
fn poll_next(

futures-core/src/stream/stream_obj.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ use super::Stream;
22
use crate::task::{LocalWaker, Poll};
33
use core::fmt;
44
use core::marker::PhantomData;
5-
use core::mem;
65
use core::pin::Pin;
76

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

191-
#[cfg(feature = "std")]
192-
mod if_std {
193-
use std::boxed::Box;
190+
#[cfg(feature = "alloc")]
191+
mod if_alloc {
194192
use super::*;
193+
use core::mem;
194+
use alloc::boxed::Box;
195195

196196
unsafe impl<'a, T, F> UnsafeStreamObj<'a, T> for Box<F>
197197
where F: Stream<Item = T> + 'a

futures-core/src/task/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,5 @@ pub mod __internal;
66
pub use self::spawn::{Spawn, LocalSpawn, SpawnError};
77

88
pub use core::task::{Poll, Waker, LocalWaker, UnsafeWake};
9-
#[cfg(feature = "std")]
10-
pub use std::task::{Wake, local_waker, local_waker_from_nonlocal};
9+
#[cfg(feature = "alloc")]
10+
pub use alloc::task::{Wake, local_waker, local_waker_from_nonlocal};

futures-sink/Cargo.toml

+4-1
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,13 @@ The asynchronous `Sink` trait for the futures-rs library.
1515
name = "futures_sink"
1616

1717
[features]
18-
std = ["either/use_std", "futures-core-preview/std", "futures-channel-preview/std"]
18+
std = ["alloc", "either/use_std", "futures-core-preview/std", "futures-channel-preview/std", "alloc-shim/std"]
1919
default = ["std"]
20+
nightly = ["futures-core-preview/nightly"]
21+
alloc = ["futures-core-preview/alloc", "alloc-shim/alloc"]
2022

2123
[dependencies]
2224
either = { version = "1.4", default-features = false, optional = true }
2325
futures-core-preview = { path = "../futures-core", version = "=0.3.0-alpha.12", default-features = false }
2426
futures-channel-preview = { path = "../futures-channel", version = "=0.3.0-alpha.12", default-features = false }
27+
alloc-shim = { version = "0.3.0", features = ["futures"], optional = true }

futures-sink/src/lib.rs

+11-7
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@
88
#![doc(html_root_url = "https://rust-lang-nursery.github.io/futures-api-docs/0.3.0-alpha.12/futures_sink")]
99

1010
#![feature(futures_api)]
11+
#![cfg_attr(all(feature = "alloc", not(feature = "std")), feature(alloc))]
12+
13+
#[cfg(all(feature = "alloc", not(any(feature = "std", feature = "nightly"))))]
14+
compile_error!("The `alloc` feature without `std` requires the `nightly` feature active to explicitly opt-in to unstable features");
1115

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

158-
#[cfg(feature = "std")]
159-
mod if_std {
162+
#[cfg(feature = "alloc")]
163+
mod if_alloc {
160164
use super::*;
161165

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

167-
impl<T> Sink for ::std::vec::Vec<T> {
171+
impl<T> Sink for ::alloc::vec::Vec<T> {
168172
type SinkItem = T;
169173
type SinkError = VecSinkError;
170174

@@ -187,7 +191,7 @@ mod if_std {
187191
}
188192
}
189193

190-
impl<T> Sink for ::std::collections::VecDeque<T> {
194+
impl<T> Sink for ::alloc::collections::VecDeque<T> {
191195
type SinkItem = T;
192196
type SinkError = VecSinkError;
193197

@@ -210,7 +214,7 @@ mod if_std {
210214
}
211215
}
212216

213-
impl<S: ?Sized + Sink + Unpin> Sink for ::std::boxed::Box<S> {
217+
impl<S: ?Sized + Sink + Unpin> Sink for ::alloc::boxed::Box<S> {
214218
type SinkItem = S::SinkItem;
215219
type SinkError = S::SinkError;
216220

@@ -232,8 +236,8 @@ mod if_std {
232236
}
233237
}
234238

235-
#[cfg(feature = "std")]
236-
pub use self::if_std::*;
239+
#[cfg(feature = "alloc")]
240+
pub use self::if_alloc::*;
237241

238242
#[cfg(feature = "either")]
239243
use either::Either;

futures-util/Cargo.toml

+4-2
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,13 @@ Common utilities and extension traits for the futures-rs library.
1515
name = "futures_util"
1616

1717
[features]
18-
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"]
18+
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"]
1919
default = ["std", "futures-core-preview/either", "futures-sink-preview/either"]
2020
compat = ["std", "futures_01"]
2121
io-compat = ["compat", "tokio-io"]
2222
bench = []
23-
nightly = []
23+
nightly = ["futures-core-preview/nightly", "futures-sink-preview/nightly"]
24+
alloc = ["futures-core-preview/alloc", "futures-sink-preview/alloc", "alloc-shim/alloc"]
2425

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

4143
[dev-dependencies]
4244
futures-preview = { path = "../futures", version = "=0.3.0-alpha.12" }

futures-util/src/future/abortable.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@ use crate::task::AtomicWaker;
22
use futures_core::future::Future;
33
use futures_core::task::{LocalWaker, Poll};
44
use pin_utils::unsafe_pinned;
5-
use std::pin::Pin;
6-
use std::sync::Arc;
7-
use std::sync::atomic::{AtomicBool, Ordering};
5+
use core::pin::Pin;
6+
use core::sync::atomic::{AtomicBool, Ordering};
7+
use alloc::sync::Arc;
88

99
/// A future which can be remotely short-circuited using an `AbortHandle`.
1010
#[derive(Debug, Clone)]

futures-util/src/future/join_all.rs

+8-8
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
//! Definition of the `JoinAll` combinator, waiting for all of a list of futures
22
//! to finish.
33
4-
use std::fmt;
5-
use std::future::Future;
6-
use std::iter::FromIterator;
7-
use std::mem;
8-
use std::pin::Pin;
9-
use std::prelude::v1::*;
10-
use std::task::Poll;
4+
use core::fmt;
5+
use core::future::Future;
6+
use core::iter::FromIterator;
7+
use core::mem;
8+
use core::pin::Pin;
9+
use alloc::prelude::*;
10+
use alloc::task::Poll;
1111

1212
#[derive(Debug)]
1313
enum ElemState<F>
@@ -129,7 +129,7 @@ where
129129

130130
fn poll(
131131
mut self: Pin<&mut Self>,
132-
lw: &::std::task::LocalWaker,
132+
lw: &::alloc::task::LocalWaker,
133133
) -> Poll<Self::Output> {
134134
let mut all_done = true;
135135

futures-util/src/future/mod.rs

+7-5
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ use core::pin::Pin;
77
use futures_core::future::Future;
88
use futures_core::stream::Stream;
99
use futures_core::task::{LocalWaker, Poll};
10+
#[cfg(feature = "alloc")]
11+
use alloc::prelude::*;
1012

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

70-
#[cfg(feature = "std")]
72+
#[cfg(feature = "alloc")]
7173
mod abortable;
72-
#[cfg(feature = "std")]
74+
#[cfg(feature = "alloc")]
7375
pub use self::abortable::{abortable, Abortable, AbortHandle, AbortRegistration, Aborted};
7476

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

85-
#[cfg(feature = "std")]
87+
#[cfg(feature = "alloc")]
8688
mod join_all;
8789

88-
#[cfg(feature = "std")]
90+
#[cfg(feature = "alloc")]
8991
pub use self::join_all::{join_all, JoinAll};
9092

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

655657
/// Wrap the future in a Box, pinning it.
656-
#[cfg(feature = "std")]
658+
#[cfg(feature = "alloc")]
657659
fn boxed(self) -> Pin<Box<Self>>
658660
where Self: Sized
659661
{

futures-util/src/lib.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,17 @@
44
#![feature(futures_api, box_into_pin)]
55
#![cfg_attr(feature = "std", feature(async_await, await_macro))]
66
#![cfg_attr(feature = "nightly", feature(cfg_target_has_atomic))]
7+
#![cfg_attr(all(feature = "alloc", not(feature = "std")), feature(alloc))]
78

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

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

15+
#[cfg(all(feature = "alloc", not(any(feature = "std", feature = "nightly"))))]
16+
compile_error!("The `alloc` feature without `std` requires the `nightly` feature active to explicitly opt-in to unstable features");
17+
1418
#[macro_use]
1519
mod macros;
1620

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

92-
#[cfg(feature = "std")]
96+
#[cfg(feature = "alloc")]
9397
pub mod lock;

futures-util/src/lock/bilock.rs

+12-9
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,19 @@
33

44
use futures_core::future::Future;
55
use futures_core::task::{LocalWaker, Poll, Waker};
6+
use core::cell::UnsafeCell;
7+
use core::fmt;
8+
use core::mem;
9+
use core::ops::{Deref, DerefMut};
10+
use core::pin::Pin;
11+
use core::sync::atomic::AtomicUsize;
12+
use core::sync::atomic::Ordering::SeqCst;
13+
use alloc::boxed::Box;
14+
use alloc::sync::Arc;
15+
#[cfg(feature = "std")]
616
use std::any::Any;
7-
use std::boxed::Box;
8-
use std::cell::UnsafeCell;
17+
#[cfg(feature = "std")]
918
use std::error::Error;
10-
use std::fmt;
11-
use std::mem;
12-
use std::ops::{Deref, DerefMut};
13-
use std::pin::Pin;
14-
use std::sync::Arc;
15-
use std::sync::atomic::AtomicUsize;
16-
use std::sync::atomic::Ordering::SeqCst;
1719

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

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

0 commit comments

Comments
 (0)