Upgrade rust/crates/futures to 0.3.7

Test: make all rust crates
Change-Id: If97a17007e814752392c4c66508c46a366437f0b
diff --git a/Android.bp b/Android.bp
index 7510d2d..2061372 100644
--- a/Android.bp
+++ b/Android.bp
@@ -26,25 +26,23 @@
 }
 
 // dependent_library ["feature_list"]
-//   futures-channel-0.3.5 "alloc,futures-sink,sink,std"
-//   futures-core-0.3.5 "alloc,std"
-//   futures-executor-0.3.5 "default,num_cpus,std,thread-pool"
-//   futures-io-0.3.5 "std"
-//   futures-macro-0.3.5
-//   futures-sink-0.3.5 "alloc,std"
-//   futures-task-0.3.5 "alloc,once_cell,std"
-//   futures-util-0.3.5 "alloc,async-await,async-await-macro,channel,futures-channel,futures-io,futures-macro,futures-sink,io,memchr,proc-macro-hack,proc-macro-nested,sink,slab,std"
-//   libc-0.2.72 "default,std"
+//   futures-channel-0.3.7 "alloc,futures-sink,sink,std"
+//   futures-core-0.3.7 "alloc,std"
+//   futures-executor-0.3.7 "std"
+//   futures-io-0.3.7 "std"
+//   futures-macro-0.3.7
+//   futures-sink-0.3.7 "alloc,std"
+//   futures-task-0.3.7 "alloc,once_cell,std"
+//   futures-util-0.3.7 "alloc,async-await,async-await-macro,channel,futures-channel,futures-io,futures-macro,futures-sink,io,memchr,proc-macro-hack,proc-macro-nested,sink,slab,std"
 //   memchr-2.3.3 "default,std"
-//   num_cpus-1.13.0
-//   once_cell-1.4.0 "std"
-//   pin-project-0.4.22
-//   pin-project-internal-0.4.22
+//   once_cell-1.4.1 "std"
+//   pin-project-1.0.1
+//   pin-project-internal-1.0.1
 //   pin-utils-0.1.0
-//   proc-macro-hack-0.5.16
+//   proc-macro-hack-0.5.18
 //   proc-macro-nested-0.1.6
-//   proc-macro2-1.0.18 "default,proc-macro"
+//   proc-macro2-1.0.24 "default,proc-macro"
 //   quote-1.0.7 "default,proc-macro"
 //   slab-0.4.2
-//   syn-1.0.33 "clone-impls,default,derive,full,parsing,printing,proc-macro,quote,visit-mut"
+//   syn-1.0.48 "clone-impls,default,derive,full,parsing,printing,proc-macro,quote,visit-mut"
 //   unicode-xid-0.2.1 "default"
diff --git a/Cargo.toml b/Cargo.toml
index 290b3cc..fb21673 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -13,11 +13,11 @@
 [package]
 edition = "2018"
 name = "futures"
-version = "0.3.5"
+version = "0.3.7"
 authors = ["Alex Crichton <alex@alexcrichton.com>"]
 description = "An implementation of futures and streams featuring zero allocations,\ncomposability, and iterator-like interfaces.\n"
 homepage = "https://rust-lang.github.io/futures-rs"
-documentation = "https://docs.rs/futures/0.3.5"
+documentation = "https://docs.rs/futures/0.3.7"
 readme = "../README.md"
 keywords = ["futures", "async", "future"]
 categories = ["asynchronous"]
@@ -25,54 +25,40 @@
 repository = "https://github.com/rust-lang/futures-rs"
 [package.metadata.docs.rs]
 all-features = true
+rustdoc-args = ["--cfg", "docsrs"]
 
 [package.metadata.playground]
 features = ["std", "async-await", "compat", "io-compat", "executor", "thread-pool"]
 [dependencies.futures-channel]
-version = "0.3.5"
+version = "0.3.7"
 features = ["sink"]
 default-features = false
 
 [dependencies.futures-core]
-version = "0.3.5"
+version = "0.3.7"
 default-features = false
 
 [dependencies.futures-executor]
-version = "0.3.5"
+version = "0.3.7"
 optional = true
 default-features = false
 
 [dependencies.futures-io]
-version = "0.3.5"
+version = "0.3.7"
 default-features = false
 
 [dependencies.futures-sink]
-version = "0.3.5"
+version = "0.3.7"
 default-features = false
 
 [dependencies.futures-task]
-version = "0.3.5"
+version = "0.3.7"
 default-features = false
 
 [dependencies.futures-util]
-version = "0.3.5"
+version = "0.3.7"
 features = ["sink"]
 default-features = false
-[dev-dependencies.assert_matches]
-version = "1.3.0"
-
-[dev-dependencies.futures-executor]
-version = "0.3.5"
-features = ["thread-pool"]
-
-[dev-dependencies.futures-test]
-version = "0.3.5"
-
-[dev-dependencies.pin-utils]
-version = "0.1.0"
-
-[dev-dependencies.tokio]
-version = "0.1.11"
 
 [features]
 alloc = ["futures-core/alloc", "futures-task/alloc", "futures-sink/alloc", "futures-channel/alloc", "futures-util/alloc"]
diff --git a/Cargo.toml.orig b/Cargo.toml.orig
index c7288ed..342441b 100644
--- a/Cargo.toml.orig
+++ b/Cargo.toml.orig
@@ -1,14 +1,14 @@
 [package]
 name = "futures"
 edition = "2018"
-version = "0.3.5"
+version = "0.3.7"
 authors = ["Alex Crichton <alex@alexcrichton.com>"]
 license = "MIT OR Apache-2.0"
 readme = "../README.md"
 keywords = ["futures", "async", "future"]
 repository = "https://github.com/rust-lang/futures-rs"
 homepage = "https://rust-lang.github.io/futures-rs"
-documentation = "https://docs.rs/futures/0.3.5"
+documentation = "https://docs.rs/futures/0.3.7"
 description = """
 An implementation of futures and streams featuring zero allocations,
 composability, and iterator-like interfaces.
@@ -19,20 +19,13 @@
 travis-ci = { repository = "rust-lang/futures-rs" }
 
 [dependencies]
-futures-core = { path = "../futures-core", version = "0.3.5", default-features = false }
-futures-task = { path = "../futures-task", version = "0.3.5", default-features = false }
-futures-channel = { path = "../futures-channel", version = "0.3.5", default-features = false, features = ["sink"] }
-futures-executor = { path = "../futures-executor", version = "0.3.5", default-features = false, optional = true }
-futures-io = { path = "../futures-io", version = "0.3.5", default-features = false }
-futures-sink = { path = "../futures-sink", version = "0.3.5", default-features = false }
-futures-util = { path = "../futures-util", version = "0.3.5", default-features = false, features = ["sink"] }
-
-[dev-dependencies]
-pin-utils = "0.1.0"
-futures-executor = { path = "../futures-executor", version = "0.3.5", features = ["thread-pool"] }
-futures-test = { path = "../futures-test", version = "0.3.5" }
-tokio = "0.1.11"
-assert_matches = "1.3.0"
+futures-core = { path = "../futures-core", version = "0.3.7", default-features = false }
+futures-task = { path = "../futures-task", version = "0.3.7", default-features = false }
+futures-channel = { path = "../futures-channel", version = "0.3.7", default-features = false, features = ["sink"] }
+futures-executor = { path = "../futures-executor", version = "0.3.7", default-features = false, optional = true }
+futures-io = { path = "../futures-io", version = "0.3.7", default-features = false }
+futures-sink = { path = "../futures-sink", version = "0.3.7", default-features = false }
+futures-util = { path = "../futures-util", version = "0.3.7", default-features = false, features = ["sink"] }
 
 [features]
 default = ["std", "async-await", "executor"]
@@ -55,6 +48,7 @@
 
 [package.metadata.docs.rs]
 all-features = true
+rustdoc-args = ["--cfg", "docsrs"]
 
 [package.metadata.playground]
 features = ["std", "async-await", "compat", "io-compat", "executor", "thread-pool"]
diff --git a/METADATA b/METADATA
index 1ab775c..e7e876a 100644
--- a/METADATA
+++ b/METADATA
@@ -7,13 +7,13 @@
   }
   url {
     type: ARCHIVE
-    value: "https://static.crates.io/crates/futures/futures-0.3.5.crate"
+    value: "https://static.crates.io/crates/futures/futures-0.3.7.crate"
   }
-  version: "0.3.5"
+  version: "0.3.7"
   license_type: NOTICE
   last_upgrade_date {
     year: 2020
-    month: 5
-    day: 8
+    month: 10
+    day: 25
   }
 }
diff --git a/src/lib.rs b/src/lib.rs
index e6380d2..072c2da 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -88,9 +88,16 @@
 #![cfg_attr(test, warn(single_use_lifetimes))]
 #![warn(clippy::all)]
 
+// mem::take requires Rust 1.40, matches! requires Rust 1.42
+// Can be removed if the minimum supported version increased or if https://github.com/rust-lang/rust-clippy/issues/3941
+// get's implemented.
+#![allow(clippy::mem_replace_with_default, clippy::match_like_matches_macro)]
+
 #![doc(test(attr(deny(warnings), allow(dead_code, unused_assignments, unused_variables))))]
 
-#![doc(html_root_url = "https://docs.rs/futures/0.3.5")]
+#![doc(html_root_url = "https://docs.rs/futures/0.3.7")]
+
+#![cfg_attr(docsrs, feature(doc_cfg))]
 
 #[cfg(all(feature = "cfg-target-has-atomic", not(feature = "unstable")))]
 compile_error!("The `cfg-target-has-atomic` feature requires the `unstable` feature as an explicit opt-in to unstable features");
@@ -148,6 +155,7 @@
 }
 
 #[cfg(feature = "compat")]
+#[cfg_attr(docsrs, doc(cfg(feature = "compat")))]
 pub mod compat {
     //! Interop between `futures` 0.1 and 0.3.
     //!
@@ -168,6 +176,7 @@
     };
 
     #[cfg(feature = "io-compat")]
+    #[cfg_attr(docsrs, doc(cfg(feature = "io-compat")))]
     pub use futures_util::compat::{
         AsyncRead01CompatExt,
         AsyncWrite01CompatExt,
@@ -225,6 +234,7 @@
     };
 
     #[cfg(feature = "thread-pool")]
+    #[cfg_attr(docsrs, doc(cfg(feature = "thread-pool")))]
     pub use futures_executor::{ThreadPool, ThreadPoolBuilder};
 }
 
@@ -327,12 +337,13 @@
     };
 
     #[cfg(feature = "read-initializer")]
+    #[cfg_attr(docsrs, doc(cfg(feature = "read-initializer")))]
     pub use futures_io::Initializer;
 
     pub use futures_util::io::{
         AsyncReadExt, AsyncWriteExt, AsyncSeekExt, AsyncBufReadExt, AllowStdIo,
         BufReader, BufWriter, Cursor, Chain, Close, copy, Copy, copy_buf, CopyBuf,
-        empty, Empty, Flush, IntoSink, Lines, Read, ReadExact, ReadHalf,
+        empty, Empty, FillBuf, Flush, IntoSink, Lines, Read, ReadExact, ReadHalf,
         ReadLine, ReadToEnd, ReadToString, ReadUntil, ReadVectored, repeat,
         Repeat, ReuniteError, Seek, sink, Sink, Take, Window, Write, WriteAll, WriteHalf,
         WriteVectored,
@@ -348,6 +359,7 @@
     //! library is activated, and it is activated by default.
 
     #[cfg(feature = "bilock")]
+    #[cfg_attr(docsrs, doc(cfg(feature = "bilock")))]
     pub use futures_util::lock::{BiLock, BiLockAcquire, BiLockGuard, ReuniteError};
 
     #[cfg(feature = "std")]
@@ -422,7 +434,7 @@
     //!   asynchronously produce a sequence of values.
     //! - The [`StreamExt`](crate::stream::StreamExt) trait, which provides
     //!   adapters for chaining and composing streams.
-    //! - Top-level stream contructors like [`iter`](crate::stream::iter)
+    //! - Top-level stream constructors like [`iter`](crate::stream::iter)
     //!   which creates a stream from an iterator.
 
     pub use futures_core::stream::{
@@ -446,14 +458,14 @@
         StreamExt,
         Chain, Collect, Concat, Enumerate, Filter, FilterMap, FlatMap, Flatten,
         Fold, Forward, ForEach, Fuse, StreamFuture, Inspect, Map, Next,
-        SelectNextSome, Peek, Peekable, Scan, Skip, SkipWhile, Take, TakeWhile,
-        Then, Zip,
+        SelectNextSome, Peek, Peekable, Scan, Skip, SkipWhile, Take, TakeUntil,
+        TakeWhile, Then, Zip,
 
         TryStreamExt,
         AndThen, ErrInto, MapOk, MapErr, OrElse,
         InspectOk, InspectErr,
         TryNext, TryForEach, TryFilter, TryFilterMap, TryFlatten,
-        TryCollect, TryConcat, TryFold, TrySkipWhile,
+        TryCollect, TryConcat, TryFold, TrySkipWhile, TryTakeWhile,
         IntoStream,
     };
 
diff --git a/tests/_require_features.rs b/tests/_require_features.rs
new file mode 100644
index 0000000..da76dcd
--- /dev/null
+++ b/tests/_require_features.rs
@@ -0,0 +1,8 @@
+#[cfg(not(all(
+    feature = "std", feature = "alloc", feature = "async-await",
+    feature = "compat", feature = "io-compat",
+    feature = "executor", feature = "thread-pool",
+)))]
+compile_error!("`futures` tests must have all stable features activated: \
+    use `--all-features` or `--features default,thread-pool,io-compat`"
+);
diff --git a/tests/abortable.rs b/tests/abortable.rs
index fcbabe9..6b5a25c 100644
--- a/tests/abortable.rs
+++ b/tests/abortable.rs
@@ -1,4 +1,3 @@
-#[cfg(all(feature = "alloc", feature = "executor"))]
 #[test]
 fn abortable_works() {
     use futures::channel::oneshot;
@@ -12,7 +11,6 @@
     assert_eq!(Err(Aborted), block_on(abortable_rx));
 }
 
-#[cfg(all(feature = "alloc", feature = "executor"))]
 #[test]
 fn abortable_awakens() {
     use futures::channel::oneshot;
@@ -33,7 +31,6 @@
     assert_eq!(Poll::Ready(Err(Aborted)), abortable_rx.poll_unpin(&mut cx));
 }
 
-#[cfg(all(feature = "alloc", feature = "executor"))]
 #[test]
 fn abortable_resolves() {
     use futures::channel::oneshot;
diff --git a/tests/arc_wake.rs b/tests/arc_wake.rs
index 38217f0..2830daf 100644
--- a/tests/arc_wake.rs
+++ b/tests/arc_wake.rs
@@ -1,4 +1,3 @@
-#[cfg(feature = "alloc")]
 mod countingwaker {
     use futures::task::{self, ArcWake, Waker};
     use std::sync::{Arc, Mutex};
@@ -60,7 +59,6 @@
     }
 }
 
-#[cfg(feature = "alloc")]
 #[test]
 fn proper_refcount_on_wake_panic() {
     use futures::task::{self, ArcWake, Waker};
diff --git a/tests/async_await_macros.rs b/tests/async_await_macros.rs
index fd2a349..b521038 100644
--- a/tests/async_await_macros.rs
+++ b/tests/async_await_macros.rs
@@ -1,6 +1,3 @@
-#![recursion_limit="128"]
-
-#[cfg(all(feature = "async-await", feature = "std", feature = "executor"))]
 #[test]
 fn poll_and_pending() {
     use futures::{pending, pin_mut, poll};
@@ -15,7 +12,6 @@
     });
 }
 
-#[cfg(all(feature = "async-await", feature = "std", feature = "executor"))]
 #[test]
 fn join() {
     use futures::{pin_mut, poll, join};
@@ -41,7 +37,6 @@
     });
 }
 
-#[cfg(all(feature = "async-await", feature = "std", feature = "executor"))]
 #[test]
 fn select() {
     use futures::select;
@@ -65,7 +60,6 @@
     assert!(ran);
 }
 
-#[cfg(all(feature = "alloc", feature = "executor", feature = "async-await"))]
 #[test]
 fn select_biased() {
     use futures::channel::oneshot;
@@ -89,7 +83,6 @@
     assert!(ran);
 }
 
-#[cfg(all(feature = "async-await", feature = "std", feature = "executor"))]
 #[test]
 fn select_streams() {
     use futures::select;
@@ -139,7 +132,6 @@
     assert!(ran);
 }
 
-#[cfg(all(feature = "async-await", feature = "std", feature = "executor"))]
 #[test]
 fn select_can_move_uncompleted_futures() {
     use futures::select;
@@ -171,7 +163,6 @@
     assert!(ran);
 }
 
-#[cfg(all(feature = "async-await", feature = "std", feature = "executor"))]
 #[test]
 fn select_nested() {
     use futures::select;
@@ -192,7 +183,6 @@
     assert_eq!(res, 3);
 }
 
-#[cfg(all(feature = "async-await", feature = "std"))]
 #[test]
 fn select_size() {
     use futures::select;
@@ -217,7 +207,6 @@
     assert_eq!(::std::mem::size_of_val(&fut), 40);
 }
 
-#[cfg(all(feature = "async-await", feature = "std", feature = "executor"))]
 #[test]
 fn select_on_non_unpin_expressions() {
     use futures::select;
@@ -240,7 +229,6 @@
     assert_eq!(res, 5);
 }
 
-#[cfg(all(feature = "async-await", feature = "std", feature = "executor"))]
 #[test]
 fn select_on_non_unpin_expressions_with_default() {
     use futures::select;
@@ -264,7 +252,6 @@
     assert_eq!(res, 5);
 }
 
-#[cfg(all(feature = "async-await", feature = "std"))]
 #[test]
 fn select_on_non_unpin_size() {
     use futures::select;
@@ -287,7 +274,6 @@
     assert_eq!(32, std::mem::size_of_val(&fut));
 }
 
-#[cfg(all(feature = "async-await", feature = "std", feature = "executor"))]
 #[test]
 fn select_can_be_used_as_expression() {
     use futures::select;
@@ -303,7 +289,6 @@
     });
 }
 
-#[cfg(all(feature = "async-await", feature = "std", feature = "executor"))]
 #[test]
 fn select_with_default_can_be_used_as_expression() {
     use futures::select;
@@ -325,7 +310,6 @@
     });
 }
 
-#[cfg(all(feature = "async-await", feature = "std", feature = "executor"))]
 #[test]
 fn select_with_complete_can_be_used_as_expression() {
     use futures::select;
@@ -343,7 +327,6 @@
     });
 }
 
-#[cfg(all(feature = "async-await", feature = "std", feature = "executor"))]
 #[test]
 fn select_on_mutable_borrowing_future_with_same_borrow_in_block() {
     use futures::select;
@@ -364,7 +347,6 @@
     });
 }
 
-#[cfg(all(feature = "async-await", feature = "std", feature = "executor"))]
 #[test]
 fn select_on_mutable_borrowing_future_with_same_borrow_in_block_and_default() {
     use futures::select;
@@ -388,7 +370,6 @@
     });
 }
 
-#[cfg(feature = "async-await")]
 #[test]
 fn join_size() {
     use futures::join;
@@ -408,7 +389,6 @@
     assert_eq!(::std::mem::size_of_val(&fut), 28);
 }
 
-#[cfg(feature = "async-await")]
 #[test]
 fn try_join_size() {
     use futures::try_join;
@@ -428,7 +408,6 @@
     assert_eq!(::std::mem::size_of_val(&fut), 28);
 }
 
-#[cfg(feature = "async-await")]
 #[test]
 fn join_doesnt_require_unpin() {
     use futures::join;
@@ -438,7 +417,6 @@
     };
 }
 
-#[cfg(feature = "async-await")]
 #[test]
 fn try_join_doesnt_require_unpin() {
     use futures::try_join;
diff --git a/tests/atomic_waker.rs b/tests/atomic_waker.rs
index 5693bd0..bf15d0f 100644
--- a/tests/atomic_waker.rs
+++ b/tests/atomic_waker.rs
@@ -1,4 +1,3 @@
-#[cfg(feature = "executor")]
 #[test]
 fn basic() {
     use std::sync::atomic::AtomicUsize;
diff --git a/tests/buffer_unordered.rs b/tests/buffer_unordered.rs
index 6485a1e..5c8b8bf 100644
--- a/tests/buffer_unordered.rs
+++ b/tests/buffer_unordered.rs
@@ -1,4 +1,3 @@
-#[cfg(all(feature = "alloc", feature = "std", feature = "executor"))]
 #[test]
 #[ignore] // FIXME: https://github.com/rust-lang/futures-rs/issues/1790
 fn works() {
diff --git a/tests/compat.rs b/tests/compat.rs
index 39adc7c..ba4c897 100644
--- a/tests/compat.rs
+++ b/tests/compat.rs
@@ -1,5 +1,3 @@
-#![cfg(feature = "compat")]
-
 use tokio::timer::Delay;
 use tokio::runtime::Runtime;
 use std::time::Instant;
diff --git a/tests/eager_drop.rs b/tests/eager_drop.rs
index bfb60a7..11edb1b 100644
--- a/tests/eager_drop.rs
+++ b/tests/eager_drop.rs
@@ -43,29 +43,26 @@
 }
 
 mod channelled {
-    use pin_utils::unsafe_pinned;
     use futures::future::Future;
-    use std::pin::Pin;
     use futures::task::{Context,Poll};
+    use pin_project::pin_project;
+    use std::pin::Pin;
 
+    #[pin_project]
     struct FutureData<F, T> {
         _data: T,
+        #[pin]
         future: F,
     }
 
-    impl<F, T> FutureData<F, T> {
-        unsafe_pinned!(future: F);
-    }
-
     impl<F: Future, T: Send + 'static> Future for FutureData<F, T> {
         type Output = F::Output;
 
         fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<F::Output> {
-            self.future().poll(cx)
+            self.project().future.poll(cx)
         }
     }
 
-    #[cfg(feature = "alloc")]
     #[test]
     fn then_drops_eagerly() {
         use futures::channel::oneshot;
@@ -90,7 +87,6 @@
         rx2.recv().unwrap();
     }
 
-    #[cfg(feature = "alloc")]
     #[test]
     fn and_then_drops_eagerly() {
         use futures::channel::oneshot;
@@ -115,7 +111,6 @@
         rx2.recv().unwrap();
     }
 
-    #[cfg(feature = "alloc")]
     #[test]
     fn or_else_drops_eagerly() {
         use futures::channel::oneshot;
diff --git a/tests/eventual.rs b/tests/eventual.rs
index 6835588..bff000d 100644
--- a/tests/eventual.rs
+++ b/tests/eventual.rs
@@ -1,4 +1,3 @@
-#![cfg(all(feature = "executor", feature = "thread-pool"))]
 use futures::channel::oneshot;
 use futures::executor::ThreadPool;
 use futures::future::{self, ok, Future, FutureExt, TryFutureExt};
diff --git a/tests/future_try_flatten_stream.rs b/tests/future_try_flatten_stream.rs
index aa85ed0..4a614f9 100644
--- a/tests/future_try_flatten_stream.rs
+++ b/tests/future_try_flatten_stream.rs
@@ -1,4 +1,3 @@
-#[cfg(feature = "executor")]
 #[test]
 fn successful_future() {
     use futures::executor::block_on_stream;
@@ -16,7 +15,6 @@
     assert_eq!(None, iter.next());
 }
 
-#[cfg(feature = "executor")]
 #[test]
 fn failed_future() {
     use core::marker::PhantomData;
diff --git a/tests/futures_ordered.rs b/tests/futures_ordered.rs
index 74a220a..7f21c82 100644
--- a/tests/futures_ordered.rs
+++ b/tests/futures_ordered.rs
@@ -1,4 +1,3 @@
-#[cfg(all(feature = "alloc", feature="executor"))]
 #[test]
 fn works_1() {
     use futures::channel::oneshot;
@@ -25,7 +24,6 @@
     assert_eq!(None, iter.next());
 }
 
-#[cfg(feature = "alloc")]
 #[test]
 fn works_2() {
     use futures::channel::oneshot;
@@ -51,7 +49,6 @@
     assert!(stream.poll_next_unpin(&mut cx).is_ready());
 }
 
-#[cfg(feature = "executor")]
 #[test]
 fn from_iterator() {
     use futures::executor::block_on;
@@ -67,7 +64,6 @@
     assert_eq!(block_on(stream.collect::<Vec<_>>()), vec![1,2,3]);
 }
 
-#[cfg(feature = "alloc")]
 #[test]
 fn queue_never_unblocked() {
     use futures::channel::oneshot;
diff --git a/tests/futures_unordered.rs b/tests/futures_unordered.rs
index 3285903..4dd0deb 100644
--- a/tests/futures_unordered.rs
+++ b/tests/futures_unordered.rs
@@ -1,4 +1,3 @@
-#[cfg(feature = "alloc")]
 #[test]
 fn is_terminated() {
     use futures::future;
@@ -31,7 +30,6 @@
     assert_eq!(tasks.is_terminated(), true);
 }
 
-#[cfg(all(feature = "alloc", feature = "executor"))]
 #[test]
 fn works_1() {
     use futures::channel::oneshot;
@@ -58,7 +56,6 @@
     assert_eq!(None, iter.next());
 }
 
-#[cfg(feature = "alloc")]
 #[test]
 fn works_2() {
     use futures::channel::oneshot;
@@ -88,7 +85,6 @@
     assert_eq!(stream.poll_next_unpin(&mut cx), Poll::Ready(None));
 }
 
-#[cfg(feature = "executor")]
 #[test]
 fn from_iterator() {
     use futures::executor::block_on;
@@ -106,7 +102,6 @@
     assert_eq!(block_on(stream.collect::<Vec<_>>()), vec![1, 2, 3]);
 }
 
-#[cfg(feature = "alloc")]
 #[test]
 fn finished_future() {
     use std::marker::Unpin;
@@ -138,7 +133,6 @@
     assert!(stream.poll_next_unpin(cx).is_pending());
 }
 
-#[cfg(all(feature = "alloc", feature = "executor"))]
 #[test]
 fn iter_mut_cancel() {
     use futures::channel::oneshot;
@@ -169,7 +163,6 @@
     assert_eq!(iter.next(), None);
 }
 
-#[cfg(feature = "alloc")]
 #[test]
 fn iter_mut_len() {
     use futures::future;
@@ -194,7 +187,6 @@
     assert!(iter_mut.next().is_none());
 }
 
-#[cfg(feature = "executor")]
 #[test]
 fn iter_cancel() {
     use std::marker::Unpin;
@@ -249,7 +241,6 @@
     assert_eq!(iter.next(), None);
 }
 
-#[cfg(feature = "alloc")]
 #[test]
 fn iter_len() {
     use futures::future;
@@ -274,7 +265,6 @@
     assert!(iter.next().is_none());
 }
 
-#[cfg(feature = "alloc")]
 #[test]
 fn futures_not_moved_after_poll() {
     use futures::future;
@@ -292,7 +282,6 @@
     assert_stream_done!(stream);
 }
 
-#[cfg(feature = "alloc")]
 #[test]
 fn len_valid_during_out_of_order_completion() {
     use futures::channel::oneshot;
diff --git a/tests/inspect.rs b/tests/inspect.rs
index 4cbe477..375778b 100644
--- a/tests/inspect.rs
+++ b/tests/inspect.rs
@@ -1,4 +1,3 @@
-#[cfg(feature = "executor")]
 #[test]
 fn smoke() {
     use futures::executor::block_on;
diff --git a/tests/io_buf_reader.rs b/tests/io_buf_reader.rs
index 07d934d..f8f9d14 100644
--- a/tests/io_buf_reader.rs
+++ b/tests/io_buf_reader.rs
@@ -1,4 +1,3 @@
-#[cfg(any(feature = "std", feature = "executor"))]
 macro_rules! run_fill_buf {
     ($reader:expr) => {{
         use futures_test::task::noop_context;
@@ -14,7 +13,6 @@
     }};
 }
 
-#[cfg(any(feature = "std", feature = "executor"))]
 mod util {
     use futures::future::Future;
     pub fn run<F: Future + Unpin>(mut f: F) -> F::Output {
@@ -31,7 +29,6 @@
     }
 }
 
-#[cfg(feature = "std")]
 mod maybe_pending {
     use futures::task::{Context,Poll};
     use std::{cmp,io};
@@ -85,7 +82,6 @@
     }
 }
 
-#[cfg(feature = "executor")]
 #[test]
 fn test_buffered_reader() {
     use futures::executor::block_on;
@@ -126,7 +122,6 @@
     assert_eq!(block_on(reader.read(&mut buf)).unwrap(), 0);
 }
 
-#[cfg(feature = "executor")]
 #[test]
 fn test_buffered_reader_seek() {
     use futures::executor::block_on;
@@ -147,7 +142,6 @@
     assert_eq!(block_on(reader.seek(SeekFrom::Current(-2))).ok(), Some(3));
 }
 
-#[cfg(feature = "executor")]
 #[test]
 fn test_buffered_reader_seek_underflow() {
     use futures::executor::block_on;
@@ -198,7 +192,6 @@
     assert_eq!(reader.get_ref().get_ref().pos, expected);
 }
 
-#[cfg(feature = "executor")]
 #[test]
 fn test_short_reads() {
     use futures::executor::block_on;
@@ -232,7 +225,6 @@
     assert_eq!(block_on(reader.read(&mut buf)).unwrap(), 0);
 }
 
-#[cfg(feature = "std")]
 #[test]
 fn maybe_pending() {
     use futures::io::{AsyncReadExt, BufReader};
@@ -274,7 +266,6 @@
     assert_eq!(run(reader.read(&mut buf)).unwrap(), 0);
 }
 
-#[cfg(feature = "std")]
 #[test]
 fn maybe_pending_buf_read() {
     use futures::io::{AsyncBufReadExt, BufReader};
@@ -298,7 +289,6 @@
 }
 
 // https://github.com/rust-lang/futures-rs/pull/1573#discussion_r281162309
-#[cfg(feature = "std")]
 #[test]
 fn maybe_pending_seek() {
     use futures::io::{AsyncBufRead, AsyncSeek, AsyncSeekExt, AsyncRead, BufReader,
diff --git a/tests/io_buf_writer.rs b/tests/io_buf_writer.rs
index 935335b..d58a6d8 100644
--- a/tests/io_buf_writer.rs
+++ b/tests/io_buf_writer.rs
@@ -1,4 +1,3 @@
-#[cfg(feature = "std")]
 mod maybe_pending {
     use futures::io::AsyncWrite;
     use futures::task::{Context, Poll};
@@ -41,7 +40,6 @@
     }
 }
 
-#[cfg(any(feature = "std", feature = "executor"))]
 mod util {
     use futures::future::Future;
 
@@ -59,7 +57,6 @@
     }
 }
 
-#[cfg(feature = "executor")]
 #[test]
 fn buf_writer() {
     use futures::executor::block_on;
@@ -105,7 +102,6 @@
     assert_eq!(*writer.get_ref(), [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]);
 }
 
-#[cfg(feature = "executor")]
 #[test]
 fn buf_writer_inner_flushes() {
     use futures::executor::block_on;
@@ -119,7 +115,6 @@
     assert_eq!(w, [0, 1]);
 }
 
-#[cfg(feature = "executor")]
 #[test]
 fn buf_writer_seek() {
     use futures::executor::block_on;
@@ -138,7 +133,6 @@
     assert_eq!(&w.into_inner().into_inner()[..], &[0, 1, 8, 9, 4, 5, 6, 7]);
 }
 
-#[cfg(feature = "std")]
 #[test]
 fn maybe_pending_buf_writer() {
     use futures::io::{AsyncWriteExt, BufWriter};
@@ -186,7 +180,6 @@
     assert_eq!(&writer.get_ref().inner, &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]);
 }
 
-#[cfg(feature = "std")]
 #[test]
 fn maybe_pending_buf_writer_inner_flushes() {
     use futures::io::{AsyncWriteExt, BufWriter};
@@ -202,7 +195,6 @@
     assert_eq!(w, [0, 1]);
 }
 
-#[cfg(feature = "std")]
 #[test]
 fn maybe_pending_buf_writer_seek() {
     use futures::io::{AsyncSeek, AsyncSeekExt, AsyncWrite, AsyncWriteExt, BufWriter, Cursor, SeekFrom};
diff --git a/tests/io_cursor.rs b/tests/io_cursor.rs
index 0a93c83..4ba6342 100644
--- a/tests/io_cursor.rs
+++ b/tests/io_cursor.rs
@@ -1,4 +1,3 @@
-#[cfg(all(feature = "std", feature = "executor"))]
 #[test]
 fn cursor_asyncwrite_vec() {
     use assert_matches::assert_matches;
@@ -17,7 +16,6 @@
     assert_eq!(cursor.into_inner(), [1, 2, 3, 4, 5, 6, 6, 7]);
 }
 
-#[cfg(all(feature = "std", feature = "executor"))]
 #[test]
 fn cursor_asyncwrite_box() {
     use assert_matches::assert_matches;
diff --git a/tests/io_lines.rs b/tests/io_lines.rs
index e10edd0..2552c7c 100644
--- a/tests/io_lines.rs
+++ b/tests/io_lines.rs
@@ -1,4 +1,3 @@
-#[cfg(any(feature = "std", feature = "executor"))]
 mod util {
     use futures::future::Future;
 
@@ -16,7 +15,6 @@
     }
 }
 
-#[cfg(feature = "executor")]
 #[test]
 fn lines() {
     use futures::executor::block_on;
@@ -41,7 +39,6 @@
     assert!(block_on(s.next()).is_none());
 }
 
-#[cfg(feature = "std")]
 #[test]
 fn maybe_pending() {
     use futures::stream::{self, StreamExt, TryStreamExt};
diff --git a/tests/io_read.rs b/tests/io_read.rs
index ba68fcc..bc2a434 100644
--- a/tests/io_read.rs
+++ b/tests/io_read.rs
@@ -1,4 +1,3 @@
-#[cfg(feature = "std")]
 mod mock_reader {
     use futures::io::AsyncRead;
     use std::io;
@@ -28,7 +27,6 @@
 
 /// Verifies that the default implementation of `poll_read_vectored`
 /// calls `poll_read` with an empty slice if no buffers are provided.
-#[cfg(feature = "std")]
 #[test]
 fn read_vectored_no_buffers() {
     use futures::io::AsyncRead;
@@ -53,7 +51,6 @@
 
 /// Verifies that the default implementation of `poll_read_vectored`
 /// calls `poll_read` with the first non-empty buffer.
-#[cfg(feature = "std")]
 #[test]
 fn read_vectored_first_non_empty() {
     use futures::io::AsyncRead;
@@ -72,7 +69,7 @@
     let cx = &mut panic_context();
     let mut buf = [0; 4];
     let bufs = &mut [
-        io::IoSliceMut::new(&mut []), 
+        io::IoSliceMut::new(&mut []),
         io::IoSliceMut::new(&mut []),
         io::IoSliceMut::new(&mut buf),
     ];
@@ -82,4 +79,3 @@
     assert_eq!(res, Poll::Ready(Ok(4)));
     assert_eq!(buf, b"four"[..]);
 }
-
diff --git a/tests/io_read_exact.rs b/tests/io_read_exact.rs
index a772e34..bd4b36d 100644
--- a/tests/io_read_exact.rs
+++ b/tests/io_read_exact.rs
@@ -1,4 +1,3 @@
-#[cfg(feature = "executor")]
 #[test]
 fn read_exact() {
     use futures::executor::block_on;
diff --git a/tests/io_read_line.rs b/tests/io_read_line.rs
index ab25f26..51e8126 100644
--- a/tests/io_read_line.rs
+++ b/tests/io_read_line.rs
@@ -1,4 +1,3 @@
-#[cfg(feature = "executor")]
 #[test]
 fn read_line() {
     use futures::executor::block_on;
@@ -21,7 +20,6 @@
     assert_eq!(v, "");
 }
 
-#[cfg(feature = "std")]
 #[test]
 fn maybe_pending() {
     use futures::future::Future;
diff --git a/tests/io_read_to_string.rs b/tests/io_read_to_string.rs
index 0a79a22..2e9c00a 100644
--- a/tests/io_read_to_string.rs
+++ b/tests/io_read_to_string.rs
@@ -1,4 +1,3 @@
-#[cfg(all(feature = "std", feature = "executor"))]
 #[test]
 fn read_to_string() {
     use futures::executor::block_on;
@@ -19,7 +18,6 @@
     assert!(block_on(c.read_to_string(&mut v)).is_err());
 }
 
-#[cfg(feature = "std")]
 #[test]
 fn interleave_pending() {
     use futures::future::Future;
diff --git a/tests/io_read_until.rs b/tests/io_read_until.rs
index 1e018b7..6fa22ee 100644
--- a/tests/io_read_until.rs
+++ b/tests/io_read_until.rs
@@ -1,4 +1,3 @@
-#[cfg(feature = "executor")]
 #[test]
 fn read_until() {
     use futures::executor::block_on;
@@ -21,8 +20,6 @@
     assert_eq!(v, []);
 }
 
-
-#[cfg(feature = "std")]
 #[test]
 fn maybe_pending() {
     use futures::future::Future;
diff --git a/tests/io_window.rs b/tests/io_window.rs
index 8cc41a3..8f0d48b 100644
--- a/tests/io_window.rs
+++ b/tests/io_window.rs
@@ -1,14 +1,17 @@
-#![cfg(feature = "std")]
+#![allow(clippy::reversed_empty_ranges)] // This is intentional.
+
 use futures::io::Window;
 
 #[test]
 fn set() {
     let mut buffer = Window::new(&[1, 2, 3]);
     buffer.set(..3);
+    assert_eq!(buffer.as_ref(), &[1, 2, 3]);
     buffer.set(3..3);
+    assert_eq!(buffer.as_ref(), &[]);
     buffer.set(3..=2); // == 3..3
+    assert_eq!(buffer.as_ref(), &[]);
     buffer.set(0..2);
-
     assert_eq!(buffer.as_ref(), &[1, 2]);
 }
 
diff --git a/tests/io_write.rs b/tests/io_write.rs
index af0d5c3..165b3d3 100644
--- a/tests/io_write.rs
+++ b/tests/io_write.rs
@@ -1,4 +1,3 @@
-#[cfg(feature = "std")]
 mod mock_writer {
     use futures::io::AsyncWrite;
     use std::io;
@@ -36,7 +35,6 @@
 
 /// Verifies that the default implementation of `poll_write_vectored`
 /// calls `poll_write` with an empty slice if no buffers are provided.
-#[cfg(feature = "std")]
 #[test]
 fn write_vectored_no_buffers() {
     use futures::io::AsyncWrite;
@@ -61,7 +59,6 @@
 
 /// Verifies that the default implementation of `poll_write_vectored`
 /// calls `poll_write` with the first non-empty buffer.
-#[cfg(feature = "std")]
 #[test]
 fn write_vectored_first_non_empty() {
     use futures::io::AsyncWrite;
@@ -78,7 +75,7 @@
     });
     let cx = &mut panic_context();
     let bufs = &mut [
-        io::IoSlice::new(&[]), 
+        io::IoSlice::new(&[]),
         io::IoSlice::new(&[]),
         io::IoSlice::new(b"four")
     ];
@@ -87,4 +84,3 @@
     let res = res.map_err(|e| e.kind());
     assert_eq!(res, Poll::Ready(Ok(4)));
 }
-
diff --git a/tests/join_all.rs b/tests/join_all.rs
index 0d8fbf2..1450679 100644
--- a/tests/join_all.rs
+++ b/tests/join_all.rs
@@ -1,4 +1,3 @@
-#[cfg(feature = "executor")]
 mod util {
     use std::future::Future;
     use std::fmt::Debug;
@@ -15,7 +14,6 @@
     }
 }
 
-#[cfg(feature = "executor")]
 #[test]
 fn collect_collects() {
     use futures_util::future::{join_all,ready};
@@ -28,14 +26,13 @@
     // TODO: needs more tests
 }
 
-#[cfg(feature = "executor")]
 #[test]
 fn join_all_iter_lifetime() {
     use futures_util::future::{join_all,ready};
     use std::future::Future;
     // In futures-rs version 0.1, this function would fail to typecheck due to an overly
     // conservative type parameterization of `JoinAll`.
-    fn sizes<'a>(bufs: Vec<&'a [u8]>) -> Box<dyn Future<Output = Vec<usize>> + Unpin> {
+    fn sizes(bufs: Vec<&[u8]>) -> Box<dyn Future<Output = Vec<usize>> + Unpin> {
         let iter = bufs.into_iter().map(|b| ready::<usize>(b.len()));
         Box::new(join_all(iter))
     }
@@ -43,7 +40,6 @@
     util::assert_done(|| sizes(vec![&[1,2,3], &[], &[0]]), vec![3 as usize, 0, 1]);
 }
 
-#[cfg(feature = "executor")]
 #[test]
 fn join_all_from_iter() {
     use futures_util::future::{JoinAll,ready};
diff --git a/tests/macro_comma_support.rs b/tests/macro_comma_support.rs
index e6a609b..ca13163 100644
--- a/tests/macro_comma_support.rs
+++ b/tests/macro_comma_support.rs
@@ -1,4 +1,3 @@
-#[cfg(feature = "executor")]
 #[test]
 fn ready() {
     use futures::{
@@ -14,7 +13,6 @@
     }))
 }
 
-#[cfg(all(feature = "executor", feature = "async-await"))]
 #[test]
 fn poll() {
     use futures::{
@@ -28,7 +26,6 @@
     })
 }
 
-#[cfg(all(feature = "executor", feature = "async-await"))]
 #[test]
 fn join() {
     use futures::{
@@ -43,7 +40,6 @@
     })
 }
 
-#[cfg(all(feature = "executor", feature = "async-await"))]
 #[test]
 fn try_join() {
     use futures::{
diff --git a/tests/mutex.rs b/tests/mutex.rs
index 7ee9f41..68e0301 100644
--- a/tests/mutex.rs
+++ b/tests/mutex.rs
@@ -1,4 +1,3 @@
-#[cfg(all(feature = "alloc", feature = "std"))]
 #[test]
 fn mutex_acquire_uncontested() {
     use futures::future::FutureExt;
@@ -11,7 +10,6 @@
     }
 }
 
-#[cfg(all(feature = "alloc", feature = "std"))]
 #[test]
 fn mutex_wakes_waiters() {
     use futures::future::FutureExt;
@@ -35,7 +33,6 @@
     assert!(waiter.poll_unpin(&mut panic_context()).is_ready());
 }
 
-#[cfg(feature = "thread-pool")]
 #[test]
 fn mutex_contested() {
     use futures::channel::mpsc;
diff --git a/tests/object_safety.rs b/tests/object_safety.rs
index b49ee88..30c892f 100644
--- a/tests/object_safety.rs
+++ b/tests/object_safety.rs
@@ -28,7 +28,6 @@
     assert_is_object_safe::<&dyn Sink<(), Error = ()>>();
 }
 
-#[cfg(feature = "std")] // futures::io
 #[test]
 fn io() {
     // `AsyncReadExt`, `AsyncWriteExt`, `AsyncSeekExt` and `AsyncBufReadExt` are not object safe.
diff --git a/tests/oneshot.rs b/tests/oneshot.rs
index 302160b..2494306 100644
--- a/tests/oneshot.rs
+++ b/tests/oneshot.rs
@@ -1,4 +1,3 @@
-#[cfg(feature = "alloc")] // channel
 #[test]
 fn oneshot_send1() {
     use futures::channel::oneshot;
@@ -16,7 +15,6 @@
     t.join().unwrap();
 }
 
-#[cfg(feature = "alloc")] // channel
 #[test]
 fn oneshot_send2() {
     use futures::channel::oneshot;
@@ -33,7 +31,6 @@
     assert_eq!(1, rx2.recv().unwrap());
 }
 
-#[cfg(feature = "alloc")] // channel
 #[test]
 fn oneshot_send3() {
     use futures::channel::oneshot;
@@ -50,7 +47,6 @@
     assert_eq!(1, rx2.recv().unwrap());
 }
 
-#[cfg(feature = "alloc")] // channel
 #[test]
 fn oneshot_drop_tx1() {
     use futures::channel::oneshot;
@@ -67,7 +63,6 @@
     assert_eq!(Err(oneshot::Canceled), rx2.recv().unwrap());
 }
 
-#[cfg(feature = "alloc")] // channel
 #[test]
 fn oneshot_drop_tx2() {
     use futures::channel::oneshot;
@@ -86,7 +81,6 @@
     assert_eq!(Err(oneshot::Canceled), rx2.recv().unwrap());
 }
 
-#[cfg(feature = "alloc")] // channel
 #[test]
 fn oneshot_drop_rx() {
     use futures::channel::oneshot;
diff --git a/tests/ready_queue.rs b/tests/ready_queue.rs
index be6ccc3..9aa3636 100644
--- a/tests/ready_queue.rs
+++ b/tests/ready_queue.rs
@@ -1,4 +1,3 @@
-#[cfg(feature = "alloc")] // FuturesUnordered
 mod assert_send_sync {
     use futures::stream::FuturesUnordered;
 
@@ -6,7 +5,6 @@
     impl AssertSendSync for FuturesUnordered<()> {}
 }
 
-#[cfg(all(feature = "alloc", feature = "executor"))] // channel:: + executor::
 #[test]
 fn basic_usage() {
     use futures::channel::oneshot;
@@ -41,7 +39,6 @@
     }));
 }
 
-#[cfg(all(feature = "alloc", feature = "executor"))] // channel:: + executor::
 #[test]
 fn resolving_errors() {
     use futures::channel::oneshot;
@@ -76,7 +73,6 @@
     }));
 }
 
-#[cfg(all(feature = "alloc", feature = "executor"))] // channel:: + executor::
 #[test]
 fn dropping_ready_queue() {
     use futures::channel::oneshot;
@@ -110,7 +106,6 @@
     }));
 }
 
-#[cfg(all(feature = "alloc", feature = "executor"))] // channel:: + executor::
 #[test]
 fn stress() {
     use futures::channel::oneshot;
@@ -149,7 +144,7 @@
 
             assert_eq!(rx.len(), n);
 
-            rx.sort();
+            rx.sort_unstable();
 
             for (i, x) in rx.into_iter().enumerate() {
                 assert_eq!(i, x);
@@ -160,7 +155,6 @@
     }
 }
 
-#[cfg(feature = "executor")] // executor
 #[test]
 fn panicking_future_dropped() {
     use futures::executor::block_on;
diff --git a/tests/recurse.rs b/tests/recurse.rs
index d3f4124..87a4ff2 100644
--- a/tests/recurse.rs
+++ b/tests/recurse.rs
@@ -1,4 +1,3 @@
-#[cfg(feature = "executor")] // executor::
 #[test]
 fn lots() {
     use futures::executor::block_on;
diff --git a/tests/select_all.rs b/tests/select_all.rs
index 9a6d736..540db2c 100644
--- a/tests/select_all.rs
+++ b/tests/select_all.rs
@@ -1,4 +1,3 @@
-#[cfg(feature = "executor")] // executor::
 #[test]
 fn smoke() {
     use futures::executor::block_on;
diff --git a/tests/select_ok.rs b/tests/select_ok.rs
index dd3703e..81cadb7 100644
--- a/tests/select_ok.rs
+++ b/tests/select_ok.rs
@@ -1,4 +1,3 @@
-#[cfg(feature = "executor")] // executor::
 #[test]
 fn ignore_err() {
     use futures::executor::block_on;
@@ -22,7 +21,6 @@
     assert!(v.is_empty());
 }
 
-#[cfg(feature = "executor")] // executor::
 #[test]
 fn last_err() {
     use futures::executor::block_on;
diff --git a/tests/shared.rs b/tests/shared.rs
index 21e80fe..b2251a5 100644
--- a/tests/shared.rs
+++ b/tests/shared.rs
@@ -12,7 +12,6 @@
     }
 }
 
-#[cfg(all(feature = "alloc", feature = "executor"))] // channel:: + executor::
 fn send_shared_oneshot_and_wait_on_multiple_threads(threads_number: u32) {
     use futures::channel::oneshot;
     use futures::executor::block_on;
@@ -37,25 +36,21 @@
     }
 }
 
-#[cfg(all(feature = "alloc", feature = "executor"))] // channel:: + executor::
 #[test]
 fn one_thread() {
     send_shared_oneshot_and_wait_on_multiple_threads(1);
 }
 
-#[cfg(all(feature = "alloc", feature = "executor"))] // channel:: + executor::
 #[test]
 fn two_threads() {
     send_shared_oneshot_and_wait_on_multiple_threads(2);
 }
 
-#[cfg(all(feature = "alloc", feature = "executor"))] // channel:: + executor::
 #[test]
 fn many_threads() {
     send_shared_oneshot_and_wait_on_multiple_threads(1000);
 }
 
-#[cfg(all(feature = "alloc", feature = "executor"))] // channel:: + executor::
 #[test]
 fn drop_on_one_task_ok() {
     use futures::channel::oneshot;
@@ -89,7 +84,6 @@
     t2.join().unwrap();
 }
 
-#[cfg(feature = "executor")] // executor::
 #[test]
 fn drop_in_poll() {
     use futures::executor::block_on;
@@ -112,7 +106,6 @@
     assert_eq!(block_on(future1), 1);
 }
 
-#[cfg(all(feature = "alloc", feature = "executor"))] // channel:: + executor::
 #[test]
 fn peek() {
     use futures::channel::oneshot;
@@ -150,7 +143,6 @@
     }
 }
 
-#[cfg(all(feature = "alloc", feature = "executor"))] // channel:: + executor::
 #[test]
 fn dont_clone_in_single_owner_shared_future() {
     use futures::channel::oneshot;
@@ -171,7 +163,6 @@
     assert_eq!(block_on(rx).unwrap().0.get(), 0);
 }
 
-#[cfg(all(feature = "alloc", feature = "executor"))] // channel:: + executor::
 #[test]
 fn dont_do_unnecessary_clones_on_output() {
     use futures::channel::oneshot;
@@ -194,7 +185,6 @@
     assert_eq!(block_on(rx).unwrap().0.get(), 2);
 }
 
-#[cfg(all(feature = "alloc", feature = "executor"))] // channel:: + executor::
 #[test]
 fn shared_future_that_wakes_itself_until_pending_is_returned() {
     use futures::executor::block_on;
diff --git a/tests/sink.rs b/tests/sink.rs
index f6ce28c..8ed201e 100644
--- a/tests/sink.rs
+++ b/tests/sink.rs
@@ -1,4 +1,3 @@
-#[allow(dead_code)]
 mod sassert_next {
     use futures::stream::{Stream, StreamExt};
     use futures::task::Poll;
@@ -18,7 +17,6 @@
     }
 }
 
-#[allow(dead_code)]
 mod unwrap {
     use futures::task::Poll;
     use std::fmt;
@@ -32,8 +30,6 @@
     }
 }
 
-#[allow(dead_code)]
-#[cfg(feature = "alloc")] // ArcWake
 mod flag_cx {
     use futures::task::{self, ArcWake, Context};
     use std::sync::Arc;
@@ -73,7 +69,6 @@
     }
 }
 
-#[allow(dead_code)]
 mod start_send_fut {
     use futures::future::Future;
     use futures::ready;
@@ -105,7 +100,6 @@
     }
 }
 
-#[allow(dead_code)]
 mod manual_flush {
     use futures::sink::Sink;
     use futures::task::{Context, Poll, Waker};
@@ -166,7 +160,6 @@
     }
 }
 
-#[allow(dead_code)]
 mod allowance {
     use futures::sink::Sink;
     use futures::task::{Context, Poll, Waker};
@@ -245,8 +238,6 @@
     }
 }
 
-
-#[cfg(feature = "alloc")] // futures_sink::Sink satisfying for .left/right_sink
 #[test]
 fn either_sink() {
     use futures::sink::{Sink, SinkExt};
@@ -262,7 +253,6 @@
     Pin::new(&mut s).start_send(0).unwrap();
 }
 
-#[cfg(feature = "executor")] // executor::
 #[test]
 fn vec_sink() {
     use futures::executor::block_on;
@@ -277,7 +267,6 @@
     assert_eq!(v, vec![0, 1]);
 }
 
-#[cfg(feature = "alloc")] //  futures_sink::Sink satisfying for .start_send()
 #[test]
 fn vecdeque_sink() {
     use futures::sink::Sink;
@@ -293,7 +282,6 @@
     assert_eq!(deque.pop_front(), None);
 }
 
-#[cfg(feature = "executor")] // executor::
 #[test]
 fn send() {
     use futures::executor::block_on;
@@ -311,7 +299,6 @@
     assert_eq!(v, vec![0, 1, 2]);
 }
 
-#[cfg(feature = "executor")] // executor::
 #[test]
 fn send_all() {
     use futures::executor::block_on;
@@ -332,7 +319,6 @@
 
 // Test that `start_send` on an `mpsc` channel does indeed block when the
 // channel is full
-#[cfg(feature = "executor")] // executor::
 #[test]
 fn mpsc_blocking_start_send() {
     use futures::channel::mpsc;
@@ -365,7 +351,6 @@
 
 // test `flush` by using `with` to make the first insertion into a sink block
 // until a oneshot is completed
-#[cfg(feature = "executor")] // executor::
 #[test]
 fn with_flush() {
     use futures::channel::oneshot;
@@ -403,7 +388,6 @@
 }
 
 // test simple use of with to change data
-#[cfg(feature = "executor")] // executor::
 #[test]
 fn with_as_map() {
     use futures::executor::block_on;
@@ -419,7 +403,6 @@
 }
 
 // test simple use of with_flat_map
-#[cfg(feature = "executor")] // executor::
 #[test]
 fn with_flat_map() {
     use futures::executor::block_on;
@@ -436,7 +419,6 @@
 
 // Check that `with` propagates `poll_ready` to the inner sink.
 // Regression test for the issue #1834.
-#[cfg(feature = "executor")] // executor::
 #[test]
 fn with_propagates_poll_ready() {
     use futures::channel::mpsc;
@@ -473,7 +455,6 @@
 
 // test that the `with` sink doesn't require the underlying sink to flush,
 // but doesn't claim to be flushed until the underlying sink is
-#[cfg(feature = "alloc")] // flag_cx
 #[test]
 fn with_flush_propagate() {
     use futures::future::{self, FutureExt};
@@ -503,7 +484,6 @@
 }
 
 // test that a buffer is a no-nop around a sink that always accepts sends
-#[cfg(feature = "executor")] // executor::
 #[test]
 fn buffer_noop() {
     use futures::executor::block_on;
@@ -522,8 +502,6 @@
 
 // test basic buffer functionality, including both filling up to capacity,
 // and writing out when the underlying sink is ready
-#[cfg(feature = "executor")] // executor::
-#[cfg(feature = "alloc")] // flag_cx
 #[test]
 fn buffer() {
     use futures::executor::block_on;
@@ -552,7 +530,6 @@
     })
 }
 
-#[cfg(feature = "executor")] // executor::
 #[test]
 fn fanout_smoke() {
     use futures::executor::block_on;
@@ -568,8 +545,6 @@
     assert_eq!(sink2, vec![1, 2, 3]);
 }
 
-#[cfg(feature = "executor")] // executor::
-#[cfg(feature = "alloc")] // flag_cx
 #[test]
 fn fanout_backpressure() {
     use futures::channel::mpsc;
@@ -612,7 +587,6 @@
     })
 }
 
-#[cfg(all(feature = "alloc", feature = "std"))] // channel::mpsc
 #[test]
 fn sink_map_err() {
     use futures::channel::mpsc;
@@ -636,7 +610,6 @@
     );
 }
 
-#[cfg(all(feature = "alloc", feature = "std"))] // channel::mpsc
 #[test]
 fn err_into() {
     use futures::channel::mpsc;
diff --git a/tests/sink_fanout.rs b/tests/sink_fanout.rs
index 62f32f2..7d1fa43 100644
--- a/tests/sink_fanout.rs
+++ b/tests/sink_fanout.rs
@@ -1,4 +1,3 @@
-#[cfg(all(feature = "alloc", feature="std", feature="executor"))] // channel::mpsc, executor::
 #[test]
 fn it_works() {
     use futures::channel::mpsc;
diff --git a/tests/split.rs b/tests/split.rs
index 140cf3c..86c2fc6 100644
--- a/tests/split.rs
+++ b/tests/split.rs
@@ -1,21 +1,18 @@
-#[cfg(feature = "executor")] // executor::
 #[test]
 fn test_split() {
     use futures::executor::block_on;
     use futures::sink::{Sink, SinkExt};
     use futures::stream::{self, Stream, StreamExt};
     use futures::task::{Context, Poll};
-    use pin_utils::unsafe_pinned;
+    use pin_project::pin_project;
     use std::pin::Pin;
 
+    #[pin_project]
     struct Join<T, U> {
+        #[pin]
         stream: T,
-        sink: U
-    }
-
-    impl<T, U> Join<T, U> {
-        unsafe_pinned!(stream: T);
-        unsafe_pinned!(sink: U);
+        #[pin]
+        sink: U,
     }
 
     impl<T: Stream, U> Stream for Join<T, U> {
@@ -25,7 +22,7 @@
             self: Pin<&mut Self>,
             cx: &mut Context<'_>,
         ) -> Poll<Option<T::Item>> {
-            self.stream().poll_next(cx)
+            self.project().stream.poll_next(cx)
         }
     }
 
@@ -36,28 +33,28 @@
             self: Pin<&mut Self>,
             cx: &mut Context<'_>,
         ) -> Poll<Result<(), Self::Error>> {
-            self.sink().poll_ready(cx)
+            self.project().sink.poll_ready(cx)
         }
 
         fn start_send(
             self: Pin<&mut Self>,
             item: Item,
         ) -> Result<(), Self::Error> {
-            self.sink().start_send(item)
+            self.project().sink.start_send(item)
         }
 
         fn poll_flush(
             self: Pin<&mut Self>,
             cx: &mut Context<'_>,
         ) -> Poll<Result<(), Self::Error>> {
-            self.sink().poll_flush(cx)
+            self.project().sink.poll_flush(cx)
         }
 
         fn poll_close(
             self: Pin<&mut Self>,
             cx: &mut Context<'_>,
         ) -> Poll<Result<(), Self::Error>> {
-            self.sink().poll_close(cx)
+            self.project().sink.poll_close(cx)
         }
     }
 
diff --git a/tests/stream.rs b/tests/stream.rs
index 09fe9e2..14b283d 100644
--- a/tests/stream.rs
+++ b/tests/stream.rs
@@ -1,4 +1,3 @@
-#[cfg(feature = "executor")] // executor::
 #[test]
 fn select() {
     use futures::executor::block_on;
@@ -16,7 +15,6 @@
     select_and_compare(vec![1, 2], vec![4, 5, 6], vec![1, 4, 2, 5, 6]);
 }
 
-#[cfg(feature = "executor")] // executor::
 #[test]
 fn flat_map() {
     use futures::stream::{self, StreamExt};
@@ -37,7 +35,6 @@
     });
 }
 
-#[cfg(feature = "executor")] // executor::
 #[test]
 fn scan() {
     use futures::stream::{self, StreamExt};
@@ -56,7 +53,6 @@
     });
 }
 
-#[cfg(feature = "executor")] // executor::
 #[test]
 fn take_until() {
     use futures::future::{self, Future};
@@ -136,7 +132,6 @@
     let _ = rx1.ready_chunks(0);
 }
 
-#[cfg(feature = "executor")] // executor::
 #[test]
 fn ready_chunks() {
     use futures::channel::mpsc;
@@ -162,4 +157,4 @@
         assert_eq!(s.next().await.unwrap(), vec![2,3]);
         assert_eq!(s.next().await.unwrap(), vec![4]);
     });
-}
\ No newline at end of file
+}
diff --git a/tests/stream_catch_unwind.rs b/tests/stream_catch_unwind.rs
index 94c7a75..272558c 100644
--- a/tests/stream_catch_unwind.rs
+++ b/tests/stream_catch_unwind.rs
@@ -1,4 +1,3 @@
-#[cfg(feature = "executor")]
 #[test]
 fn panic_in_the_middle_of_the_stream() {
     use futures::executor::block_on_stream;
@@ -15,7 +14,6 @@
     assert!(iter.next().is_none());
 }
 
-#[cfg(feature = "executor")]
 #[test]
 fn no_panic() {
     use futures::executor::block_on_stream;
diff --git a/tests/stream_into_async_read.rs b/tests/stream_into_async_read.rs
index 1b26233..eb78b59 100644
--- a/tests/stream_into_async_read.rs
+++ b/tests/stream_into_async_read.rs
@@ -1,4 +1,3 @@
-#[cfg(feature = "std")] // io::
 #[test]
 fn test_into_async_read() {
     use core::pin::Pin;
@@ -52,7 +51,6 @@
     assert_read!(reader, &mut buf, 0);
 }
 
-#[cfg(feature = "std")] // io::
 #[test]
 fn test_into_async_bufread() -> std::io::Result<()> {
     use core::pin::Pin;
diff --git a/tests/stream_peekable.rs b/tests/stream_peekable.rs
index c49cd72..66a7385 100644
--- a/tests/stream_peekable.rs
+++ b/tests/stream_peekable.rs
@@ -1,4 +1,3 @@
-#[cfg(feature = "executor")] // executor::
 #[test]
 fn peekable() {
     use futures::executor::block_on;
diff --git a/tests/stream_select_all.rs b/tests/stream_select_all.rs
index 411cb73..6178412 100644
--- a/tests/stream_select_all.rs
+++ b/tests/stream_select_all.rs
@@ -1,4 +1,3 @@
-#[cfg(feature = "alloc")] // stream::SelectAll
 #[test]
 fn is_terminated() {
     use futures::future::{self, FutureExt};
@@ -29,7 +28,6 @@
     assert_eq!(tasks.is_terminated(), true);
 }
 
-#[cfg(feature = "executor")] // executor::
 #[test]
 fn issue_1626() {
     use futures::executor::block_on_stream;
@@ -51,8 +49,6 @@
     assert_eq!(s.next(), None);
 }
 
-#[cfg(all(feature = "alloc", feature = "std"))] // channel::mpsc
-#[cfg(feature = "executor")] // executor::
 #[test]
 fn works_1() {
     use futures::channel::mpsc;
diff --git a/tests/stream_select_next_some.rs b/tests/stream_select_next_some.rs
index f2b3af2..bec5262 100644
--- a/tests/stream_select_next_some.rs
+++ b/tests/stream_select_next_some.rs
@@ -1,4 +1,3 @@
-#[cfg(feature = "alloc")] // stream::FuturesUnordered
 #[test]
 fn is_terminated() {
     use futures::future;
@@ -29,8 +28,6 @@
     assert_eq!(select_next_some.is_terminated(), true);
 }
 
-#[cfg(all(feature = "async-await", feature = "std"))] // futures::select
-#[cfg(feature = "executor")] // executor::
 #[test]
 fn select() {
     use futures::{future, select};
@@ -62,9 +59,6 @@
 }
 
 // Check that `select!` macro does not fail when importing from `futures_util`.
-#[cfg(feature = "alloc")] // stream::FuturesUnordered
-#[cfg(feature = "async-await")] // futures_util::select turned on
-#[cfg(feature = "executor")] // executor::
 #[test]
 fn futures_util_select() {
     use futures::future;
diff --git a/tests/try_join.rs b/tests/try_join.rs
index 0861c1e..6c6d084 100644
--- a/tests/try_join.rs
+++ b/tests/try_join.rs
@@ -1,5 +1,3 @@
-#![cfg(feature = "executor")] // executor::
-#![cfg(feature = "async-await")] // try_join!
 #![deny(unreachable_code)]
 
 use futures::{try_join, executor::block_on};
diff --git a/tests/try_join_all.rs b/tests/try_join_all.rs
index 1097a36..3de679b 100644
--- a/tests/try_join_all.rs
+++ b/tests/try_join_all.rs
@@ -1,4 +1,3 @@
-#[cfg(feature = "executor")] // executor::
 mod util {
     use std::future::Future;
     use futures::executor::block_on;
@@ -14,7 +13,6 @@
     }
 }
 
-#[cfg(feature = "executor")] // assert_done
 #[test]
 fn collect_collects() {
     use futures_util::future::{err, ok, try_join_all};
@@ -30,7 +28,6 @@
     // TODO: needs more tests
 }
 
-#[cfg(feature = "executor")] // assert_done
 #[test]
 fn try_join_all_iter_lifetime() {
     use futures_util::future::{ok, try_join_all};
@@ -40,7 +37,7 @@
 
     // In futures-rs version 0.1, this function would fail to typecheck due to an overly
     // conservative type parameterization of `TryJoinAll`.
-    fn sizes<'a>(bufs: Vec<&'a [u8]>) -> Box<dyn Future<Output = Result<Vec<usize>, ()>> + Unpin> {
+    fn sizes(bufs: Vec<&[u8]>) -> Box<dyn Future<Output = Result<Vec<usize>, ()>> + Unpin> {
         let iter = bufs.into_iter().map(|b| ok::<usize, ()>(b.len()));
         Box::new(try_join_all(iter))
     }
@@ -48,7 +45,6 @@
     assert_done(|| sizes(vec![&[1,2,3], &[], &[0]]), Ok(vec![3 as usize, 0, 1]));
 }
 
-#[cfg(feature = "executor")] // assert_done
 #[test]
 fn try_join_all_from_iter() {
     use futures_util::future::{ok, TryJoinAll};