diff --git a/Cargo.lock b/Cargo.lock
index 6dc524536ce0d42a7b55b6b9a8dc1aafe970f133..279823ad025e1e1ddea0ef3ee698e9266a204683 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -153,7 +153,7 @@ dependencies = [
  "cc",
  "cubeb",
  "error-chain",
- "futures 0.1.29",
+ "futures 0.1.31",
  "iovec",
  "libc",
  "log",
@@ -178,7 +178,7 @@ dependencies = [
  "audio_thread_priority",
  "audioipc",
  "cubeb-backend",
- "futures 0.1.29",
+ "futures 0.1.31",
  "futures-cpupool",
  "log",
  "tokio 0.1.11",
@@ -193,7 +193,7 @@ dependencies = [
  "audioipc",
  "cubeb-core",
  "error-chain",
- "futures 0.1.29",
+ "futures 0.1.31",
  "log",
  "once_cell",
  "slab",
@@ -1627,15 +1627,15 @@ checksum = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7"
 
 [[package]]
 name = "futures"
-version = "0.1.29"
+version = "0.1.31"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1b980f2816d6ee8673b6517b52cb0e808a180efc92e5c19d02cdda79066703ef"
+checksum = "3a471a38ef8ed83cd6e40aa59c1ffe17db6855c18e3604d9c4ed8c08ebc28678"
 
 [[package]]
 name = "futures"
-version = "0.3.12"
+version = "0.3.15"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "da9052a1a50244d8d5aa9bf55cbc2fb6f357c86cc52e46c62ed390a7180cf150"
+checksum = "0e7e43a803dae2fa37c1f6a8fe121e1f7bf9548b4dfc0522a42f34145dadfc27"
 dependencies = [
  "futures-channel",
  "futures-core",
@@ -1647,9 +1647,9 @@ dependencies = [
 
 [[package]]
 name = "futures-channel"
-version = "0.3.12"
+version = "0.3.15"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f2d31b7ec7efab6eefc7c57233bb10b847986139d88cc2f5a02a1ae6871a1846"
+checksum = "e682a68b29a882df0545c143dc3646daefe80ba479bcdede94d5a703de2871e2"
 dependencies = [
  "futures-core",
  "futures-sink",
@@ -1657,9 +1657,9 @@ dependencies = [
 
 [[package]]
 name = "futures-core"
-version = "0.3.12"
+version = "0.3.15"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "79e5145dde8da7d1b3892dad07a9c98fc04bc39892b1ecc9692cf53e2b780a65"
+checksum = "0402f765d8a89a26043b889b26ce3c4679d268fa6bb22cd7c6aad98340e179d1"
 
 [[package]]
 name = "futures-cpupool"
@@ -1667,37 +1667,35 @@ version = "0.1.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "ab90cde24b3319636588d0c35fe03b1333857621051837ed769faefb4c2162e4"
 dependencies = [
- "futures 0.1.29",
+ "futures 0.1.31",
  "num_cpus",
 ]
 
 [[package]]
 name = "futures-io"
-version = "0.3.12"
+version = "0.3.15"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "28be053525281ad8259d47e4de5de657b25e7bac113458555bb4b70bc6870500"
+checksum = "acc499defb3b348f8d8f3f66415835a9131856ff7714bf10dadfc4ec4bdb29a1"
 
 [[package]]
 name = "futures-sink"
-version = "0.3.12"
+version = "0.3.15"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "caf5c69029bda2e743fddd0582d1083951d65cc9539aebf8812f36c3491342d6"
+checksum = "a57bead0ceff0d6dde8f465ecd96c9338121bb7717d3e7b108059531870c4282"
 
 [[package]]
 name = "futures-task"
-version = "0.3.12"
+version = "0.3.15"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "13de07eb8ea81ae445aca7b69f5f7bf15d7bf4912d8ca37d6645c77ae8a58d86"
-dependencies = [
- "once_cell",
-]
+checksum = "8a16bef9fc1a4dddb5bee51c989e3fbba26569cbb0e31f5b303c184e3dd33dae"
 
 [[package]]
 name = "futures-util"
-version = "0.3.12"
+version = "0.3.15"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "632a8cd0f2a4b3fdea1657f08bde063848c3bd00f9bbf6e256b8be78802e624b"
+checksum = "feb5c238d27e2bf94ffdfd27b2c29e3df4a68c4193bb6427384259e2bf191967"
 dependencies = [
+ "autocfg",
  "futures-core",
  "futures-sink",
  "futures-task",
@@ -5179,7 +5177,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "6e93c78d23cc61aa245a8acd2c4a79c4d7fa7fb5c3ca90d5737029f043a84895"
 dependencies = [
  "bytes 0.4.12",
- "futures 0.1.29",
+ "futures 0.1.31",
  "mio",
  "tokio-codec",
  "tokio-current-thread",
@@ -5218,7 +5216,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "881e9645b81c2ce95fcb799ded2c29ffb9f25ef5bef909089a420e5961dd8ccb"
 dependencies = [
  "bytes 0.4.12",
- "futures 0.1.29",
+ "futures 0.1.31",
  "tokio-io",
 ]
 
@@ -5228,7 +5226,7 @@ version = "0.1.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "d16217cad7f1b840c5a97dfb3c43b0c871fef423a6e8d2118c604e843662a443"
 dependencies = [
- "futures 0.1.29",
+ "futures 0.1.31",
  "tokio-executor",
 ]
 
@@ -5239,7 +5237,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "ca6df436c42b0c3330a82d855d2ef017cd793090ad550a6bc2184f4b933532ab"
 dependencies = [
  "crossbeam-utils 0.6.6",
- "futures 0.1.29",
+ "futures 0.1.31",
 ]
 
 [[package]]
@@ -5248,7 +5246,7 @@ version = "0.1.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "b5cbe4ca6e71cb0b62a66e4e6f53a8c06a6eefe46cc5f665ad6f274c9906f135"
 dependencies = [
- "futures 0.1.29",
+ "futures 0.1.31",
  "tokio-io",
  "tokio-threadpool",
 ]
@@ -5260,7 +5258,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "a5c9635ee806f26d302b8baa1e145689a280d8f5aa8d0552e7344808da54cc21"
 dependencies = [
  "bytes 0.4.12",
- "futures 0.1.29",
+ "futures 0.1.31",
  "log",
 ]
 
@@ -5270,7 +5268,7 @@ version = "0.1.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "8703a5762ff6913510dc64272c714c4389ffd8c4b3cf602879b8bd14ff06b604"
 dependencies = [
- "futures 0.1.29",
+ "futures 0.1.31",
  "log",
  "mio",
  "slab",
@@ -5285,7 +5283,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "5b4c329b47f071eb8a746040465fa751bd95e4716e98daef6a9b4e434c17d565"
 dependencies = [
  "bytes 0.4.12",
- "futures 0.1.29",
+ "futures 0.1.31",
  "iovec",
  "mio",
  "tokio-io",
@@ -5301,7 +5299,7 @@ dependencies = [
  "crossbeam-deque",
  "crossbeam-queue",
  "crossbeam-utils 0.6.6",
- "futures 0.1.29",
+ "futures 0.1.31",
  "lazy_static",
  "log",
  "num_cpus",
@@ -5316,7 +5314,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "f2106812d500ed25a4f38235b9cae8f78a09edf43203e16e59c3b769a342a60e"
 dependencies = [
  "crossbeam-utils 0.6.6",
- "futures 0.1.29",
+ "futures 0.1.31",
  "slab",
  "tokio-executor",
 ]
@@ -5328,7 +5326,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "43eb534af6e8f37d43ab1b612660df14755c42bd003c5f8d2475ee78cc4600c0"
 dependencies = [
  "bytes 0.4.12",
- "futures 0.1.29",
+ "futures 0.1.31",
  "log",
  "mio",
  "tokio-codec",
@@ -5343,7 +5341,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "037ffc3ba0e12a0ab4aca92e5234e0dedeb48fddf6ccd260f1f150a36a9f2445"
 dependencies = [
  "bytes 0.4.12",
- "futures 0.1.29",
+ "futures 0.1.31",
  "iovec",
  "libc",
  "log",
@@ -5598,7 +5596,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "54cd1e2b3eb3539284d88b76a9afcf5e20f2ef2fab74db5b21a1c30d7d945e82"
 dependencies = [
  "bytes 0.5.6",
- "futures 0.3.12",
+ "futures 0.3.15",
  "headers",
  "http",
  "hyper",
diff --git a/third_party/rust/futures-0.1.29/.cargo-checksum.json b/third_party/rust/futures-0.1.29/.cargo-checksum.json
deleted file mode 100644
index 53315b746a9f04275d526f3eca9113484c9b3142..0000000000000000000000000000000000000000
--- a/third_party/rust/futures-0.1.29/.cargo-checksum.json
+++ /dev/null
@@ -1 +0,0 @@
-{"files":{"CHANGELOG.md":"081044d6883e82c3c5a288e0cf0e839acfffbc329c6170cecbf436d163b3390c","Cargo.toml":"5d0b116df9944a21333a3fc73d15794932d50dfa6029776450db00c2fd852714","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"69036b033e4bb951821964dbc3d9b1efe6913a6e36d9c1f206de4035a1a85cc4","README.md":"2337dbe13d477119b7a2339ec8bc785ae32f5cd0ba4d7b68975681752e0efce8","appveyor.yml":"7b8de5d694cb575649354d7fc3eff0781e2c5c412df4bc8a90b36b6fdb55bfab","benches/bilock.rs":"60b9e0814b8396e0320d299273c6f91c2ccc09a2bb59eec92df74a1f0919e54f","benches/futures_unordered.rs":"fa2d3b5e6cdfe1e941d78c119a696fb583341fa0a0895ec2692e6d374ceb9a0e","benches/poll.rs":"ca369079c4db366a180be22f406eaf8e94e2e771c02568eb35d89e63093006cf","benches/sync_mpsc.rs":"8d4dbf78afcdf61fc72da326c4810bc797462771707d079f95a7f75aa2ec0ec0","benches/thread_notify.rs":"1992b1e2b352fbc15a611d1318ac1bf6f19318d769086d55c80e6863f1b0e106","src/executor.rs":"80466c075daf030e07cc0d053618837cb73c07f5399b3d65016925f4488adb73","src/future/and_then.rs":"15653d392d331a1fc4619129f737acc28525c88d1675b7fcea6ed27c5b1bf302","src/future/catch_unwind.rs":"dfef6b6a66c09574338046cf23b0c6aacd8200872d512b831d6dc12038f05298","src/future/chain.rs":"4d712e989e079f4164d5d9fe3bb522d521094b0d8083ee639350570444e5bb93","src/future/either.rs":"898813aa84c19946203dd076050035d899014a6b0749ba50f41ae148580f7169","src/future/empty.rs":"b549a1ca0f21bc6d1a26d9063a9a60deb9235ff7eff5db915050115fed91a9c7","src/future/flatten.rs":"7eb15429fcc749326371fe571e1f7d294d7b83f7557e6e1971e2206180253d65","src/future/flatten_stream.rs":"cf914425c3606b61c046df5c43d64266d6f2328693e4122441f9bbcf7cb0a4e1","src/future/from_err.rs":"a1f42d95f7b52e80c2e5a03b44cbce0efbe5fc486dfe33d799b74ab9ba9057ab","src/future/fuse.rs":"3920c819b850c8f04b3868eae70dc0d3e6802ff0b517501f3aa5057a3b632102","src/future/inspect.rs":"89c362d8402dddd784bcc54e62ca27657ca8108e1ae8de5a7237e08650e10636","src/future/into_stream.rs":"0fa6bc4d70e8b4d75cf45fba53b39f033b87574103fffea4090b78f049bf43d0","src/future/join.rs":"b1dcefb03b1cb4e609ad2e79ba9a6cfab24235d7a4fff7fb9daf2c8fbf0f3d70","src/future/join_all.rs":"30fc27cbc1248046937b441a165a911e9ed1cd887ad6f3aeeb573b59c43e9cbf","src/future/lazy.rs":"1a2025bae3675fb682cefbf8a88bbb7a7519cfdee42dd6b3049a4d2b7ab8b5b1","src/future/loop_fn.rs":"5bd952247ae4e9d31dff77386bbd3700f596da136ea53e9e9944266af3f08688","src/future/map.rs":"91e148d9adaea929b85ede63c71fb07ef9b5611db906a13eedad2cf551745b47","src/future/map_err.rs":"2c8e87fa8ff56061722db6c69aaba588e6df6835a4e2fe84826f0bd4fed2e007","src/future/mod.rs":"a0a2f09ffdcbe20e0b210be3fe3d0d6863b8472ea84cd677af57074a9a618166","src/future/option.rs":"93270226cadcfa349250023e2070e687cf595831f427904ca744f7bc50342ded","src/future/or_else.rs":"444567101c4c437b184aa2e2eec0cf4363af442c0afc58d6508d3d2ac86489a9","src/future/poll_fn.rs":"817bfb75e7c43ca96a53e8cc9f48606c92c3c6742b07a732ce79a8f9b7bf8808","src/future/result.rs":"cc62c2377defb7b53aa859bf05c41c52a9cf8583378b7072bb2b45232d5fc9c5","src/future/select.rs":"73efd98004d5d8c46607bf770ff07a810bcdbe05cce0e8e4f41f5e659fd44203","src/future/select2.rs":"cfbbf3a9794109c56a3703456fae6111826bc25f98f2f36b234d483eeeeab482","src/future/select_all.rs":"b009e57ac241a3aba78db0bb751432cb99c1e91b8bae1b3baf225921f0daa441","src/future/select_ok.rs":"4884896914d8903edbfa12b5e255d35d5b2c91a9182ce6f774978db636617905","src/future/shared.rs":"17caad7513b78351f1232b959c60b882675f3c008b20cd01bbd30cefbda3bd68","src/future/then.rs":"c49b388ab3c78979ad9ae40f6e859ee98e9351bdb11e3c3f1ad4ceca77651a56","src/lib.rs":"bd097d35f814f889e9ec29b2ce75c9da57841f06feffcc56a40df5758c3848b9","src/lock.rs":"fe4c8185f9774a134d4ce27af4a9c8b25f30f7dcc6990473210d66b6b8936ce4","src/poll.rs":"df74c3a8169d7895f3c46dd6de99edd77bd024b85e26b1d0644d2b8e5ef515b9","src/resultstream.rs":"365bc127c0410badb58ea2beb2abae546968ba3ac91abe2140e93e0c3620228f","src/sink/buffer.rs":"17e6bad2434f31630494a9a98e40a287da8a603515885ab8a17199ab0e5f8e46","src/sink/fanout.rs":"1fbcabdb1d22a43919417790082dc27ac65e2a100263504b6664a0b5e0657ae1","src/sink/flush.rs":"6c9a3bb9705c740e601ca6101cf6e6a87f2568661cff39a3576ef55986e3cb60","src/sink/from_err.rs":"b6d6e43c1f90c70bc1576ac2c9f1a7777fc07eef419721850962d896ac6cc3de","src/sink/map_err.rs":"b34a60880336b536666c1047f1919dd90eeed10b869e9c679fa928a3d5321112","src/sink/mod.rs":"4b4d80d008bfa8d0abc83cd640dc9c107423c7920795678c079c544c037ab632","src/sink/send.rs":"019f3f8ab450edc0adb864e4b819f5b0d4cfe9dc33a53093c2aa18e1eb6270dc","src/sink/send_all.rs":"b05047459faceecf0dfd5e6280014c31f5a2a1058974785db8ede497c10a1e79","src/sink/wait.rs":"9c70fdd54c642e4ecf7d9b0ff1fbb2df9c89349dfd60b5482748cd93c6dc301e","src/sink/with.rs":"a122cc26108cb3396db12cb2107c576d366c61191f656acedd5ff6c65165fcfc","src/sink/with_flat_map.rs":"7b0f367d98a99d297c3ce097e9858ad7b0dfdafbb66516cba0767b62beb01af3","src/stream/and_then.rs":"9f0f6ee06343ab03eebcb71257963e76d8e7208e4015b402cc8a58f793e37d79","src/stream/buffer_unordered.rs":"057c3dec32baf451ef02f44ef849086637e4d2cbb2d65907cc15ed9398fe131b","src/stream/buffered.rs":"4ced19e37e47182d5f9c7f852a7906c35b71ac4a5b2774a9101859defbecb190","src/stream/catch_unwind.rs":"957b935645f1744a4741962772c15e94370153f33e0db356309bf98ebb599c37","src/stream/chain.rs":"0b6b06cf5aaf0c2f665c61c65766d6113e24f690ebd9ad3a89abfa521e2ce9b2","src/stream/channel.rs":"f728402228fea0be01ec5cf1d02e49e52666c0c9ea986708d18e24f30376f6de","src/stream/chunks.rs":"455481ae5bc83cde009dc73a5ba9d1fc6281dd5750591e7d08eb25f149cd822b","src/stream/collect.rs":"e770850c7ed2d458b521c12af4ee76adf2303919849d2f95fa93fdf574c86d37","src/stream/concat.rs":"747723d73dc8edfe807834835362abc305704fc9cd9c1faf7b387b3d02cd397e","src/stream/empty.rs":"e8e2820fd3b2329a6987a11c3b3f28849f49427d1a745f2bdc7a4982476514e7","src/stream/filter.rs":"4abaf6c7bd3ecbccf7deac7920cc6bdc1b17875bedf7c6acd7e702254b3b83ba","src/stream/filter_map.rs":"573079f98efc38bbc68746084702b952ccb035bd8238c3c30fa103979865ed0e","src/stream/flatten.rs":"f2edce326745373c9c524bb574ce18584be95c7fd1a0ef875256b39891219b18","src/stream/fold.rs":"7f397373ed66560ff1eb0cffc5dafaf1569d3c8155fe418cc2bf6fc33faec230","src/stream/for_each.rs":"bd7f96bf551a829e37a54fd529e0b68a8868480797df039c75e1f226639cf096","src/stream/forward.rs":"8c077e48a22ceff5e47c8db9da4834e3051db2b9bd63e8e8e515d84703c1af0d","src/stream/from_err.rs":"bde1791790030c480aa88c6f7b235703d5b400249c841c8b045ea2203728b96c","src/stream/fuse.rs":"5d544151de7e5a3ce8a47bdeabe5cc9beaf0937b1eeed67e8d76842f54dea65d","src/stream/future.rs":"8f72146483c0423cbc11d45c76ee219ed12d940164c83199bb85cd6d5d64c22d","src/stream/futures_ordered.rs":"82e46576eb5201bd00470831353ea4dd9fcd6bc2d194452bda385806f7a25586","src/stream/futures_unordered.rs":"fa8cfe9e364b9bcb3d67a95a307f79631f5bf3506131955f4d8dab3fbc321e68","src/stream/inspect.rs":"4a1e7d7bbb0842a7021c5145bb1b64dbc213cfdccff51fe8399e3120c123eab5","src/stream/inspect_err.rs":"b4f2bc6a139df8f8eb403aafbca91c05b3093d3a6e13cef034a639fbe3ebe01e","src/stream/iter.rs":"cfff6b28759ccf390e8367f9f63209133c16e7fa53c7ae71167f318ba3ec624b","src/stream/iter_ok.rs":"5165cb02972776515734e0f343e626fbb448b65b38cdeacffbd86116f3c3cd37","src/stream/iter_result.rs":"9db38b1066d9adc1ece496432127049d36fb4b9895660c2af2b7ac28510c9084","src/stream/map.rs":"ba16b1469e519377939cf3bd073b258ac41e6349aab1c59393e3b30178a56496","src/stream/map_err.rs":"5ce9a279fde1f4f0887435856e1efa4fdeda749d43f4bab658b0abd216bc0a6f","src/stream/merge.rs":"63bb60ca386e280985cee8e16ae8b07f02d57aa8a0fa877ae01fb8b4678366d0","src/stream/mod.rs":"5fe336a9e59e6e92f2fef56b95757f0fdd9a350de89b38e09e6e4a31a8ada299","src/stream/once.rs":"277c960dc4bfa09fcc6112efa4e38a9fe937dc31fff440405e60bfd843f3c1ab","src/stream/or_else.rs":"c11ea499d85d6204ad083058eeca9dbf29873c49ee21bf01f9fe53e9ec3bba52","src/stream/peek.rs":"25d78baa0b3e30d2d1c72d1f3b1aa2a28811522d345dceefec587beb18b70fe2","src/stream/poll_fn.rs":"1dffbe60bd50c19efb71de2f768eecf70fa280b0d9c9cb889d16bb43b1619c8b","src/stream/repeat.rs":"807f2be5c9c1e7d54954f73ee38a373e71177aca43be8866712798f29ab541c2","src/stream/select.rs":"027873d9142e896272f7471cccaaccb133bf9f696a3f7510f3fb1aa4253a7c09","src/stream/skip.rs":"d7c839ca15f830709ebedd9526bb9ebd64ee22cb944e44213ce850a1383b71fa","src/stream/skip_while.rs":"aeb9bd64530bfaa631f4ca9500861c62fbf32849b09383eb26904bedd8b8b269","src/stream/split.rs":"c9b391fcbf3d1762bde442fd3549bd4739d2f9f486e88063650d42fea33c6af3","src/stream/take.rs":"9872429dd89cb34755b514abde9b6a876da076aea0449fcadfcc48e982507f21","src/stream/take_while.rs":"36bc2a33850ba2b58fb0da3866c96c8f4dfbd81133e615fda031518e71d425b5","src/stream/then.rs":"c7c66e27180cf2d98694de27504283a32444a0d0d6919ab25b3621fa6169408d","src/stream/unfold.rs":"5e69718714cc38c5ca6d0a6f5243ab28e392bdc97d96e8ab9059d9f0e772120c","src/stream/wait.rs":"936a15df4499d188f210cb0133bc8ad25e33e5b674a96105b4da549f32e92b40","src/stream/zip.rs":"33f1401683a29ce194927533c40bdbbc0783c552cf0b666f268fa7109e593853","src/sync/bilock.rs":"def09b26f9d66f2be0a8885ad6cf7106c3a073493bad591fc4a068212f0d739f","src/sync/mod.rs":"27ad26777f600f7054215fccdff07f4303182af2a6e0998d4229d62b090b7aac","src/sync/mpsc/mod.rs":"97542ef9fcbe338f2ac0ce982a9af11883aded33d3b4ce34a788cf98e00a7d3f","src/sync/mpsc/queue.rs":"b39889f1b2000a3de995a50f46243f97a98d3cce7c6de4b95c4d8ffeb42af918","src/sync/oneshot.rs":"5d41f1d19b78ada7d5587d0fb5751de5886281cf59889ba1b77cbde399975f1f","src/task.rs":"38e6bff1ec9ba6d62825793865185b68a7b4688f373adb039f54374e564b41d0","src/task_impl/atomic_task.rs":"027606777e948f37a5931a152f9e755e5a235da0131a396f71e39945f04c7961","src/task_impl/core.rs":"e3aff0cc6f0604a24950c2a5f9076e338b33f30581c5f503aa3ce230d42c44f4","src/task_impl/mod.rs":"a026baea5e1ba8157f65979726060182ebcae17c4a7bdd63b5e946ea3c6f5101","src/task_impl/std/data.rs":"9b6210811c095c4d0ec0f59a566bb8f5bc4b6ba544c72a4565dc47f3b7fbfab9","src/task_impl/std/mod.rs":"f02dc6451700ad3c6305b8732ffaafee536bf61f79c083b254a67cc7de0a02fb","src/task_impl/std/task_rc.rs":"a6e46e79fecb1497d603c016f4f1b14523346f74af800c9c27c069229d62dc25","src/task_impl/std/unpark_mutex.rs":"7a53b7209ff00880bce9d912c249b077870625ca87fe9ab7b0f441d3af430302","src/unsync/mod.rs":"e5da32f78212646f0161fec2e7193cda830f541bc9ae37361fbcf82e99cc1d86","src/unsync/mpsc.rs":"ef63328496eeaa6575a17525193c6093e7803df3a64355a40f0187119ca1d731","src/unsync/oneshot.rs":"89661388a87d4ac83befc31df9ad11e6a8c6104e2dde7be9e3585d7549cfe8c4","tests/all.rs":"99c6ad1d1e16ad2e0bc3027e1f5cb1a8f89404f71d77d3fc85badb67278f8179","tests/bilock.rs":"68462100c0c1e4e72f220d96ce1e6b25648f4c10a390be8a3bbfa99bbd795f31","tests/buffer_unordered.rs":"50ceb305da08fa095ee40a8f145fa9d95db59372cca949d77f011bbabc072152","tests/channel.rs":"61aff33ff7b2aa00e64762b7fd084f8f70cea078b6ef71b2db18ba96bbb4cf5f","tests/eager_drop.rs":"e0a615c39f1fb9baae543212e72a165f68e7576f6b8c6db1809149d819bd546b","tests/eventual.rs":"73cbd3836a598175439b5dc5597f7e464dfbc6d77379aaae1172c6c7f85220e5","tests/fuse.rs":"feba43c51cbeeb383f6ebba4a4c75107de69a3cdb3eadb3e673fbeb5a91f9ac4","tests/future_flatten_stream.rs":"133b91a9e2170849ed7dbcb4024675873a781bf2dd190cfcaa9c41418c3ccb97","tests/futures_ordered.rs":"7835bf9bedb9322a93070b5d87886b7a333dc469aee74f7eb86a1a7914b4602c","tests/futures_unordered.rs":"048153d9c4ec3433efbb97edfe01a458762e76160624362c658432f6f2357524","tests/inspect.rs":"d7706a175be9ed6ecc09d7a45e1559160e00da85fa8a9a7caec4c53918999842","tests/mpsc-close.rs":"62c1d2acaf60e3e896471fef6a507a125b336c04781237de8dc9d13e59cfa9fc","tests/mpsc.rs":"46488138956c2293680b3282e2001a413631728638760ee0073daa5e6f75de5a","tests/oneshot.rs":"a8773b3a65e79944045118f36bfd81fceb826d4e2846b46f86db37a02d7ae1f4","tests/ready_queue.rs":"3d50c4e71e3954c5b8e2672255b6af33abaebc16172c038e64c3323d633693c0","tests/recurse.rs":"4922e1ad975dca9d6b63d155515cc24181ad6a915adcbb743f7c8a58c0148a77","tests/select_all.rs":"3666e95ea94da17abb1899101e51b294af576bc446119fbc8aea5bb2991f439a","tests/select_ok.rs":"7a740e5b2d70c7776202ed1495b016f6e63ae1de06ca0f12ab21fcb3117450a9","tests/shared.rs":"4abb7c9a7f6207e40bc7408ee405df4e5a3e778054ceb113b4a177a886a64d11","tests/sink.rs":"7da8db7fb7c4f4f259d2d520b92a121de0a750b389217c8a4a02070bd0006423","tests/split.rs":"24dd293f049a37bfaabb02ae558c81e9fef9298a2ce43ecb544450b045c15f5c","tests/stream.rs":"3ca52f06a4503a853acce77997e4e744903c2084a83e0abf1e704e4f73833805","tests/stream_catch_unwind.rs":"6cee77f455a671d038aac24cf2f79636f1c0a5d8900957a2fed0ee3ed99832b8","tests/support/local_executor.rs":"10ca7f0bc1d9fd45350a807cfd76015fe24bf68d9a711e16ea0ec6be22af9ddd","tests/support/mod.rs":"1961189f57851a468e518327da0b7893eee990e477b82a278e0015f25b5e5a1c","tests/unfold.rs":"27ff8c3c83b333094bbffe6aebadf3730f0e35d1367b7b602a3df4e233d934d8","tests/unsync-oneshot.rs":"e676b37a64e1d6c0816d55cf443d86249ec2ff8180f1fc0d009de51e6842dac8","tests/unsync.rs":"89c335c6d8764ea12bc8ae75b6df717b8c697863764353a55faf884eaeb24699"},"package":"1b980f2816d6ee8673b6517b52cb0e808a180efc92e5c19d02cdda79066703ef"}
\ No newline at end of file
diff --git a/third_party/rust/futures-0.1.29/appveyor.yml b/third_party/rust/futures-0.1.29/appveyor.yml
deleted file mode 100644
index b516f6084c51ceaec198d2d8d37fe871039593e5..0000000000000000000000000000000000000000
--- a/third_party/rust/futures-0.1.29/appveyor.yml
+++ /dev/null
@@ -1,39 +0,0 @@
-environment:
-
-  # At the time this was added AppVeyor was having troubles with checking
-  # revocation of SSL certificates of sites like static.rust-lang.org and what
-  # we think is crates.io. The libcurl HTTP client by default checks for
-  # revocation on Windows and according to a mailing list [1] this can be
-  # disabled.
-  #
-  # The `CARGO_HTTP_CHECK_REVOKE` env var here tells cargo to disable SSL
-  # revocation checking on Windows in libcurl. Note, though, that rustup, which
-  # we're using to download Rust here, also uses libcurl as the default backend.
-  # Unlike Cargo, however, rustup doesn't have a mechanism to disable revocation
-  # checking. To get rustup working we set `RUSTUP_USE_HYPER` which forces it to
-  # use the Hyper instead of libcurl backend. Both Hyper and libcurl use
-  # schannel on Windows but it appears that Hyper configures it slightly
-  # differently such that revocation checking isn't turned on by default.
-  #
-  # [1]: https://curl.haxx.se/mail/lib-2016-03/0202.html
-  RUSTUP_USE_HYPER: 1
-  CARGO_HTTP_CHECK_REVOKE: false
-
-  matrix:
-  - TARGET: x86_64-pc-windows-msvc
-install:
-  - set PATH=C:\Program Files\Git\mingw64\bin;%PATH%
-  - curl -sSf -o rustup-init.exe https://win.rustup.rs/
-  - rustup-init.exe -y --default-host %TARGET%
-  - set PATH=%PATH%;C:\Users\appveyor\.cargo\bin
-  - rustc -V
-  - cargo -V
-
-build: false
-
-test_script:
-  - cargo build
-  - cargo build --no-default-features
-  - cargo test
-  - cargo test --no-default-features --features use_std
-  - cargo test --manifest-path futures-cpupool/Cargo.toml
diff --git a/third_party/rust/futures-0.1.31/.cargo-checksum.json b/third_party/rust/futures-0.1.31/.cargo-checksum.json
new file mode 100644
index 0000000000000000000000000000000000000000..4a1527313371627cb1c16a5a9d4ba6197026b936
--- /dev/null
+++ b/third_party/rust/futures-0.1.31/.cargo-checksum.json
@@ -0,0 +1 @@
+{"files":{"CHANGELOG.md":"081044d6883e82c3c5a288e0cf0e839acfffbc329c6170cecbf436d163b3390c","Cargo.toml":"b4b975265a565070b59e3a4224efdd58ec458d585b4a50fbbe917fc94283b852","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"69036b033e4bb951821964dbc3d9b1efe6913a6e36d9c1f206de4035a1a85cc4","README.md":"453b187f7ca8e04f4a11e0a1a57ac13019823161a4ba72835ed16d1539bc2bbd","benches/bilock.rs":"60b9e0814b8396e0320d299273c6f91c2ccc09a2bb59eec92df74a1f0919e54f","benches/futures_unordered.rs":"fa2d3b5e6cdfe1e941d78c119a696fb583341fa0a0895ec2692e6d374ceb9a0e","benches/poll.rs":"ca369079c4db366a180be22f406eaf8e94e2e771c02568eb35d89e63093006cf","benches/sync_mpsc.rs":"8d4dbf78afcdf61fc72da326c4810bc797462771707d079f95a7f75aa2ec0ec0","benches/thread_notify.rs":"1992b1e2b352fbc15a611d1318ac1bf6f19318d769086d55c80e6863f1b0e106","src/executor.rs":"80466c075daf030e07cc0d053618837cb73c07f5399b3d65016925f4488adb73","src/future/and_then.rs":"15653d392d331a1fc4619129f737acc28525c88d1675b7fcea6ed27c5b1bf302","src/future/catch_unwind.rs":"dfef6b6a66c09574338046cf23b0c6aacd8200872d512b831d6dc12038f05298","src/future/chain.rs":"4d712e989e079f4164d5d9fe3bb522d521094b0d8083ee639350570444e5bb93","src/future/either.rs":"898813aa84c19946203dd076050035d899014a6b0749ba50f41ae148580f7169","src/future/empty.rs":"b549a1ca0f21bc6d1a26d9063a9a60deb9235ff7eff5db915050115fed91a9c7","src/future/flatten.rs":"7eb15429fcc749326371fe571e1f7d294d7b83f7557e6e1971e2206180253d65","src/future/flatten_stream.rs":"cf914425c3606b61c046df5c43d64266d6f2328693e4122441f9bbcf7cb0a4e1","src/future/from_err.rs":"a1f42d95f7b52e80c2e5a03b44cbce0efbe5fc486dfe33d799b74ab9ba9057ab","src/future/fuse.rs":"3920c819b850c8f04b3868eae70dc0d3e6802ff0b517501f3aa5057a3b632102","src/future/inspect.rs":"89c362d8402dddd784bcc54e62ca27657ca8108e1ae8de5a7237e08650e10636","src/future/into_stream.rs":"0fa6bc4d70e8b4d75cf45fba53b39f033b87574103fffea4090b78f049bf43d0","src/future/join.rs":"b1dcefb03b1cb4e609ad2e79ba9a6cfab24235d7a4fff7fb9daf2c8fbf0f3d70","src/future/join_all.rs":"30fc27cbc1248046937b441a165a911e9ed1cd887ad6f3aeeb573b59c43e9cbf","src/future/lazy.rs":"1a2025bae3675fb682cefbf8a88bbb7a7519cfdee42dd6b3049a4d2b7ab8b5b1","src/future/loop_fn.rs":"5bd952247ae4e9d31dff77386bbd3700f596da136ea53e9e9944266af3f08688","src/future/map.rs":"91e148d9adaea929b85ede63c71fb07ef9b5611db906a13eedad2cf551745b47","src/future/map_err.rs":"2c8e87fa8ff56061722db6c69aaba588e6df6835a4e2fe84826f0bd4fed2e007","src/future/mod.rs":"a0a2f09ffdcbe20e0b210be3fe3d0d6863b8472ea84cd677af57074a9a618166","src/future/option.rs":"93270226cadcfa349250023e2070e687cf595831f427904ca744f7bc50342ded","src/future/or_else.rs":"444567101c4c437b184aa2e2eec0cf4363af442c0afc58d6508d3d2ac86489a9","src/future/poll_fn.rs":"817bfb75e7c43ca96a53e8cc9f48606c92c3c6742b07a732ce79a8f9b7bf8808","src/future/result.rs":"cc62c2377defb7b53aa859bf05c41c52a9cf8583378b7072bb2b45232d5fc9c5","src/future/select.rs":"73efd98004d5d8c46607bf770ff07a810bcdbe05cce0e8e4f41f5e659fd44203","src/future/select2.rs":"cfbbf3a9794109c56a3703456fae6111826bc25f98f2f36b234d483eeeeab482","src/future/select_all.rs":"b009e57ac241a3aba78db0bb751432cb99c1e91b8bae1b3baf225921f0daa441","src/future/select_ok.rs":"4884896914d8903edbfa12b5e255d35d5b2c91a9182ce6f774978db636617905","src/future/shared.rs":"4d53dc900b6e68a9854da2f1d391c8e724790d06d67ba1b3fb65b0ad73347f14","src/future/then.rs":"c49b388ab3c78979ad9ae40f6e859ee98e9351bdb11e3c3f1ad4ceca77651a56","src/lib.rs":"34cd577dc7d92d1922c679903c092d3d818a824148076ff0eec3ff5f296b099c","src/lock.rs":"fe4c8185f9774a134d4ce27af4a9c8b25f30f7dcc6990473210d66b6b8936ce4","src/poll.rs":"df74c3a8169d7895f3c46dd6de99edd77bd024b85e26b1d0644d2b8e5ef515b9","src/resultstream.rs":"365bc127c0410badb58ea2beb2abae546968ba3ac91abe2140e93e0c3620228f","src/sink/buffer.rs":"17e6bad2434f31630494a9a98e40a287da8a603515885ab8a17199ab0e5f8e46","src/sink/fanout.rs":"1fbcabdb1d22a43919417790082dc27ac65e2a100263504b6664a0b5e0657ae1","src/sink/flush.rs":"6c9a3bb9705c740e601ca6101cf6e6a87f2568661cff39a3576ef55986e3cb60","src/sink/from_err.rs":"b6d6e43c1f90c70bc1576ac2c9f1a7777fc07eef419721850962d896ac6cc3de","src/sink/map_err.rs":"b34a60880336b536666c1047f1919dd90eeed10b869e9c679fa928a3d5321112","src/sink/mod.rs":"4b4d80d008bfa8d0abc83cd640dc9c107423c7920795678c079c544c037ab632","src/sink/send.rs":"019f3f8ab450edc0adb864e4b819f5b0d4cfe9dc33a53093c2aa18e1eb6270dc","src/sink/send_all.rs":"b05047459faceecf0dfd5e6280014c31f5a2a1058974785db8ede497c10a1e79","src/sink/wait.rs":"9c70fdd54c642e4ecf7d9b0ff1fbb2df9c89349dfd60b5482748cd93c6dc301e","src/sink/with.rs":"a122cc26108cb3396db12cb2107c576d366c61191f656acedd5ff6c65165fcfc","src/sink/with_flat_map.rs":"7b0f367d98a99d297c3ce097e9858ad7b0dfdafbb66516cba0767b62beb01af3","src/stream/and_then.rs":"9f0f6ee06343ab03eebcb71257963e76d8e7208e4015b402cc8a58f793e37d79","src/stream/buffer_unordered.rs":"057c3dec32baf451ef02f44ef849086637e4d2cbb2d65907cc15ed9398fe131b","src/stream/buffered.rs":"4ced19e37e47182d5f9c7f852a7906c35b71ac4a5b2774a9101859defbecb190","src/stream/catch_unwind.rs":"957b935645f1744a4741962772c15e94370153f33e0db356309bf98ebb599c37","src/stream/chain.rs":"0b6b06cf5aaf0c2f665c61c65766d6113e24f690ebd9ad3a89abfa521e2ce9b2","src/stream/channel.rs":"f728402228fea0be01ec5cf1d02e49e52666c0c9ea986708d18e24f30376f6de","src/stream/chunks.rs":"455481ae5bc83cde009dc73a5ba9d1fc6281dd5750591e7d08eb25f149cd822b","src/stream/collect.rs":"e770850c7ed2d458b521c12af4ee76adf2303919849d2f95fa93fdf574c86d37","src/stream/concat.rs":"747723d73dc8edfe807834835362abc305704fc9cd9c1faf7b387b3d02cd397e","src/stream/empty.rs":"e8e2820fd3b2329a6987a11c3b3f28849f49427d1a745f2bdc7a4982476514e7","src/stream/filter.rs":"4abaf6c7bd3ecbccf7deac7920cc6bdc1b17875bedf7c6acd7e702254b3b83ba","src/stream/filter_map.rs":"573079f98efc38bbc68746084702b952ccb035bd8238c3c30fa103979865ed0e","src/stream/flatten.rs":"f2edce326745373c9c524bb574ce18584be95c7fd1a0ef875256b39891219b18","src/stream/fold.rs":"7f397373ed66560ff1eb0cffc5dafaf1569d3c8155fe418cc2bf6fc33faec230","src/stream/for_each.rs":"bd7f96bf551a829e37a54fd529e0b68a8868480797df039c75e1f226639cf096","src/stream/forward.rs":"ad33478f18e830ce8d85c3d5555d030a3f599c2546ad5554710c5ed844607a93","src/stream/from_err.rs":"bde1791790030c480aa88c6f7b235703d5b400249c841c8b045ea2203728b96c","src/stream/fuse.rs":"5d544151de7e5a3ce8a47bdeabe5cc9beaf0937b1eeed67e8d76842f54dea65d","src/stream/future.rs":"8f72146483c0423cbc11d45c76ee219ed12d940164c83199bb85cd6d5d64c22d","src/stream/futures_ordered.rs":"82e46576eb5201bd00470831353ea4dd9fcd6bc2d194452bda385806f7a25586","src/stream/futures_unordered.rs":"e7287b90083f4122522b721269b655ae37ebfcd16256d6bbbad349465eed6812","src/stream/inspect.rs":"4a1e7d7bbb0842a7021c5145bb1b64dbc213cfdccff51fe8399e3120c123eab5","src/stream/inspect_err.rs":"b4f2bc6a139df8f8eb403aafbca91c05b3093d3a6e13cef034a639fbe3ebe01e","src/stream/iter.rs":"cfff6b28759ccf390e8367f9f63209133c16e7fa53c7ae71167f318ba3ec624b","src/stream/iter_ok.rs":"5165cb02972776515734e0f343e626fbb448b65b38cdeacffbd86116f3c3cd37","src/stream/iter_result.rs":"9db38b1066d9adc1ece496432127049d36fb4b9895660c2af2b7ac28510c9084","src/stream/map.rs":"ba16b1469e519377939cf3bd073b258ac41e6349aab1c59393e3b30178a56496","src/stream/map_err.rs":"5ce9a279fde1f4f0887435856e1efa4fdeda749d43f4bab658b0abd216bc0a6f","src/stream/merge.rs":"63bb60ca386e280985cee8e16ae8b07f02d57aa8a0fa877ae01fb8b4678366d0","src/stream/mod.rs":"5fe336a9e59e6e92f2fef56b95757f0fdd9a350de89b38e09e6e4a31a8ada299","src/stream/once.rs":"277c960dc4bfa09fcc6112efa4e38a9fe937dc31fff440405e60bfd843f3c1ab","src/stream/or_else.rs":"c11ea499d85d6204ad083058eeca9dbf29873c49ee21bf01f9fe53e9ec3bba52","src/stream/peek.rs":"25d78baa0b3e30d2d1c72d1f3b1aa2a28811522d345dceefec587beb18b70fe2","src/stream/poll_fn.rs":"1dffbe60bd50c19efb71de2f768eecf70fa280b0d9c9cb889d16bb43b1619c8b","src/stream/repeat.rs":"807f2be5c9c1e7d54954f73ee38a373e71177aca43be8866712798f29ab541c2","src/stream/select.rs":"027873d9142e896272f7471cccaaccb133bf9f696a3f7510f3fb1aa4253a7c09","src/stream/skip.rs":"d7c839ca15f830709ebedd9526bb9ebd64ee22cb944e44213ce850a1383b71fa","src/stream/skip_while.rs":"aeb9bd64530bfaa631f4ca9500861c62fbf32849b09383eb26904bedd8b8b269","src/stream/split.rs":"c9b391fcbf3d1762bde442fd3549bd4739d2f9f486e88063650d42fea33c6af3","src/stream/take.rs":"9872429dd89cb34755b514abde9b6a876da076aea0449fcadfcc48e982507f21","src/stream/take_while.rs":"36bc2a33850ba2b58fb0da3866c96c8f4dfbd81133e615fda031518e71d425b5","src/stream/then.rs":"c7c66e27180cf2d98694de27504283a32444a0d0d6919ab25b3621fa6169408d","src/stream/unfold.rs":"5e69718714cc38c5ca6d0a6f5243ab28e392bdc97d96e8ab9059d9f0e772120c","src/stream/wait.rs":"936a15df4499d188f210cb0133bc8ad25e33e5b674a96105b4da549f32e92b40","src/stream/zip.rs":"33f1401683a29ce194927533c40bdbbc0783c552cf0b666f268fa7109e593853","src/sync/bilock.rs":"def09b26f9d66f2be0a8885ad6cf7106c3a073493bad591fc4a068212f0d739f","src/sync/mod.rs":"27ad26777f600f7054215fccdff07f4303182af2a6e0998d4229d62b090b7aac","src/sync/mpsc/mod.rs":"97542ef9fcbe338f2ac0ce982a9af11883aded33d3b4ce34a788cf98e00a7d3f","src/sync/mpsc/queue.rs":"b39889f1b2000a3de995a50f46243f97a98d3cce7c6de4b95c4d8ffeb42af918","src/sync/oneshot.rs":"5d41f1d19b78ada7d5587d0fb5751de5886281cf59889ba1b77cbde399975f1f","src/task.rs":"38e6bff1ec9ba6d62825793865185b68a7b4688f373adb039f54374e564b41d0","src/task_impl/atomic_task.rs":"027606777e948f37a5931a152f9e755e5a235da0131a396f71e39945f04c7961","src/task_impl/core.rs":"e3aff0cc6f0604a24950c2a5f9076e338b33f30581c5f503aa3ce230d42c44f4","src/task_impl/mod.rs":"a026baea5e1ba8157f65979726060182ebcae17c4a7bdd63b5e946ea3c6f5101","src/task_impl/std/data.rs":"9b6210811c095c4d0ec0f59a566bb8f5bc4b6ba544c72a4565dc47f3b7fbfab9","src/task_impl/std/mod.rs":"f67d06c30d11e4b33e9432e7b292f8a5888f6f094b48f781a23272e2bd218847","src/task_impl/std/task_rc.rs":"a6e46e79fecb1497d603c016f4f1b14523346f74af800c9c27c069229d62dc25","src/task_impl/std/unpark_mutex.rs":"7a53b7209ff00880bce9d912c249b077870625ca87fe9ab7b0f441d3af430302","src/unsync/mod.rs":"e5da32f78212646f0161fec2e7193cda830f541bc9ae37361fbcf82e99cc1d86","src/unsync/mpsc.rs":"ef63328496eeaa6575a17525193c6093e7803df3a64355a40f0187119ca1d731","src/unsync/oneshot.rs":"89661388a87d4ac83befc31df9ad11e6a8c6104e2dde7be9e3585d7549cfe8c4","tests/all.rs":"483cfb9ed40cbffc9c9c84cc8e19711fad2fdace74afea95c57c12ecd46d8524","tests/bilock.rs":"ad0a2b79a135d653c3dd5fe6ec7b2fc90c8ea287ba7e54a1a6140b0ea03ade97","tests/buffer_unordered.rs":"50ceb305da08fa095ee40a8f145fa9d95db59372cca949d77f011bbabc072152","tests/channel.rs":"cf5b59e84722b54e37aed7edaef5e2d1036b3ff7c278167228157dd4e9dae323","tests/eager_drop.rs":"e0a615c39f1fb9baae543212e72a165f68e7576f6b8c6db1809149d819bd546b","tests/eventual.rs":"73cbd3836a598175439b5dc5597f7e464dfbc6d77379aaae1172c6c7f85220e5","tests/fuse.rs":"feba43c51cbeeb383f6ebba4a4c75107de69a3cdb3eadb3e673fbeb5a91f9ac4","tests/future_flatten_stream.rs":"133b91a9e2170849ed7dbcb4024675873a781bf2dd190cfcaa9c41418c3ccb97","tests/futures_ordered.rs":"ad1d83d09a0600dda9d084616d3cef03bbc89aa2da6a6b44898839df1de32e95","tests/futures_unordered.rs":"b5e665e6921670dd88983432b7c33f760dabf75711f3e754358cefc47f5f17c1","tests/inspect.rs":"d7706a175be9ed6ecc09d7a45e1559160e00da85fa8a9a7caec4c53918999842","tests/mpsc-close.rs":"62c1d2acaf60e3e896471fef6a507a125b336c04781237de8dc9d13e59cfa9fc","tests/mpsc.rs":"082f05481952a08a5e33fd6655b17f4f7b4461ad78412323be248073c8ee3542","tests/oneshot.rs":"a8773b3a65e79944045118f36bfd81fceb826d4e2846b46f86db37a02d7ae1f4","tests/ready_queue.rs":"3d50c4e71e3954c5b8e2672255b6af33abaebc16172c038e64c3323d633693c0","tests/recurse.rs":"16bd311747c6d00035febb4b6c30e0fb6d03f3398b9a175cbb46f46ac5466beb","tests/select_all.rs":"3666e95ea94da17abb1899101e51b294af576bc446119fbc8aea5bb2991f439a","tests/select_ok.rs":"7a740e5b2d70c7776202ed1495b016f6e63ae1de06ca0f12ab21fcb3117450a9","tests/shared.rs":"5916ecfd2af1ac74843ee1a85da2a8f61513568ff334242a60b1ee9459f2eed8","tests/sink.rs":"a6241723f306183900873c9f7cfe9e2c3096d880c90bef5a5a6d53f2a3237882","tests/split.rs":"24dd293f049a37bfaabb02ae558c81e9fef9298a2ce43ecb544450b045c15f5c","tests/stream.rs":"9cc5fc74be8e299491927f04008665da108aa47ba68d42256a07c79030da171e","tests/stream_catch_unwind.rs":"6cee77f455a671d038aac24cf2f79636f1c0a5d8900957a2fed0ee3ed99832b8","tests/support/local_executor.rs":"d082081397d0cbe9a3e0e20fdd23df6364016dd8f6c6a0db3441a9cde4268f35","tests/support/mod.rs":"1961189f57851a468e518327da0b7893eee990e477b82a278e0015f25b5e5a1c","tests/unfold.rs":"27ff8c3c83b333094bbffe6aebadf3730f0e35d1367b7b602a3df4e233d934d8","tests/unsync-oneshot.rs":"e676b37a64e1d6c0816d55cf443d86249ec2ff8180f1fc0d009de51e6842dac8","tests/unsync.rs":"ec7d4c7e46b8af1a1719f818e6b1777553fd6b7cc5c6e4df1a98efb19d52e933"},"package":"3a471a38ef8ed83cd6e40aa59c1ffe17db6855c18e3604d9c4ed8c08ebc28678"}
\ No newline at end of file
diff --git a/third_party/rust/futures-0.1.29/CHANGELOG.md b/third_party/rust/futures-0.1.31/CHANGELOG.md
similarity index 100%
rename from third_party/rust/futures-0.1.29/CHANGELOG.md
rename to third_party/rust/futures-0.1.31/CHANGELOG.md
diff --git a/third_party/rust/futures-0.1.29/Cargo.toml b/third_party/rust/futures-0.1.31/Cargo.toml
similarity index 88%
rename from third_party/rust/futures-0.1.29/Cargo.toml
rename to third_party/rust/futures-0.1.31/Cargo.toml
index 88fe68280045330e077a707f5c274dc288658291..23e9c4b22523dac322969fbc28892c268ea1b6ac 100644
--- a/third_party/rust/futures-0.1.29/Cargo.toml
+++ b/third_party/rust/futures-0.1.31/Cargo.toml
@@ -12,7 +12,7 @@
 
 [package]
 name = "futures"
-version = "0.1.29"
+version = "0.1.31"
 authors = ["Alex Crichton <alex@alexcrichton.com>"]
 description = "An implementation of futures and streams featuring zero allocations,\ncomposability, and iterator-like interfaces.\n"
 homepage = "https://github.com/rust-lang-nursery/futures-rs"
@@ -30,8 +30,3 @@ default = ["use_std", "with-deprecated"]
 nightly = []
 use_std = []
 with-deprecated = []
-[badges.appveyor]
-repository = "rust-lang-nursery/futures-rs"
-
-[badges.travis-ci]
-repository = "rust-lang-nursery/futures-rs"
diff --git a/third_party/rust/futures-0.1.29/LICENSE-APACHE b/third_party/rust/futures-0.1.31/LICENSE-APACHE
similarity index 100%
rename from third_party/rust/futures-0.1.29/LICENSE-APACHE
rename to third_party/rust/futures-0.1.31/LICENSE-APACHE
diff --git a/third_party/rust/futures-0.1.29/LICENSE-MIT b/third_party/rust/futures-0.1.31/LICENSE-MIT
similarity index 100%
rename from third_party/rust/futures-0.1.29/LICENSE-MIT
rename to third_party/rust/futures-0.1.31/LICENSE-MIT
diff --git a/third_party/rust/futures-0.1.29/README.md b/third_party/rust/futures-0.1.31/README.md
similarity index 83%
rename from third_party/rust/futures-0.1.29/README.md
rename to third_party/rust/futures-0.1.31/README.md
index 3052efcb18ad39d9252de030fca4a2f6a35ad840..1c33d5ddbb502a20a1cfbe4ec1f9fd36891e7c60 100644
--- a/third_party/rust/futures-0.1.29/README.md
+++ b/third_party/rust/futures-0.1.31/README.md
@@ -2,8 +2,7 @@
 
 This library is an implementation of **zero-cost futures** in Rust.
 
-[![Build Status](https://travis-ci.org/rust-lang-nursery/futures-rs.svg?branch=master)](https://travis-ci.org/rust-lang-nursery/futures-rs)
-[![Build status](https://ci.appveyor.com/api/projects/status/yl5w3ittk4kggfsh?svg=true)](https://ci.appveyor.com/project/rust-lang-nursery/futures-rs)
+[![Build Status](https://img.shields.io/github/workflow/status/rust-lang/futures-rs/CI/master)](https://github.com/rust-lang/futures-rs/actions)
 [![Crates.io](https://img.shields.io/crates/v/futures.svg?maxAge=2592000)](https://crates.io/crates/futures)
 
 [Documentation](https://docs.rs/futures)
diff --git a/third_party/rust/futures-0.1.29/benches/bilock.rs b/third_party/rust/futures-0.1.31/benches/bilock.rs
similarity index 100%
rename from third_party/rust/futures-0.1.29/benches/bilock.rs
rename to third_party/rust/futures-0.1.31/benches/bilock.rs
diff --git a/third_party/rust/futures-0.1.29/benches/futures_unordered.rs b/third_party/rust/futures-0.1.31/benches/futures_unordered.rs
similarity index 100%
rename from third_party/rust/futures-0.1.29/benches/futures_unordered.rs
rename to third_party/rust/futures-0.1.31/benches/futures_unordered.rs
diff --git a/third_party/rust/futures-0.1.29/benches/poll.rs b/third_party/rust/futures-0.1.31/benches/poll.rs
similarity index 100%
rename from third_party/rust/futures-0.1.29/benches/poll.rs
rename to third_party/rust/futures-0.1.31/benches/poll.rs
diff --git a/third_party/rust/futures-0.1.29/benches/sync_mpsc.rs b/third_party/rust/futures-0.1.31/benches/sync_mpsc.rs
similarity index 100%
rename from third_party/rust/futures-0.1.29/benches/sync_mpsc.rs
rename to third_party/rust/futures-0.1.31/benches/sync_mpsc.rs
diff --git a/third_party/rust/futures-0.1.29/benches/thread_notify.rs b/third_party/rust/futures-0.1.31/benches/thread_notify.rs
similarity index 100%
rename from third_party/rust/futures-0.1.29/benches/thread_notify.rs
rename to third_party/rust/futures-0.1.31/benches/thread_notify.rs
diff --git a/third_party/rust/futures-0.1.29/src/executor.rs b/third_party/rust/futures-0.1.31/src/executor.rs
similarity index 100%
rename from third_party/rust/futures-0.1.29/src/executor.rs
rename to third_party/rust/futures-0.1.31/src/executor.rs
diff --git a/third_party/rust/futures-0.1.29/src/future/and_then.rs b/third_party/rust/futures-0.1.31/src/future/and_then.rs
similarity index 100%
rename from third_party/rust/futures-0.1.29/src/future/and_then.rs
rename to third_party/rust/futures-0.1.31/src/future/and_then.rs
diff --git a/third_party/rust/futures-0.1.29/src/future/catch_unwind.rs b/third_party/rust/futures-0.1.31/src/future/catch_unwind.rs
similarity index 100%
rename from third_party/rust/futures-0.1.29/src/future/catch_unwind.rs
rename to third_party/rust/futures-0.1.31/src/future/catch_unwind.rs
diff --git a/third_party/rust/futures-0.1.29/src/future/chain.rs b/third_party/rust/futures-0.1.31/src/future/chain.rs
similarity index 100%
rename from third_party/rust/futures-0.1.29/src/future/chain.rs
rename to third_party/rust/futures-0.1.31/src/future/chain.rs
diff --git a/third_party/rust/futures-0.1.29/src/future/either.rs b/third_party/rust/futures-0.1.31/src/future/either.rs
similarity index 100%
rename from third_party/rust/futures-0.1.29/src/future/either.rs
rename to third_party/rust/futures-0.1.31/src/future/either.rs
diff --git a/third_party/rust/futures-0.1.29/src/future/empty.rs b/third_party/rust/futures-0.1.31/src/future/empty.rs
similarity index 100%
rename from third_party/rust/futures-0.1.29/src/future/empty.rs
rename to third_party/rust/futures-0.1.31/src/future/empty.rs
diff --git a/third_party/rust/futures-0.1.29/src/future/flatten.rs b/third_party/rust/futures-0.1.31/src/future/flatten.rs
similarity index 100%
rename from third_party/rust/futures-0.1.29/src/future/flatten.rs
rename to third_party/rust/futures-0.1.31/src/future/flatten.rs
diff --git a/third_party/rust/futures-0.1.29/src/future/flatten_stream.rs b/third_party/rust/futures-0.1.31/src/future/flatten_stream.rs
similarity index 100%
rename from third_party/rust/futures-0.1.29/src/future/flatten_stream.rs
rename to third_party/rust/futures-0.1.31/src/future/flatten_stream.rs
diff --git a/third_party/rust/futures-0.1.29/src/future/from_err.rs b/third_party/rust/futures-0.1.31/src/future/from_err.rs
similarity index 100%
rename from third_party/rust/futures-0.1.29/src/future/from_err.rs
rename to third_party/rust/futures-0.1.31/src/future/from_err.rs
diff --git a/third_party/rust/futures-0.1.29/src/future/fuse.rs b/third_party/rust/futures-0.1.31/src/future/fuse.rs
similarity index 100%
rename from third_party/rust/futures-0.1.29/src/future/fuse.rs
rename to third_party/rust/futures-0.1.31/src/future/fuse.rs
diff --git a/third_party/rust/futures-0.1.29/src/future/inspect.rs b/third_party/rust/futures-0.1.31/src/future/inspect.rs
similarity index 100%
rename from third_party/rust/futures-0.1.29/src/future/inspect.rs
rename to third_party/rust/futures-0.1.31/src/future/inspect.rs
diff --git a/third_party/rust/futures-0.1.29/src/future/into_stream.rs b/third_party/rust/futures-0.1.31/src/future/into_stream.rs
similarity index 100%
rename from third_party/rust/futures-0.1.29/src/future/into_stream.rs
rename to third_party/rust/futures-0.1.31/src/future/into_stream.rs
diff --git a/third_party/rust/futures-0.1.29/src/future/join.rs b/third_party/rust/futures-0.1.31/src/future/join.rs
similarity index 100%
rename from third_party/rust/futures-0.1.29/src/future/join.rs
rename to third_party/rust/futures-0.1.31/src/future/join.rs
diff --git a/third_party/rust/futures-0.1.29/src/future/join_all.rs b/third_party/rust/futures-0.1.31/src/future/join_all.rs
similarity index 100%
rename from third_party/rust/futures-0.1.29/src/future/join_all.rs
rename to third_party/rust/futures-0.1.31/src/future/join_all.rs
diff --git a/third_party/rust/futures-0.1.29/src/future/lazy.rs b/third_party/rust/futures-0.1.31/src/future/lazy.rs
similarity index 100%
rename from third_party/rust/futures-0.1.29/src/future/lazy.rs
rename to third_party/rust/futures-0.1.31/src/future/lazy.rs
diff --git a/third_party/rust/futures-0.1.29/src/future/loop_fn.rs b/third_party/rust/futures-0.1.31/src/future/loop_fn.rs
similarity index 100%
rename from third_party/rust/futures-0.1.29/src/future/loop_fn.rs
rename to third_party/rust/futures-0.1.31/src/future/loop_fn.rs
diff --git a/third_party/rust/futures-0.1.29/src/future/map.rs b/third_party/rust/futures-0.1.31/src/future/map.rs
similarity index 100%
rename from third_party/rust/futures-0.1.29/src/future/map.rs
rename to third_party/rust/futures-0.1.31/src/future/map.rs
diff --git a/third_party/rust/futures-0.1.29/src/future/map_err.rs b/third_party/rust/futures-0.1.31/src/future/map_err.rs
similarity index 100%
rename from third_party/rust/futures-0.1.29/src/future/map_err.rs
rename to third_party/rust/futures-0.1.31/src/future/map_err.rs
diff --git a/third_party/rust/futures-0.1.29/src/future/mod.rs b/third_party/rust/futures-0.1.31/src/future/mod.rs
similarity index 100%
rename from third_party/rust/futures-0.1.29/src/future/mod.rs
rename to third_party/rust/futures-0.1.31/src/future/mod.rs
diff --git a/third_party/rust/futures-0.1.29/src/future/option.rs b/third_party/rust/futures-0.1.31/src/future/option.rs
similarity index 100%
rename from third_party/rust/futures-0.1.29/src/future/option.rs
rename to third_party/rust/futures-0.1.31/src/future/option.rs
diff --git a/third_party/rust/futures-0.1.29/src/future/or_else.rs b/third_party/rust/futures-0.1.31/src/future/or_else.rs
similarity index 100%
rename from third_party/rust/futures-0.1.29/src/future/or_else.rs
rename to third_party/rust/futures-0.1.31/src/future/or_else.rs
diff --git a/third_party/rust/futures-0.1.29/src/future/poll_fn.rs b/third_party/rust/futures-0.1.31/src/future/poll_fn.rs
similarity index 100%
rename from third_party/rust/futures-0.1.29/src/future/poll_fn.rs
rename to third_party/rust/futures-0.1.31/src/future/poll_fn.rs
diff --git a/third_party/rust/futures-0.1.29/src/future/result.rs b/third_party/rust/futures-0.1.31/src/future/result.rs
similarity index 100%
rename from third_party/rust/futures-0.1.29/src/future/result.rs
rename to third_party/rust/futures-0.1.31/src/future/result.rs
diff --git a/third_party/rust/futures-0.1.29/src/future/select.rs b/third_party/rust/futures-0.1.31/src/future/select.rs
similarity index 100%
rename from third_party/rust/futures-0.1.29/src/future/select.rs
rename to third_party/rust/futures-0.1.31/src/future/select.rs
diff --git a/third_party/rust/futures-0.1.29/src/future/select2.rs b/third_party/rust/futures-0.1.31/src/future/select2.rs
similarity index 100%
rename from third_party/rust/futures-0.1.29/src/future/select2.rs
rename to third_party/rust/futures-0.1.31/src/future/select2.rs
diff --git a/third_party/rust/futures-0.1.29/src/future/select_all.rs b/third_party/rust/futures-0.1.31/src/future/select_all.rs
similarity index 100%
rename from third_party/rust/futures-0.1.29/src/future/select_all.rs
rename to third_party/rust/futures-0.1.31/src/future/select_all.rs
diff --git a/third_party/rust/futures-0.1.29/src/future/select_ok.rs b/third_party/rust/futures-0.1.31/src/future/select_ok.rs
similarity index 100%
rename from third_party/rust/futures-0.1.29/src/future/select_ok.rs
rename to third_party/rust/futures-0.1.31/src/future/select_ok.rs
diff --git a/third_party/rust/futures-0.1.29/src/future/shared.rs b/third_party/rust/futures-0.1.31/src/future/shared.rs
similarity index 79%
rename from third_party/rust/futures-0.1.29/src/future/shared.rs
rename to third_party/rust/futures-0.1.31/src/future/shared.rs
index f40c0be17020dc20f2ad65af9526118b4c5deaed..e3b6d2fca7a518282237601acf28105233d76677 100644
--- a/third_party/rust/futures-0.1.29/src/future/shared.rs
+++ b/third_party/rust/futures-0.1.31/src/future/shared.rs
@@ -59,9 +59,8 @@ struct Notifier {
 
 const IDLE: usize = 0;
 const POLLING: usize = 1;
-const REPOLL: usize = 2;
-const COMPLETE: usize = 3;
-const POISONED: usize = 4;
+const COMPLETE: usize = 2;
+const POISONED: usize = 3;
 
 pub fn new<F: Future>(future: F) -> Shared<F> {
     Shared {
@@ -133,7 +132,7 @@ impl<F> Future for Shared<F>
             IDLE => {
                 // Lock acquired, fall through
             }
-            POLLING | REPOLL => {
+            POLLING => {
                 // Another task is currently polling, at this point we just want
                 // to ensure that our task handle is currently registered
 
@@ -146,56 +145,45 @@ impl<F> Future for Shared<F>
             _ => unreachable!(),
         }
 
-        loop {
-            struct Reset<'a>(&'a AtomicUsize);
+        struct Reset<'a>(&'a AtomicUsize);
 
-            impl<'a> Drop for Reset<'a> {
-                fn drop(&mut self) {
-                    use std::thread;
+        impl<'a> Drop for Reset<'a> {
+            fn drop(&mut self) {
+                use std::thread;
 
-                    if thread::panicking() {
-                        self.0.store(POISONED, SeqCst);
-                    }
+                if thread::panicking() {
+                    self.0.store(POISONED, SeqCst);
                 }
             }
+        }
 
-            let _reset = Reset(&self.inner.notifier.state);
-
-            // Poll the future
-            let res = unsafe {
-                (*self.inner.future.get()).as_mut().unwrap()
-                    .poll_future_notify(&self.inner.notifier, 0)
-            };
-            match res {
-                Ok(Async::NotReady) => {
-                    // Not ready, try to release the handle
-                    match self.inner.notifier.state.compare_and_swap(POLLING, IDLE, SeqCst) {
-                        POLLING => {
-                            // Success
-                            return Ok(Async::NotReady);
-                        }
-                        REPOLL => {
-                            // Gotta poll again!
-                            let prev = self.inner.notifier.state.swap(POLLING, SeqCst);
-                            assert_eq!(prev, REPOLL);
-                        }
-                        _ => unreachable!(),
+        let _reset = Reset(&self.inner.notifier.state);
+
+        // Poll the future
+        let res = unsafe {
+            (*self.inner.future.get()).as_mut().unwrap()
+                .poll_future_notify(&self.inner.notifier, 0)
+        };
+        match res {
+            Ok(Async::NotReady) => {
+                // Not ready, try to release the handle
+                match self.inner.notifier.state.compare_and_swap(POLLING, IDLE, SeqCst) {
+                    POLLING => {
+                        // Success
+                        return Ok(Async::NotReady);
                     }
-
+                    _ => unreachable!(),
                 }
-                Ok(Async::Ready(i)) => {
-                    unsafe {
-                        (*self.inner.result.get()) = Some(Ok(SharedItem { item: Arc::new(i) }));
-                    }
 
-                    break;
+            }
+            Ok(Async::Ready(i)) => {
+                unsafe {
+                    (*self.inner.result.get()) = Some(Ok(SharedItem { item: Arc::new(i) }));
                 }
-                Err(e) => {
-                    unsafe {
-                        (*self.inner.result.get()) = Some(Err(SharedError { error: Arc::new(e) }));
-                    }
-
-                    break;
+            }
+            Err(e) => {
+                unsafe {
+                    (*self.inner.result.get()) = Some(Err(SharedError { error: Arc::new(e) }));
                 }
             }
         }
@@ -225,8 +213,6 @@ impl<F> Drop for Shared<F> where F: Future {
 
 impl Notify for Notifier {
     fn notify(&self, _id: usize) {
-        self.state.compare_and_swap(POLLING, REPOLL, SeqCst);
-
         let waiters = mem::replace(&mut *self.waiters.lock().unwrap(), HashMap::new());
 
         for (_, waiter) in waiters {
@@ -302,6 +288,7 @@ impl<E> fmt::Display for SharedError<E>
 impl<E> error::Error for SharedError<E>
     where E: error::Error,
 {
+    #[allow(deprecated)]
     fn description(&self) -> &str {
         self.error.description()
     }
diff --git a/third_party/rust/futures-0.1.29/src/future/then.rs b/third_party/rust/futures-0.1.31/src/future/then.rs
similarity index 100%
rename from third_party/rust/futures-0.1.29/src/future/then.rs
rename to third_party/rust/futures-0.1.31/src/future/then.rs
diff --git a/third_party/rust/futures-0.1.29/src/lib.rs b/third_party/rust/futures-0.1.31/src/lib.rs
similarity index 99%
rename from third_party/rust/futures-0.1.29/src/lib.rs
rename to third_party/rust/futures-0.1.31/src/lib.rs
index 59e4874b2c0ab593965e78ca5690760cabd7ba4c..ccadb6777f10fed58134452d2cd67146e8178520 100644
--- a/third_party/rust/futures-0.1.29/src/lib.rs
+++ b/third_party/rust/futures-0.1.31/src/lib.rs
@@ -157,6 +157,7 @@
 
 #![no_std]
 #![deny(missing_docs, missing_debug_implementations)]
+#![allow(bare_trait_objects, unknown_lints)]
 #![doc(html_root_url = "https://docs.rs/futures/0.1")]
 
 #[macro_use]
diff --git a/third_party/rust/futures-0.1.29/src/lock.rs b/third_party/rust/futures-0.1.31/src/lock.rs
similarity index 100%
rename from third_party/rust/futures-0.1.29/src/lock.rs
rename to third_party/rust/futures-0.1.31/src/lock.rs
diff --git a/third_party/rust/futures-0.1.29/src/poll.rs b/third_party/rust/futures-0.1.31/src/poll.rs
similarity index 100%
rename from third_party/rust/futures-0.1.29/src/poll.rs
rename to third_party/rust/futures-0.1.31/src/poll.rs
diff --git a/third_party/rust/futures-0.1.29/src/resultstream.rs b/third_party/rust/futures-0.1.31/src/resultstream.rs
similarity index 100%
rename from third_party/rust/futures-0.1.29/src/resultstream.rs
rename to third_party/rust/futures-0.1.31/src/resultstream.rs
diff --git a/third_party/rust/futures-0.1.29/src/sink/buffer.rs b/third_party/rust/futures-0.1.31/src/sink/buffer.rs
similarity index 100%
rename from third_party/rust/futures-0.1.29/src/sink/buffer.rs
rename to third_party/rust/futures-0.1.31/src/sink/buffer.rs
diff --git a/third_party/rust/futures-0.1.29/src/sink/fanout.rs b/third_party/rust/futures-0.1.31/src/sink/fanout.rs
similarity index 100%
rename from third_party/rust/futures-0.1.29/src/sink/fanout.rs
rename to third_party/rust/futures-0.1.31/src/sink/fanout.rs
diff --git a/third_party/rust/futures-0.1.29/src/sink/flush.rs b/third_party/rust/futures-0.1.31/src/sink/flush.rs
similarity index 100%
rename from third_party/rust/futures-0.1.29/src/sink/flush.rs
rename to third_party/rust/futures-0.1.31/src/sink/flush.rs
diff --git a/third_party/rust/futures-0.1.29/src/sink/from_err.rs b/third_party/rust/futures-0.1.31/src/sink/from_err.rs
similarity index 100%
rename from third_party/rust/futures-0.1.29/src/sink/from_err.rs
rename to third_party/rust/futures-0.1.31/src/sink/from_err.rs
diff --git a/third_party/rust/futures-0.1.29/src/sink/map_err.rs b/third_party/rust/futures-0.1.31/src/sink/map_err.rs
similarity index 100%
rename from third_party/rust/futures-0.1.29/src/sink/map_err.rs
rename to third_party/rust/futures-0.1.31/src/sink/map_err.rs
diff --git a/third_party/rust/futures-0.1.29/src/sink/mod.rs b/third_party/rust/futures-0.1.31/src/sink/mod.rs
similarity index 100%
rename from third_party/rust/futures-0.1.29/src/sink/mod.rs
rename to third_party/rust/futures-0.1.31/src/sink/mod.rs
diff --git a/third_party/rust/futures-0.1.29/src/sink/send.rs b/third_party/rust/futures-0.1.31/src/sink/send.rs
similarity index 100%
rename from third_party/rust/futures-0.1.29/src/sink/send.rs
rename to third_party/rust/futures-0.1.31/src/sink/send.rs
diff --git a/third_party/rust/futures-0.1.29/src/sink/send_all.rs b/third_party/rust/futures-0.1.31/src/sink/send_all.rs
similarity index 100%
rename from third_party/rust/futures-0.1.29/src/sink/send_all.rs
rename to third_party/rust/futures-0.1.31/src/sink/send_all.rs
diff --git a/third_party/rust/futures-0.1.29/src/sink/wait.rs b/third_party/rust/futures-0.1.31/src/sink/wait.rs
similarity index 100%
rename from third_party/rust/futures-0.1.29/src/sink/wait.rs
rename to third_party/rust/futures-0.1.31/src/sink/wait.rs
diff --git a/third_party/rust/futures-0.1.29/src/sink/with.rs b/third_party/rust/futures-0.1.31/src/sink/with.rs
similarity index 100%
rename from third_party/rust/futures-0.1.29/src/sink/with.rs
rename to third_party/rust/futures-0.1.31/src/sink/with.rs
diff --git a/third_party/rust/futures-0.1.29/src/sink/with_flat_map.rs b/third_party/rust/futures-0.1.31/src/sink/with_flat_map.rs
similarity index 100%
rename from third_party/rust/futures-0.1.29/src/sink/with_flat_map.rs
rename to third_party/rust/futures-0.1.31/src/sink/with_flat_map.rs
diff --git a/third_party/rust/futures-0.1.29/src/stream/and_then.rs b/third_party/rust/futures-0.1.31/src/stream/and_then.rs
similarity index 100%
rename from third_party/rust/futures-0.1.29/src/stream/and_then.rs
rename to third_party/rust/futures-0.1.31/src/stream/and_then.rs
diff --git a/third_party/rust/futures-0.1.29/src/stream/buffer_unordered.rs b/third_party/rust/futures-0.1.31/src/stream/buffer_unordered.rs
similarity index 100%
rename from third_party/rust/futures-0.1.29/src/stream/buffer_unordered.rs
rename to third_party/rust/futures-0.1.31/src/stream/buffer_unordered.rs
diff --git a/third_party/rust/futures-0.1.29/src/stream/buffered.rs b/third_party/rust/futures-0.1.31/src/stream/buffered.rs
similarity index 100%
rename from third_party/rust/futures-0.1.29/src/stream/buffered.rs
rename to third_party/rust/futures-0.1.31/src/stream/buffered.rs
diff --git a/third_party/rust/futures-0.1.29/src/stream/catch_unwind.rs b/third_party/rust/futures-0.1.31/src/stream/catch_unwind.rs
similarity index 100%
rename from third_party/rust/futures-0.1.29/src/stream/catch_unwind.rs
rename to third_party/rust/futures-0.1.31/src/stream/catch_unwind.rs
diff --git a/third_party/rust/futures-0.1.29/src/stream/chain.rs b/third_party/rust/futures-0.1.31/src/stream/chain.rs
similarity index 100%
rename from third_party/rust/futures-0.1.29/src/stream/chain.rs
rename to third_party/rust/futures-0.1.31/src/stream/chain.rs
diff --git a/third_party/rust/futures-0.1.29/src/stream/channel.rs b/third_party/rust/futures-0.1.31/src/stream/channel.rs
similarity index 100%
rename from third_party/rust/futures-0.1.29/src/stream/channel.rs
rename to third_party/rust/futures-0.1.31/src/stream/channel.rs
diff --git a/third_party/rust/futures-0.1.29/src/stream/chunks.rs b/third_party/rust/futures-0.1.31/src/stream/chunks.rs
similarity index 100%
rename from third_party/rust/futures-0.1.29/src/stream/chunks.rs
rename to third_party/rust/futures-0.1.31/src/stream/chunks.rs
diff --git a/third_party/rust/futures-0.1.29/src/stream/collect.rs b/third_party/rust/futures-0.1.31/src/stream/collect.rs
similarity index 100%
rename from third_party/rust/futures-0.1.29/src/stream/collect.rs
rename to third_party/rust/futures-0.1.31/src/stream/collect.rs
diff --git a/third_party/rust/futures-0.1.29/src/stream/concat.rs b/third_party/rust/futures-0.1.31/src/stream/concat.rs
similarity index 100%
rename from third_party/rust/futures-0.1.29/src/stream/concat.rs
rename to third_party/rust/futures-0.1.31/src/stream/concat.rs
diff --git a/third_party/rust/futures-0.1.29/src/stream/empty.rs b/third_party/rust/futures-0.1.31/src/stream/empty.rs
similarity index 100%
rename from third_party/rust/futures-0.1.29/src/stream/empty.rs
rename to third_party/rust/futures-0.1.31/src/stream/empty.rs
diff --git a/third_party/rust/futures-0.1.29/src/stream/filter.rs b/third_party/rust/futures-0.1.31/src/stream/filter.rs
similarity index 100%
rename from third_party/rust/futures-0.1.29/src/stream/filter.rs
rename to third_party/rust/futures-0.1.31/src/stream/filter.rs
diff --git a/third_party/rust/futures-0.1.29/src/stream/filter_map.rs b/third_party/rust/futures-0.1.31/src/stream/filter_map.rs
similarity index 100%
rename from third_party/rust/futures-0.1.29/src/stream/filter_map.rs
rename to third_party/rust/futures-0.1.31/src/stream/filter_map.rs
diff --git a/third_party/rust/futures-0.1.29/src/stream/flatten.rs b/third_party/rust/futures-0.1.31/src/stream/flatten.rs
similarity index 100%
rename from third_party/rust/futures-0.1.29/src/stream/flatten.rs
rename to third_party/rust/futures-0.1.31/src/stream/flatten.rs
diff --git a/third_party/rust/futures-0.1.29/src/stream/fold.rs b/third_party/rust/futures-0.1.31/src/stream/fold.rs
similarity index 100%
rename from third_party/rust/futures-0.1.29/src/stream/fold.rs
rename to third_party/rust/futures-0.1.31/src/stream/fold.rs
diff --git a/third_party/rust/futures-0.1.29/src/stream/for_each.rs b/third_party/rust/futures-0.1.31/src/stream/for_each.rs
similarity index 100%
rename from third_party/rust/futures-0.1.29/src/stream/for_each.rs
rename to third_party/rust/futures-0.1.31/src/stream/for_each.rs
diff --git a/third_party/rust/futures-0.1.29/src/stream/forward.rs b/third_party/rust/futures-0.1.31/src/stream/forward.rs
similarity index 98%
rename from third_party/rust/futures-0.1.29/src/stream/forward.rs
rename to third_party/rust/futures-0.1.31/src/stream/forward.rs
index 1d8b731828bbb9bbfd2cafb3eb8f162d3f79f5f0..6722af8c20acebd817ec4158f3ccbf91984c37b7 100644
--- a/third_party/rust/futures-0.1.29/src/stream/forward.rs
+++ b/third_party/rust/futures-0.1.31/src/stream/forward.rs
@@ -91,7 +91,7 @@ impl<T, U> Future for Forward<T, U>
         }
 
         loop {
-            match self.stream_mut()
+            match self.stream.as_mut()
                 .expect("Attempted to poll Forward after completion")
                 .poll()?
             {
diff --git a/third_party/rust/futures-0.1.29/src/stream/from_err.rs b/third_party/rust/futures-0.1.31/src/stream/from_err.rs
similarity index 100%
rename from third_party/rust/futures-0.1.29/src/stream/from_err.rs
rename to third_party/rust/futures-0.1.31/src/stream/from_err.rs
diff --git a/third_party/rust/futures-0.1.29/src/stream/fuse.rs b/third_party/rust/futures-0.1.31/src/stream/fuse.rs
similarity index 100%
rename from third_party/rust/futures-0.1.29/src/stream/fuse.rs
rename to third_party/rust/futures-0.1.31/src/stream/fuse.rs
diff --git a/third_party/rust/futures-0.1.29/src/stream/future.rs b/third_party/rust/futures-0.1.31/src/stream/future.rs
similarity index 100%
rename from third_party/rust/futures-0.1.29/src/stream/future.rs
rename to third_party/rust/futures-0.1.31/src/stream/future.rs
diff --git a/third_party/rust/futures-0.1.29/src/stream/futures_ordered.rs b/third_party/rust/futures-0.1.31/src/stream/futures_ordered.rs
similarity index 100%
rename from third_party/rust/futures-0.1.29/src/stream/futures_ordered.rs
rename to third_party/rust/futures-0.1.31/src/stream/futures_ordered.rs
diff --git a/third_party/rust/futures-0.1.29/src/stream/futures_unordered.rs b/third_party/rust/futures-0.1.31/src/stream/futures_unordered.rs
similarity index 94%
rename from third_party/rust/futures-0.1.29/src/stream/futures_unordered.rs
rename to third_party/rust/futures-0.1.31/src/stream/futures_unordered.rs
index a183d6340620a0ddb51326bd973003a5bb4f277d..3f25c86f39494a4ee0f7b4250ffb7c5e9a9e45ae 100644
--- a/third_party/rust/futures-0.1.29/src/stream/futures_unordered.rs
+++ b/third_party/rust/futures-0.1.31/src/stream/futures_unordered.rs
@@ -274,6 +274,26 @@ impl<T> Stream for FuturesUnordered<T>
     type Error = T::Error;
 
     fn poll(&mut self) -> Poll<Option<T::Item>, T::Error> {
+        // Variable to determine how many times it is allowed to poll underlying
+        // futures without yielding.
+        //
+        // A single call to `poll_next` may potentially do a lot of work before
+        // yielding. This happens in particular if the underlying futures are awoken
+        // frequently but continue to return `Pending`. This is problematic if other
+        // tasks are waiting on the executor, since they do not get to run. This value
+        // caps the number of calls to `poll` on underlying futures a single call to
+        // `poll_next` is allowed to make.
+        //
+        // The value is the length of FuturesUnordered. This ensures that each
+        // future is polled only once at most per iteration.
+        //
+        // See also https://github.com/rust-lang/futures-rs/issues/2047.
+        let yield_every = self.len();
+
+        // Keep track of how many child futures we have polled,
+        // in case we want to forcibly yield.
+        let mut polled = 0;
+
         // Ensure `parent` is correctly set.
         self.inner.parent.register();
 
@@ -369,12 +389,21 @@ impl<T> Stream for FuturesUnordered<T>
                         future.poll()
                     })
                 };
+                polled += 1;
 
                 let ret = match res {
                     Ok(Async::NotReady) => {
                         let node = bomb.node.take().unwrap();
                         *node.future.get() = Some(future);
                         bomb.queue.link(node);
+
+                        if polled == yield_every {
+                            // We have polled a large number of futures in a row without yielding.
+                            // To ensure we do not starve other tasks waiting on the executor,
+                            // we yield here, but immediately wake ourselves up to continue.
+                            task_impl::current().notify();
+                            return Ok(Async::NotReady);
+                        }
                         continue
                     }
                     Ok(Async::Ready(e)) => Ok(Async::Ready(Some(e))),
diff --git a/third_party/rust/futures-0.1.29/src/stream/inspect.rs b/third_party/rust/futures-0.1.31/src/stream/inspect.rs
similarity index 100%
rename from third_party/rust/futures-0.1.29/src/stream/inspect.rs
rename to third_party/rust/futures-0.1.31/src/stream/inspect.rs
diff --git a/third_party/rust/futures-0.1.29/src/stream/inspect_err.rs b/third_party/rust/futures-0.1.31/src/stream/inspect_err.rs
similarity index 100%
rename from third_party/rust/futures-0.1.29/src/stream/inspect_err.rs
rename to third_party/rust/futures-0.1.31/src/stream/inspect_err.rs
diff --git a/third_party/rust/futures-0.1.29/src/stream/iter.rs b/third_party/rust/futures-0.1.31/src/stream/iter.rs
similarity index 100%
rename from third_party/rust/futures-0.1.29/src/stream/iter.rs
rename to third_party/rust/futures-0.1.31/src/stream/iter.rs
diff --git a/third_party/rust/futures-0.1.29/src/stream/iter_ok.rs b/third_party/rust/futures-0.1.31/src/stream/iter_ok.rs
similarity index 100%
rename from third_party/rust/futures-0.1.29/src/stream/iter_ok.rs
rename to third_party/rust/futures-0.1.31/src/stream/iter_ok.rs
diff --git a/third_party/rust/futures-0.1.29/src/stream/iter_result.rs b/third_party/rust/futures-0.1.31/src/stream/iter_result.rs
similarity index 100%
rename from third_party/rust/futures-0.1.29/src/stream/iter_result.rs
rename to third_party/rust/futures-0.1.31/src/stream/iter_result.rs
diff --git a/third_party/rust/futures-0.1.29/src/stream/map.rs b/third_party/rust/futures-0.1.31/src/stream/map.rs
similarity index 100%
rename from third_party/rust/futures-0.1.29/src/stream/map.rs
rename to third_party/rust/futures-0.1.31/src/stream/map.rs
diff --git a/third_party/rust/futures-0.1.29/src/stream/map_err.rs b/third_party/rust/futures-0.1.31/src/stream/map_err.rs
similarity index 100%
rename from third_party/rust/futures-0.1.29/src/stream/map_err.rs
rename to third_party/rust/futures-0.1.31/src/stream/map_err.rs
diff --git a/third_party/rust/futures-0.1.29/src/stream/merge.rs b/third_party/rust/futures-0.1.31/src/stream/merge.rs
similarity index 100%
rename from third_party/rust/futures-0.1.29/src/stream/merge.rs
rename to third_party/rust/futures-0.1.31/src/stream/merge.rs
diff --git a/third_party/rust/futures-0.1.29/src/stream/mod.rs b/third_party/rust/futures-0.1.31/src/stream/mod.rs
similarity index 100%
rename from third_party/rust/futures-0.1.29/src/stream/mod.rs
rename to third_party/rust/futures-0.1.31/src/stream/mod.rs
diff --git a/third_party/rust/futures-0.1.29/src/stream/once.rs b/third_party/rust/futures-0.1.31/src/stream/once.rs
similarity index 100%
rename from third_party/rust/futures-0.1.29/src/stream/once.rs
rename to third_party/rust/futures-0.1.31/src/stream/once.rs
diff --git a/third_party/rust/futures-0.1.29/src/stream/or_else.rs b/third_party/rust/futures-0.1.31/src/stream/or_else.rs
similarity index 100%
rename from third_party/rust/futures-0.1.29/src/stream/or_else.rs
rename to third_party/rust/futures-0.1.31/src/stream/or_else.rs
diff --git a/third_party/rust/futures-0.1.29/src/stream/peek.rs b/third_party/rust/futures-0.1.31/src/stream/peek.rs
similarity index 100%
rename from third_party/rust/futures-0.1.29/src/stream/peek.rs
rename to third_party/rust/futures-0.1.31/src/stream/peek.rs
diff --git a/third_party/rust/futures-0.1.29/src/stream/poll_fn.rs b/third_party/rust/futures-0.1.31/src/stream/poll_fn.rs
similarity index 100%
rename from third_party/rust/futures-0.1.29/src/stream/poll_fn.rs
rename to third_party/rust/futures-0.1.31/src/stream/poll_fn.rs
diff --git a/third_party/rust/futures-0.1.29/src/stream/repeat.rs b/third_party/rust/futures-0.1.31/src/stream/repeat.rs
similarity index 100%
rename from third_party/rust/futures-0.1.29/src/stream/repeat.rs
rename to third_party/rust/futures-0.1.31/src/stream/repeat.rs
diff --git a/third_party/rust/futures-0.1.29/src/stream/select.rs b/third_party/rust/futures-0.1.31/src/stream/select.rs
similarity index 100%
rename from third_party/rust/futures-0.1.29/src/stream/select.rs
rename to third_party/rust/futures-0.1.31/src/stream/select.rs
diff --git a/third_party/rust/futures-0.1.29/src/stream/skip.rs b/third_party/rust/futures-0.1.31/src/stream/skip.rs
similarity index 100%
rename from third_party/rust/futures-0.1.29/src/stream/skip.rs
rename to third_party/rust/futures-0.1.31/src/stream/skip.rs
diff --git a/third_party/rust/futures-0.1.29/src/stream/skip_while.rs b/third_party/rust/futures-0.1.31/src/stream/skip_while.rs
similarity index 100%
rename from third_party/rust/futures-0.1.29/src/stream/skip_while.rs
rename to third_party/rust/futures-0.1.31/src/stream/skip_while.rs
diff --git a/third_party/rust/futures-0.1.29/src/stream/split.rs b/third_party/rust/futures-0.1.31/src/stream/split.rs
similarity index 100%
rename from third_party/rust/futures-0.1.29/src/stream/split.rs
rename to third_party/rust/futures-0.1.31/src/stream/split.rs
diff --git a/third_party/rust/futures-0.1.29/src/stream/take.rs b/third_party/rust/futures-0.1.31/src/stream/take.rs
similarity index 100%
rename from third_party/rust/futures-0.1.29/src/stream/take.rs
rename to third_party/rust/futures-0.1.31/src/stream/take.rs
diff --git a/third_party/rust/futures-0.1.29/src/stream/take_while.rs b/third_party/rust/futures-0.1.31/src/stream/take_while.rs
similarity index 100%
rename from third_party/rust/futures-0.1.29/src/stream/take_while.rs
rename to third_party/rust/futures-0.1.31/src/stream/take_while.rs
diff --git a/third_party/rust/futures-0.1.29/src/stream/then.rs b/third_party/rust/futures-0.1.31/src/stream/then.rs
similarity index 100%
rename from third_party/rust/futures-0.1.29/src/stream/then.rs
rename to third_party/rust/futures-0.1.31/src/stream/then.rs
diff --git a/third_party/rust/futures-0.1.29/src/stream/unfold.rs b/third_party/rust/futures-0.1.31/src/stream/unfold.rs
similarity index 100%
rename from third_party/rust/futures-0.1.29/src/stream/unfold.rs
rename to third_party/rust/futures-0.1.31/src/stream/unfold.rs
diff --git a/third_party/rust/futures-0.1.29/src/stream/wait.rs b/third_party/rust/futures-0.1.31/src/stream/wait.rs
similarity index 100%
rename from third_party/rust/futures-0.1.29/src/stream/wait.rs
rename to third_party/rust/futures-0.1.31/src/stream/wait.rs
diff --git a/third_party/rust/futures-0.1.29/src/stream/zip.rs b/third_party/rust/futures-0.1.31/src/stream/zip.rs
similarity index 100%
rename from third_party/rust/futures-0.1.29/src/stream/zip.rs
rename to third_party/rust/futures-0.1.31/src/stream/zip.rs
diff --git a/third_party/rust/futures-0.1.29/src/sync/bilock.rs b/third_party/rust/futures-0.1.31/src/sync/bilock.rs
similarity index 100%
rename from third_party/rust/futures-0.1.29/src/sync/bilock.rs
rename to third_party/rust/futures-0.1.31/src/sync/bilock.rs
diff --git a/third_party/rust/futures-0.1.29/src/sync/mod.rs b/third_party/rust/futures-0.1.31/src/sync/mod.rs
similarity index 100%
rename from third_party/rust/futures-0.1.29/src/sync/mod.rs
rename to third_party/rust/futures-0.1.31/src/sync/mod.rs
diff --git a/third_party/rust/futures-0.1.29/src/sync/mpsc/mod.rs b/third_party/rust/futures-0.1.31/src/sync/mpsc/mod.rs
similarity index 100%
rename from third_party/rust/futures-0.1.29/src/sync/mpsc/mod.rs
rename to third_party/rust/futures-0.1.31/src/sync/mpsc/mod.rs
diff --git a/third_party/rust/futures-0.1.29/src/sync/mpsc/queue.rs b/third_party/rust/futures-0.1.31/src/sync/mpsc/queue.rs
similarity index 100%
rename from third_party/rust/futures-0.1.29/src/sync/mpsc/queue.rs
rename to third_party/rust/futures-0.1.31/src/sync/mpsc/queue.rs
diff --git a/third_party/rust/futures-0.1.29/src/sync/oneshot.rs b/third_party/rust/futures-0.1.31/src/sync/oneshot.rs
similarity index 100%
rename from third_party/rust/futures-0.1.29/src/sync/oneshot.rs
rename to third_party/rust/futures-0.1.31/src/sync/oneshot.rs
diff --git a/third_party/rust/futures-0.1.29/src/task.rs b/third_party/rust/futures-0.1.31/src/task.rs
similarity index 100%
rename from third_party/rust/futures-0.1.29/src/task.rs
rename to third_party/rust/futures-0.1.31/src/task.rs
diff --git a/third_party/rust/futures-0.1.29/src/task_impl/atomic_task.rs b/third_party/rust/futures-0.1.31/src/task_impl/atomic_task.rs
similarity index 100%
rename from third_party/rust/futures-0.1.29/src/task_impl/atomic_task.rs
rename to third_party/rust/futures-0.1.31/src/task_impl/atomic_task.rs
diff --git a/third_party/rust/futures-0.1.29/src/task_impl/core.rs b/third_party/rust/futures-0.1.31/src/task_impl/core.rs
similarity index 100%
rename from third_party/rust/futures-0.1.29/src/task_impl/core.rs
rename to third_party/rust/futures-0.1.31/src/task_impl/core.rs
diff --git a/third_party/rust/futures-0.1.29/src/task_impl/mod.rs b/third_party/rust/futures-0.1.31/src/task_impl/mod.rs
similarity index 100%
rename from third_party/rust/futures-0.1.29/src/task_impl/mod.rs
rename to third_party/rust/futures-0.1.31/src/task_impl/mod.rs
diff --git a/third_party/rust/futures-0.1.29/src/task_impl/std/data.rs b/third_party/rust/futures-0.1.31/src/task_impl/std/data.rs
similarity index 100%
rename from third_party/rust/futures-0.1.29/src/task_impl/std/data.rs
rename to third_party/rust/futures-0.1.31/src/task_impl/std/data.rs
diff --git a/third_party/rust/futures-0.1.29/src/task_impl/std/mod.rs b/third_party/rust/futures-0.1.31/src/task_impl/std/mod.rs
similarity index 99%
rename from third_party/rust/futures-0.1.29/src/task_impl/std/mod.rs
rename to third_party/rust/futures-0.1.31/src/task_impl/std/mod.rs
index eca750f7d844a3c1f8238c52afde27103f519c18..e82a23e5d0543fdc81f8ed6492c7396435178bed 100644
--- a/third_party/rust/futures-0.1.29/src/task_impl/std/mod.rs
+++ b/third_party/rust/futures-0.1.31/src/task_impl/std/mod.rs
@@ -5,7 +5,9 @@ use std::fmt;
 use std::marker::PhantomData;
 use std::mem;
 use std::ptr;
-use std::sync::{Arc, Mutex, Condvar, Once, ONCE_INIT};
+use std::sync::{Arc, Mutex, Condvar, Once};
+#[allow(deprecated)]
+use std::sync::ONCE_INIT;
 use std::sync::atomic::{AtomicUsize, Ordering};
 
 use {Future, Stream, Sink, Poll, Async, StartSend, AsyncSink};
@@ -32,6 +34,7 @@ pub fn is_in_task() -> bool {
     CURRENT_TASK.with(|task| !task.get().is_null())
 }
 
+#[allow(deprecated)]
 static INIT: Once = ONCE_INIT;
 
 pub fn get_ptr() -> Option<*mut u8> {
diff --git a/third_party/rust/futures-0.1.29/src/task_impl/std/task_rc.rs b/third_party/rust/futures-0.1.31/src/task_impl/std/task_rc.rs
similarity index 100%
rename from third_party/rust/futures-0.1.29/src/task_impl/std/task_rc.rs
rename to third_party/rust/futures-0.1.31/src/task_impl/std/task_rc.rs
diff --git a/third_party/rust/futures-0.1.29/src/task_impl/std/unpark_mutex.rs b/third_party/rust/futures-0.1.31/src/task_impl/std/unpark_mutex.rs
similarity index 100%
rename from third_party/rust/futures-0.1.29/src/task_impl/std/unpark_mutex.rs
rename to third_party/rust/futures-0.1.31/src/task_impl/std/unpark_mutex.rs
diff --git a/third_party/rust/futures-0.1.29/src/unsync/mod.rs b/third_party/rust/futures-0.1.31/src/unsync/mod.rs
similarity index 100%
rename from third_party/rust/futures-0.1.29/src/unsync/mod.rs
rename to third_party/rust/futures-0.1.31/src/unsync/mod.rs
diff --git a/third_party/rust/futures-0.1.29/src/unsync/mpsc.rs b/third_party/rust/futures-0.1.31/src/unsync/mpsc.rs
similarity index 100%
rename from third_party/rust/futures-0.1.29/src/unsync/mpsc.rs
rename to third_party/rust/futures-0.1.31/src/unsync/mpsc.rs
diff --git a/third_party/rust/futures-0.1.29/src/unsync/oneshot.rs b/third_party/rust/futures-0.1.31/src/unsync/oneshot.rs
similarity index 100%
rename from third_party/rust/futures-0.1.29/src/unsync/oneshot.rs
rename to third_party/rust/futures-0.1.31/src/unsync/oneshot.rs
diff --git a/third_party/rust/futures-0.1.29/tests/all.rs b/third_party/rust/futures-0.1.31/tests/all.rs
similarity index 99%
rename from third_party/rust/futures-0.1.29/tests/all.rs
rename to third_party/rust/futures-0.1.31/tests/all.rs
index bdd67315c5cfc88c9167936720a9524e2c922701..40e402f553298de6fde4feae49b811955f7e8456 100644
--- a/third_party/rust/futures-0.1.29/tests/all.rs
+++ b/third_party/rust/futures-0.1.31/tests/all.rs
@@ -1,3 +1,5 @@
+#![allow(bare_trait_objects, unknown_lints)]
+
 extern crate futures;
 
 use std::sync::mpsc::{channel, TryRecvError};
diff --git a/third_party/rust/futures-0.1.29/tests/bilock.rs b/third_party/rust/futures-0.1.31/tests/bilock.rs
similarity index 98%
rename from third_party/rust/futures-0.1.29/tests/bilock.rs
rename to third_party/rust/futures-0.1.31/tests/bilock.rs
index 78d873635a603a1e3c50e4e396d8cd53ee1ac2fc..1658bdae2718e295e4148a4fe0b9646312409400 100644
--- a/third_party/rust/futures-0.1.29/tests/bilock.rs
+++ b/third_party/rust/futures-0.1.31/tests/bilock.rs
@@ -1,3 +1,5 @@
+#![allow(bare_trait_objects, unknown_lints)]
+
 extern crate futures;
 
 use std::thread;
diff --git a/third_party/rust/futures-0.1.29/tests/buffer_unordered.rs b/third_party/rust/futures-0.1.31/tests/buffer_unordered.rs
similarity index 100%
rename from third_party/rust/futures-0.1.29/tests/buffer_unordered.rs
rename to third_party/rust/futures-0.1.31/tests/buffer_unordered.rs
diff --git a/third_party/rust/futures-0.1.29/tests/channel.rs b/third_party/rust/futures-0.1.31/tests/channel.rs
similarity index 97%
rename from third_party/rust/futures-0.1.29/tests/channel.rs
rename to third_party/rust/futures-0.1.31/tests/channel.rs
index e2f11202d0a659127c40eff7f29245fa3d5716d3..7940de45096a7c2ba6f33fc1ffb458fbd1fdd9de 100644
--- a/third_party/rust/futures-0.1.29/tests/channel.rs
+++ b/third_party/rust/futures-0.1.31/tests/channel.rs
@@ -1,3 +1,5 @@
+#![allow(bare_trait_objects, unknown_lints)]
+
 extern crate futures;
 
 use std::sync::atomic::*;
diff --git a/third_party/rust/futures-0.1.29/tests/eager_drop.rs b/third_party/rust/futures-0.1.31/tests/eager_drop.rs
similarity index 100%
rename from third_party/rust/futures-0.1.29/tests/eager_drop.rs
rename to third_party/rust/futures-0.1.31/tests/eager_drop.rs
diff --git a/third_party/rust/futures-0.1.29/tests/eventual.rs b/third_party/rust/futures-0.1.31/tests/eventual.rs
similarity index 100%
rename from third_party/rust/futures-0.1.29/tests/eventual.rs
rename to third_party/rust/futures-0.1.31/tests/eventual.rs
diff --git a/third_party/rust/futures-0.1.29/tests/fuse.rs b/third_party/rust/futures-0.1.31/tests/fuse.rs
similarity index 100%
rename from third_party/rust/futures-0.1.29/tests/fuse.rs
rename to third_party/rust/futures-0.1.31/tests/fuse.rs
diff --git a/third_party/rust/futures-0.1.29/tests/future_flatten_stream.rs b/third_party/rust/futures-0.1.31/tests/future_flatten_stream.rs
similarity index 100%
rename from third_party/rust/futures-0.1.29/tests/future_flatten_stream.rs
rename to third_party/rust/futures-0.1.31/tests/future_flatten_stream.rs
diff --git a/third_party/rust/futures-0.1.29/tests/futures_ordered.rs b/third_party/rust/futures-0.1.31/tests/futures_ordered.rs
similarity index 98%
rename from third_party/rust/futures-0.1.29/tests/futures_ordered.rs
rename to third_party/rust/futures-0.1.31/tests/futures_ordered.rs
index 229a8e58c093462c9d84b9867d1535905bf157fc..6054192e3b8df3f001b966f7fb29c270fdda7bb7 100644
--- a/third_party/rust/futures-0.1.29/tests/futures_ordered.rs
+++ b/third_party/rust/futures-0.1.31/tests/futures_ordered.rs
@@ -1,3 +1,5 @@
+#![allow(bare_trait_objects, unknown_lints)]
+
 extern crate futures;
 
 use std::any::Any;
diff --git a/third_party/rust/futures-0.1.29/tests/futures_unordered.rs b/third_party/rust/futures-0.1.31/tests/futures_unordered.rs
similarity index 74%
rename from third_party/rust/futures-0.1.29/tests/futures_unordered.rs
rename to third_party/rust/futures-0.1.31/tests/futures_unordered.rs
index 9b8c08d01b494eefbc8bf8b95e31443bf08b3338..325a6f3e483c431edc0263ed1c80dc04e71c4194 100644
--- a/third_party/rust/futures-0.1.29/tests/futures_unordered.rs
+++ b/third_party/rust/futures-0.1.31/tests/futures_unordered.rs
@@ -1,9 +1,12 @@
+#![allow(bare_trait_objects, unknown_lints)]
+
 extern crate futures;
 
 use std::any::Any;
 
 use futures::sync::oneshot;
-use futures::stream::futures_unordered;
+use std::iter::FromIterator;
+use futures::stream::{futures_unordered, FuturesUnordered};
 use futures::prelude::*;
 
 mod support;
@@ -125,3 +128,40 @@ fn iter_mut_len() {
     assert_eq!(iter_mut.len(), 0);
     assert!(iter_mut.next().is_none());
 }
+
+#[test]
+fn polled_only_once_at_most_per_iteration() {
+    #[derive(Debug, Clone, Copy, Default)]
+    struct F {
+        polled: bool,
+    }
+
+    impl Future for F {
+        type Item = ();
+        type Error = ();
+
+        fn poll(&mut self) -> Result<Async<Self::Item>, Self::Error> {
+            if self.polled {
+                panic!("polled twice")
+            } else {
+                self.polled = true;
+                Ok(Async::NotReady)
+            }
+        }
+    }
+
+
+    let tasks = FuturesUnordered::from_iter(vec![F::default(); 10]);
+    let mut tasks = futures::executor::spawn(tasks);
+    assert!(tasks.poll_stream_notify(&support::notify_noop(), 0).unwrap().is_not_ready());
+    assert_eq!(10, tasks.get_mut().iter_mut().filter(|f| f.polled).count());
+
+    let tasks = FuturesUnordered::from_iter(vec![F::default(); 33]);
+    let mut tasks = futures::executor::spawn(tasks);
+    assert!(tasks.poll_stream_notify(&support::notify_noop(), 0).unwrap().is_not_ready());
+    assert_eq!(33, tasks.get_mut().iter_mut().filter(|f| f.polled).count());
+
+    let tasks = FuturesUnordered::<F>::new();
+    let mut tasks = futures::executor::spawn(tasks);
+    assert!(tasks.poll_stream_notify(&support::notify_noop(), 0).unwrap().is_ready());
+}
diff --git a/third_party/rust/futures-0.1.29/tests/inspect.rs b/third_party/rust/futures-0.1.31/tests/inspect.rs
similarity index 100%
rename from third_party/rust/futures-0.1.29/tests/inspect.rs
rename to third_party/rust/futures-0.1.31/tests/inspect.rs
diff --git a/third_party/rust/futures-0.1.29/tests/mpsc-close.rs b/third_party/rust/futures-0.1.31/tests/mpsc-close.rs
similarity index 100%
rename from third_party/rust/futures-0.1.29/tests/mpsc-close.rs
rename to third_party/rust/futures-0.1.31/tests/mpsc-close.rs
diff --git a/third_party/rust/futures-0.1.29/tests/mpsc.rs b/third_party/rust/futures-0.1.31/tests/mpsc.rs
similarity index 99%
rename from third_party/rust/futures-0.1.29/tests/mpsc.rs
rename to third_party/rust/futures-0.1.31/tests/mpsc.rs
index faeb614608a561df43abe69c7a02dc32178dc4a5..9cb83e5952821a13f3cc3b366411589f8877f33f 100644
--- a/third_party/rust/futures-0.1.29/tests/mpsc.rs
+++ b/third_party/rust/futures-0.1.31/tests/mpsc.rs
@@ -1,4 +1,5 @@
 #![cfg(feature = "use_std")]
+#![allow(bare_trait_objects, unknown_lints)]
 
 #[macro_use]
 extern crate futures;
diff --git a/third_party/rust/futures-0.1.29/tests/oneshot.rs b/third_party/rust/futures-0.1.31/tests/oneshot.rs
similarity index 100%
rename from third_party/rust/futures-0.1.29/tests/oneshot.rs
rename to third_party/rust/futures-0.1.31/tests/oneshot.rs
diff --git a/third_party/rust/futures-0.1.29/tests/ready_queue.rs b/third_party/rust/futures-0.1.31/tests/ready_queue.rs
similarity index 100%
rename from third_party/rust/futures-0.1.29/tests/ready_queue.rs
rename to third_party/rust/futures-0.1.31/tests/ready_queue.rs
diff --git a/third_party/rust/futures-0.1.29/tests/recurse.rs b/third_party/rust/futures-0.1.31/tests/recurse.rs
similarity index 91%
rename from third_party/rust/futures-0.1.29/tests/recurse.rs
rename to third_party/rust/futures-0.1.31/tests/recurse.rs
index 4eb024ac95446e0e574c3994f103db808cdc04c5..a521ed13b7f18fdcfb932b932a3f9a63d58a602b 100644
--- a/third_party/rust/futures-0.1.29/tests/recurse.rs
+++ b/third_party/rust/futures-0.1.31/tests/recurse.rs
@@ -1,3 +1,5 @@
+#![allow(bare_trait_objects, unknown_lints)]
+
 extern crate futures;
 
 use std::sync::mpsc::channel;
diff --git a/third_party/rust/futures-0.1.29/tests/select_all.rs b/third_party/rust/futures-0.1.31/tests/select_all.rs
similarity index 100%
rename from third_party/rust/futures-0.1.29/tests/select_all.rs
rename to third_party/rust/futures-0.1.31/tests/select_all.rs
diff --git a/third_party/rust/futures-0.1.29/tests/select_ok.rs b/third_party/rust/futures-0.1.31/tests/select_ok.rs
similarity index 100%
rename from third_party/rust/futures-0.1.29/tests/select_ok.rs
rename to third_party/rust/futures-0.1.31/tests/select_ok.rs
diff --git a/third_party/rust/futures-0.1.29/tests/shared.rs b/third_party/rust/futures-0.1.31/tests/shared.rs
similarity index 87%
rename from third_party/rust/futures-0.1.29/tests/shared.rs
rename to third_party/rust/futures-0.1.31/tests/shared.rs
index 99d2b381ea34737c9c7f18977e4e81c8d000e5ac..97989fe2cbf832ce0e0b06a91c4f3a2e17a5155a 100644
--- a/third_party/rust/futures-0.1.29/tests/shared.rs
+++ b/third_party/rust/futures-0.1.31/tests/shared.rs
@@ -1,3 +1,5 @@
+#![allow(bare_trait_objects, unknown_lints)]
+
 extern crate futures;
 
 mod support;
@@ -202,3 +204,33 @@ fn recursive_poll_with_unpark() {
     drop(tx0);
     core.run(f3).unwrap();
 }
+
+#[test]
+fn shared_future_that_wakes_itself_until_pending_is_returned() {
+    use futures::Async;
+    use std::cell::Cell;
+
+    let core = ::support::local_executor::Core::new();
+
+    let proceed = Cell::new(false);
+    let fut = futures::future::poll_fn(|| {
+        Ok::<_, ()>(if proceed.get() {
+            Async::Ready(())
+        } else {
+            futures::task::current().notify();
+            Async::NotReady
+        })
+    })
+    .shared()
+    .map(|_| ())
+    .map_err(|_| ());
+
+    // The join future can only complete if the second future gets a chance to run after the first
+    // has returned pending
+    let second = futures::future::lazy(|| {
+        proceed.set(true);
+        Ok::<_, ()>(())
+    });
+
+    core.run(fut.join(second)).unwrap();
+}
diff --git a/third_party/rust/futures-0.1.29/tests/sink.rs b/third_party/rust/futures-0.1.31/tests/sink.rs
similarity index 99%
rename from third_party/rust/futures-0.1.29/tests/sink.rs
rename to third_party/rust/futures-0.1.31/tests/sink.rs
index c8a34d9e037013cf6caf9e6ef9fca344cc6d9154..460dbdf20c09aeddb0afc3a59e85332b8cf8aa73 100644
--- a/third_party/rust/futures-0.1.29/tests/sink.rs
+++ b/third_party/rust/futures-0.1.31/tests/sink.rs
@@ -1,3 +1,5 @@
+#![allow(bare_trait_objects, unknown_lints)]
+
 extern crate futures;
 
 use std::mem;
@@ -372,7 +374,7 @@ fn fanout_backpressure() {
 
     let sink = StartSendFut::new(sink, 0).wait().unwrap();
     let sink = StartSendFut::new(sink, 1).wait().unwrap();
- 
+
     let flag = Flag::new();
     let mut task = executor::spawn(sink.send(2));
     assert!(!flag.get());
diff --git a/third_party/rust/futures-0.1.29/tests/split.rs b/third_party/rust/futures-0.1.31/tests/split.rs
similarity index 100%
rename from third_party/rust/futures-0.1.29/tests/split.rs
rename to third_party/rust/futures-0.1.31/tests/split.rs
diff --git a/third_party/rust/futures-0.1.29/tests/stream.rs b/third_party/rust/futures-0.1.31/tests/stream.rs
similarity index 99%
rename from third_party/rust/futures-0.1.29/tests/stream.rs
rename to third_party/rust/futures-0.1.31/tests/stream.rs
index eb7560351d0064c0358c388a45ab86a8b608aa97..2400a2abb1fc118cc72b659a5aefcd393df4f4af 100644
--- a/third_party/rust/futures-0.1.29/tests/stream.rs
+++ b/third_party/rust/futures-0.1.31/tests/stream.rs
@@ -1,3 +1,5 @@
+#![allow(bare_trait_objects, unknown_lints)]
+
 #[macro_use]
 extern crate futures;
 
diff --git a/third_party/rust/futures-0.1.29/tests/stream_catch_unwind.rs b/third_party/rust/futures-0.1.31/tests/stream_catch_unwind.rs
similarity index 100%
rename from third_party/rust/futures-0.1.29/tests/stream_catch_unwind.rs
rename to third_party/rust/futures-0.1.31/tests/stream_catch_unwind.rs
diff --git a/third_party/rust/futures-0.1.29/tests/support/local_executor.rs b/third_party/rust/futures-0.1.31/tests/support/local_executor.rs
similarity index 99%
rename from third_party/rust/futures-0.1.29/tests/support/local_executor.rs
rename to third_party/rust/futures-0.1.31/tests/support/local_executor.rs
index 615efc1f703872dfd546f75f7c1a62843e8aace2..cf89e8152fc57db56898380e1b84900de20390ec 100644
--- a/third_party/rust/futures-0.1.29/tests/support/local_executor.rs
+++ b/third_party/rust/futures-0.1.31/tests/support/local_executor.rs
@@ -4,6 +4,8 @@
 //! futures-aware inter-thread communications, and is not intended to be used to
 //! manage I/O. For futures that do I/O you'll likely want to use `tokio-core`.
 
+#![allow(bare_trait_objects, unknown_lints)]
+
 use std::cell::{Cell, RefCell};
 use std::sync::{Arc, Mutex, mpsc};
 
diff --git a/third_party/rust/futures-0.1.29/tests/support/mod.rs b/third_party/rust/futures-0.1.31/tests/support/mod.rs
similarity index 100%
rename from third_party/rust/futures-0.1.29/tests/support/mod.rs
rename to third_party/rust/futures-0.1.31/tests/support/mod.rs
diff --git a/third_party/rust/futures-0.1.29/tests/unfold.rs b/third_party/rust/futures-0.1.31/tests/unfold.rs
similarity index 100%
rename from third_party/rust/futures-0.1.29/tests/unfold.rs
rename to third_party/rust/futures-0.1.31/tests/unfold.rs
diff --git a/third_party/rust/futures-0.1.29/tests/unsync-oneshot.rs b/third_party/rust/futures-0.1.31/tests/unsync-oneshot.rs
similarity index 100%
rename from third_party/rust/futures-0.1.29/tests/unsync-oneshot.rs
rename to third_party/rust/futures-0.1.31/tests/unsync-oneshot.rs
diff --git a/third_party/rust/futures-0.1.29/tests/unsync.rs b/third_party/rust/futures-0.1.31/tests/unsync.rs
similarity index 99%
rename from third_party/rust/futures-0.1.29/tests/unsync.rs
rename to third_party/rust/futures-0.1.31/tests/unsync.rs
index 3d110859809494c91bbeb15cd92e80f22bac2b10..490db0af1cad4beb501127048d0b0efa014559ef 100644
--- a/third_party/rust/futures-0.1.29/tests/unsync.rs
+++ b/third_party/rust/futures-0.1.31/tests/unsync.rs
@@ -1,4 +1,5 @@
 #![cfg(feature = "use_std")]
+#![allow(bare_trait_objects, unknown_lints)]
 
 extern crate futures;
 
diff --git a/third_party/rust/futures-channel/.cargo-checksum.json b/third_party/rust/futures-channel/.cargo-checksum.json
index acd00e5e984ec92c6610d1aa469a298388291925..419c031c160281bfd56ac076a9b52c937053522b 100644
--- a/third_party/rust/futures-channel/.cargo-checksum.json
+++ b/third_party/rust/futures-channel/.cargo-checksum.json
@@ -1 +1 @@
-{"files":{"Cargo.toml":"04e9d086d6111c78e73b0a24dd31cd2424b68b16df61c2725bc7de01bdd953b1","LICENSE-APACHE":"275c491d6d1160553c32fd6127061d7f9606c3ea25abfad6ca3f6ed088785427","LICENSE-MIT":"6652c868f35dfe5e8ef636810a4e576b9d663f3a17fb0f5613ad73583e1b88fd","benches/sync_mpsc.rs":"0df4edf979e0d95fcae41b47aeb9b8663d63fc3d60e53aeb8d4777f117405a3d","src/lib.rs":"4b405d2117065d39a97867220c4105d5b7916920abe2fcc467a5df1596ab55e3","src/lock.rs":"4bd5433db2d750b83420850698e5c62bf102fce8aea310e20e60f75c3532c0a4","src/mpsc/mod.rs":"a6442ce4aab3f228e747f8da06704a66665a2da8abac5c06eb94905c2a86f5f6","src/mpsc/queue.rs":"4079db228bea9d6dd2a3a5ea799d78abb1711e2aed7dcf481fe837002831f812","src/mpsc/sink_impl.rs":"b75fe55e6b935c9132fedcae00b0369b4d988aafe0b7145f12ff4d00a0ace833","src/oneshot.rs":"bb4c8a0386fe0b56c05584290472a84931970b8184269f6cd45251a0764d5df7","tests/channel.rs":"f90bd4996b4cfcc690e8497655d6f755d565b80335d77e7ef034ae4c1b31b25d","tests/mpsc-close.rs":"8cfa1dbec63658d70d02aa828d4d9f69a0bdad3414dec8e2ef8c93bcac9a11cf","tests/mpsc.rs":"cf757feea79b101431ff864d5248b8dc31ef26f067d6234e699f5728e3e60f66","tests/oneshot.rs":"d981e8733eecea7b3d49aa2ba63d579ea4e7ae9cc0b590b2446f7c5b5db9b8e3"},"package":"f2d31b7ec7efab6eefc7c57233bb10b847986139d88cc2f5a02a1ae6871a1846"}
\ No newline at end of file
+{"files":{"Cargo.toml":"f0caeae5e9e7abc9bc31f83bdea2b64d2f9c6e23c1eeb939247635a7c0f2afa0","LICENSE-APACHE":"275c491d6d1160553c32fd6127061d7f9606c3ea25abfad6ca3f6ed088785427","LICENSE-MIT":"6652c868f35dfe5e8ef636810a4e576b9d663f3a17fb0f5613ad73583e1b88fd","benches/sync_mpsc.rs":"1019dd027f104f58883f396ff70efc3dd69b3a7d62df17af090e07b2b05eaf66","build.rs":"eacc35149926db46503723d9f2aab180691571f2ea68b6f6e7b0d1d4d0d7baef","no_atomic_cas.rs":"1b1d0f659624ba744e83a20204f4f5b2b658bb7c934543851c2d569792b4b825","src/lib.rs":"c24b9af1c33e894d6ccefb6b84ef40bd569605334f2f1d89ec1f7f2c6083407d","src/lock.rs":"38655a797456ea4f67d132c42055cf74f18195e875c3b337fc81a12901f79292","src/mpsc/mod.rs":"caada2d24775af02fd3e3f3c2c6febb0731435f84421db2b8360fcc29c1fd34c","src/mpsc/queue.rs":"8822f466e7fe5a8d25ba994b7022ad7c14bcfd473d354a6cd0490240d3e170e7","src/mpsc/sink_impl.rs":"c9977b530187e82c912fcd46e08316e48ed246e77bb2419d53020e69e403d086","src/oneshot.rs":"d1170289b39656ea5f0d5f42b905ddbd5fa9c1202aa3297c9f25280a48229910","tests/channel.rs":"88f4a41d82b5c1b01e153d071a2bf48e0697355908c55ca42342ed45e63fdec8","tests/mpsc-close.rs":"456e43d3b4aad317c84da81297b05743609af57b26d10470e478f1677e4bf731","tests/mpsc.rs":"c929860c11be704692e709c10a3f5e046d6c01df2cacf568983419cdf82aab97","tests/oneshot.rs":"c44b90681c577f8d0c88e810e883328eefec1d4346b9aa615fa47cc3a7c25c01"},"package":"e682a68b29a882df0545c143dc3646daefe80ba479bcdede94d5a703de2871e2"}
\ No newline at end of file
diff --git a/third_party/rust/futures-channel/Cargo.toml b/third_party/rust/futures-channel/Cargo.toml
index 494deb539f03bbf31eb28276d878fc01d3929e4c..ea9abd598850b118f5fd4765d9b14ac285dd974a 100644
--- a/third_party/rust/futures-channel/Cargo.toml
+++ b/third_party/rust/futures-channel/Cargo.toml
@@ -13,7 +13,7 @@
 [package]
 edition = "2018"
 name = "futures-channel"
-version = "0.3.12"
+version = "0.3.15"
 authors = ["Alex Crichton <alex@alexcrichton.com>"]
 description = "Channels for asynchronous communication using futures-rs.\n"
 homepage = "https://rust-lang.github.io/futures-rs"
@@ -24,11 +24,11 @@ repository = "https://github.com/rust-lang/futures-rs"
 all-features = true
 rustdoc-args = ["--cfg", "docsrs"]
 [dependencies.futures-core]
-version = "0.3.12"
+version = "0.3.15"
 default-features = false
 
 [dependencies.futures-sink]
-version = "0.3.12"
+version = "0.3.15"
 optional = true
 default-features = false
 
@@ -36,8 +36,8 @@ default-features = false
 
 [features]
 alloc = ["futures-core/alloc"]
-cfg-target-has-atomic = ["futures-core/cfg-target-has-atomic"]
+cfg-target-has-atomic = []
 default = ["std"]
 sink = ["futures-sink"]
 std = ["alloc", "futures-core/std"]
-unstable = ["futures-core/unstable"]
+unstable = []
diff --git a/third_party/rust/futures-channel/benches/sync_mpsc.rs b/third_party/rust/futures-channel/benches/sync_mpsc.rs
index e22fe60666599c50d9dd5e68b9c56e9affb4431a..7c3c3d3a8039bc56661293cbb90b472b87989c44 100644
--- a/third_party/rust/futures-channel/benches/sync_mpsc.rs
+++ b/third_party/rust/futures-channel/benches/sync_mpsc.rs
@@ -7,8 +7,8 @@ use {
     futures::{
         channel::mpsc::{self, Sender, UnboundedSender},
         ready,
-        stream::{Stream, StreamExt},
         sink::Sink,
+        stream::{Stream, StreamExt},
         task::{Context, Poll},
     },
     futures_test::task::noop_context,
@@ -25,7 +25,6 @@ fn unbounded_1_tx(b: &mut Bencher) {
         // 1000 iterations to avoid measuring overhead of initialization
         // Result should be divided by 1000
         for i in 0..1000 {
-
             // Poll, not ready, park
             assert_eq!(Poll::Pending, rx.poll_next_unpin(&mut cx));
 
@@ -73,7 +72,6 @@ fn unbounded_uncontended(b: &mut Bencher) {
     })
 }
 
-
 /// A Stream that continuously sends incrementing number of the queue
 struct TestSender {
     tx: Sender<u32>,
@@ -84,9 +82,7 @@ struct TestSender {
 impl Stream for TestSender {
     type Item = u32;
 
-    fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>)
-        -> Poll<Option<Self::Item>>
-    {
+    fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
         let this = &mut *self;
         let mut tx = Pin::new(&mut this.tx);
 
@@ -123,12 +119,7 @@ fn bounded_100_tx(b: &mut Bencher) {
         // Each sender can send one item after specified capacity
         let (tx, mut rx) = mpsc::channel(0);
 
-        let mut tx: Vec<_> = (0..100).map(|_| {
-            TestSender {
-                tx: tx.clone(),
-                last: 0
-            }
-        }).collect();
+        let mut tx: Vec<_> = (0..100).map(|_| TestSender { tx: tx.clone(), last: 0 }).collect();
 
         for i in 0..10 {
             for x in &mut tx {
diff --git a/third_party/rust/futures-channel/build.rs b/third_party/rust/futures-channel/build.rs
new file mode 100644
index 0000000000000000000000000000000000000000..c4f341d4806b12c6af8cf1223014f47691ca5013
--- /dev/null
+++ b/third_party/rust/futures-channel/build.rs
@@ -0,0 +1,42 @@
+#![warn(rust_2018_idioms, single_use_lifetimes)]
+
+use std::env;
+
+include!("no_atomic_cas.rs");
+
+// The rustc-cfg listed below are considered public API, but it is *unstable*
+// and outside of the normal semver guarantees:
+//
+// - `futures_no_atomic_cas`
+//      Assume the target does not have atomic CAS (compare-and-swap).
+//      This is usually detected automatically by the build script, but you may
+//      need to enable it manually when building for custom targets or using
+//      non-cargo build systems that don't run the build script.
+//
+// With the exceptions mentioned above, the rustc-cfg strings below are
+// *not* public API. Please let us know by opening a GitHub issue if your build
+// environment requires some way to enable these cfgs other than by executing
+// our build script.
+fn main() {
+    let target = match env::var("TARGET") {
+        Ok(target) => target,
+        Err(e) => {
+            println!(
+                "cargo:warning={}: unable to get TARGET environment variable: {}",
+                env!("CARGO_PKG_NAME"),
+                e
+            );
+            return;
+        }
+    };
+
+    // Note that this is `no_*`, not `has_*`. This allows treating
+    // `cfg(target_has_atomic = "ptr")` as true when the build script doesn't
+    // run. This is needed for compatibility with non-cargo build systems that
+    // don't run the build script.
+    if NO_ATOMIC_CAS_TARGETS.contains(&&*target) {
+        println!("cargo:rustc-cfg=futures_no_atomic_cas");
+    }
+
+    println!("cargo:rerun-if-changed=no_atomic_cas.rs");
+}
diff --git a/third_party/rust/futures-channel/no_atomic_cas.rs b/third_party/rust/futures-channel/no_atomic_cas.rs
new file mode 100644
index 0000000000000000000000000000000000000000..0819af1a45093532034d0042a15a3d460f208d7c
--- /dev/null
+++ b/third_party/rust/futures-channel/no_atomic_cas.rs
@@ -0,0 +1,11 @@
+// This file is @generated by no_atomic_cas.sh.
+// It is not intended for manual editing.
+
+const NO_ATOMIC_CAS_TARGETS: &[&str] = &[
+    "avr-unknown-gnu-atmega328",
+    "msp430-none-elf",
+    "riscv32i-unknown-none-elf",
+    "riscv32imc-unknown-none-elf",
+    "thumbv4t-none-eabi",
+    "thumbv6m-none-eabi",
+];
diff --git a/third_party/rust/futures-channel/src/lib.rs b/third_party/rust/futures-channel/src/lib.rs
index 22d90d8a63a895c213a8f15ce5baf51c0990ed0e..9377a3e2c24c11eae8c5043be28b723018ce748b 100644
--- a/third_party/rust/futures-channel/src/lib.rs
+++ b/third_party/rust/futures-channel/src/lib.rs
@@ -11,22 +11,16 @@
 //! All items are only available when the `std` or `alloc` feature of this
 //! library is activated, and it is activated by default.
 
-#![cfg_attr(feature = "cfg-target-has-atomic", feature(cfg_target_has_atomic))]
-
 #![cfg_attr(not(feature = "std"), no_std)]
-
 #![warn(missing_docs, missing_debug_implementations, rust_2018_idioms, unreachable_pub)]
 // It cannot be included in the published code because this lints have false positives in the minimum required version.
 #![cfg_attr(test, warn(single_use_lifetimes))]
 #![warn(clippy::all)]
 #![doc(test(attr(deny(warnings), allow(dead_code, unused_assignments, unused_variables))))]
 
-#[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");
-
 macro_rules! cfg_target_has_atomic {
     ($($item:item)*) => {$(
-        #[cfg_attr(feature = "cfg-target-has-atomic", cfg(target_has_atomic = "ptr"))]
+        #[cfg(not(futures_no_atomic_cas))]
         $item
     )*};
 }
diff --git a/third_party/rust/futures-channel/src/lock.rs b/third_party/rust/futures-channel/src/lock.rs
index 5eecdd9aa2b3a6e43f24b56190fa6f736f1a90a2..b328d0f7dd9de9aab9937a12902e970c2eafff63 100644
--- a/third_party/rust/futures-channel/src/lock.rs
+++ b/third_party/rust/futures-channel/src/lock.rs
@@ -6,8 +6,8 @@
 
 use core::cell::UnsafeCell;
 use core::ops::{Deref, DerefMut};
-use core::sync::atomic::Ordering::SeqCst;
 use core::sync::atomic::AtomicBool;
+use core::sync::atomic::Ordering::SeqCst;
 
 /// A "mutex" around a value, similar to `std::sync::Mutex<T>`.
 ///
@@ -37,10 +37,7 @@ unsafe impl<T: Send> Sync for Lock<T> {}
 impl<T> Lock<T> {
     /// Creates a new lock around the given value.
     pub(crate) fn new(t: T) -> Self {
-        Self {
-            locked: AtomicBool::new(false),
-            data: UnsafeCell::new(t),
-        }
+        Self { locked: AtomicBool::new(false), data: UnsafeCell::new(t) }
     }
 
     /// Attempts to acquire this lock, returning whether the lock was acquired or
diff --git a/third_party/rust/futures-channel/src/mpsc/mod.rs b/third_party/rust/futures-channel/src/mpsc/mod.rs
index 494c97b2d1d08d623d5b24853a731bb8d8355d46..28612da84d7057095ad232b62e55e3084238e8af 100644
--- a/third_party/rust/futures-channel/src/mpsc/mod.rs
+++ b/third_party/rust/futures-channel/src/mpsc/mod.rs
@@ -79,13 +79,14 @@
 // by the queue structure.
 
 use futures_core::stream::{FusedStream, Stream};
-use futures_core::task::{Context, Poll, Waker};
 use futures_core::task::__internal::AtomicWaker;
+use futures_core::task::{Context, Poll, Waker};
 use std::fmt;
 use std::pin::Pin;
-use std::sync::{Arc, Mutex};
 use std::sync::atomic::AtomicUsize;
 use std::sync::atomic::Ordering::SeqCst;
+use std::sync::{Arc, Mutex};
+use std::thread;
 
 use crate::mpsc::queue::Queue;
 
@@ -208,9 +209,7 @@ impl SendError {
 
 impl<T> fmt::Debug for TrySendError<T> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.debug_struct("TrySendError")
-            .field("kind", &self.err.kind)
-            .finish()
+        f.debug_struct("TrySendError").field("kind", &self.err.kind).finish()
     }
 }
 
@@ -250,8 +249,7 @@ impl<T> TrySendError<T> {
 
 impl fmt::Debug for TryRecvError {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.debug_tuple("TryRecvError")
-            .finish()
+        f.debug_tuple("TryRecvError").finish()
     }
 }
 
@@ -334,10 +332,7 @@ struct SenderTask {
 
 impl SenderTask {
     fn new() -> Self {
-        Self {
-            task: None,
-            is_parked: false,
-        }
+        Self { task: None, is_parked: false }
     }
 
     fn notify(&mut self) {
@@ -380,9 +375,7 @@ pub fn channel<T>(buffer: usize) -> (Sender<T>, Receiver<T>) {
         maybe_parked: false,
     };
 
-    let rx = Receiver {
-        inner: Some(inner),
-    };
+    let rx = Receiver { inner: Some(inner) };
 
     (Sender(Some(tx)), rx)
 }
@@ -398,7 +391,6 @@ pub fn channel<T>(buffer: usize) -> (Sender<T>, Receiver<T>) {
 /// the channel. Using an `unbounded` channel has the ability of causing the
 /// process to run out of memory. In this case, the process will be aborted.
 pub fn unbounded<T>() -> (UnboundedSender<T>, UnboundedReceiver<T>) {
-
     let inner = Arc::new(UnboundedInner {
         state: AtomicUsize::new(INIT_STATE),
         message_queue: Queue::new(),
@@ -406,13 +398,9 @@ pub fn unbounded<T>() -> (UnboundedSender<T>, UnboundedReceiver<T>) {
         recv_task: AtomicWaker::new(),
     });
 
-    let tx = UnboundedSenderInner {
-        inner: inner.clone(),
-    };
+    let tx = UnboundedSenderInner { inner: inner.clone() };
 
-    let rx = UnboundedReceiver {
-        inner: Some(inner),
-    };
+    let rx = UnboundedReceiver { inner: Some(inner) };
 
     (UnboundedSender(Some(tx)), rx)
 }
@@ -429,13 +417,10 @@ impl<T> UnboundedSenderInner<T> {
         if state.is_open {
             Poll::Ready(Ok(()))
         } else {
-            Poll::Ready(Err(SendError {
-                kind: SendErrorKind::Disconnected,
-            }))
+            Poll::Ready(Err(SendError { kind: SendErrorKind::Disconnected }))
         }
     }
 
-
     // Push message to the queue and signal to the receiver
     fn queue_push_and_signal(&self, msg: T) {
         // Push the message onto the message queue
@@ -461,16 +446,17 @@ impl<T> UnboundedSenderInner<T> {
             // This probably is never hit? Odds are the process will run out of
             // memory first. It may be worth to return something else in this
             // case?
-            assert!(state.num_messages < MAX_CAPACITY, "buffer space \
-                    exhausted; sending this messages would overflow the state");
+            assert!(
+                state.num_messages < MAX_CAPACITY,
+                "buffer space \
+                    exhausted; sending this messages would overflow the state"
+            );
 
             state.num_messages += 1;
 
             let next = encode_state(&state);
             match self.inner.state.compare_exchange(curr, next, SeqCst, SeqCst) {
-                Ok(_) => {
-                    return Some(state.num_messages)
-                }
+                Ok(_) => return Some(state.num_messages),
                 Err(actual) => curr = actual,
             }
         }
@@ -515,12 +501,7 @@ impl<T> BoundedSenderInner<T> {
     fn try_send(&mut self, msg: T) -> Result<(), TrySendError<T>> {
         // If the sender is currently blocked, reject the message
         if !self.poll_unparked(None).is_ready() {
-            return Err(TrySendError {
-                err: SendError {
-                    kind: SendErrorKind::Full,
-                },
-                val: msg,
-            });
+            return Err(TrySendError { err: SendError { kind: SendErrorKind::Full }, val: msg });
         }
 
         // The channel has capacity to accept the message, so send it
@@ -530,9 +511,7 @@ impl<T> BoundedSenderInner<T> {
     // Do the send without failing.
     // Can be called only by bounded sender.
     #[allow(clippy::debug_assert_with_mut_call)]
-    fn do_send_b(&mut self, msg: T)
-        -> Result<(), TrySendError<T>>
-    {
+    fn do_send_b(&mut self, msg: T) -> Result<(), TrySendError<T>> {
         // Anyone callig do_send *should* make sure there is room first,
         // but assert here for tests as a sanity check.
         debug_assert!(self.poll_unparked(None).is_ready());
@@ -550,12 +529,12 @@ impl<T> BoundedSenderInner<T> {
                 // the configured buffer size
                 num_messages > self.inner.buffer
             }
-            None => return Err(TrySendError {
-                err: SendError {
-                    kind: SendErrorKind::Disconnected,
-                },
-                val: msg,
-            }),
+            None => {
+                return Err(TrySendError {
+                    err: SendError { kind: SendErrorKind::Disconnected },
+                    val: msg,
+                })
+            }
         };
 
         // If the channel has reached capacity, then the sender task needs to
@@ -599,16 +578,17 @@ impl<T> BoundedSenderInner<T> {
             // This probably is never hit? Odds are the process will run out of
             // memory first. It may be worth to return something else in this
             // case?
-            assert!(state.num_messages < MAX_CAPACITY, "buffer space \
-                    exhausted; sending this messages would overflow the state");
+            assert!(
+                state.num_messages < MAX_CAPACITY,
+                "buffer space \
+                    exhausted; sending this messages would overflow the state"
+            );
 
             state.num_messages += 1;
 
             let next = encode_state(&state);
             match self.inner.state.compare_exchange(curr, next, SeqCst, SeqCst) {
-                Ok(_) => {
-                    return Some(state.num_messages)
-                }
+                Ok(_) => return Some(state.num_messages),
                 Err(actual) => curr = actual,
             }
         }
@@ -643,15 +623,10 @@ impl<T> BoundedSenderInner<T> {
     ///   capacity, in which case the current task is queued to be notified once
     ///   capacity is available;
     /// - `Poll::Ready(Err(SendError))` if the receiver has been dropped.
-    fn poll_ready(
-        &mut self,
-        cx: &mut Context<'_>,
-    ) -> Poll<Result<(), SendError>> {
+    fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), SendError>> {
         let state = decode_state(self.inner.state.load(SeqCst));
         if !state.is_open {
-            return Poll::Ready(Err(SendError {
-                kind: SendErrorKind::Disconnected,
-            }));
+            return Poll::Ready(Err(SendError { kind: SendErrorKind::Disconnected }));
         }
 
         self.poll_unparked(Some(cx)).map(Ok)
@@ -698,7 +673,7 @@ impl<T> BoundedSenderInner<T> {
 
             if !task.is_parked {
                 self.maybe_parked = false;
-                return Poll::Ready(())
+                return Poll::Ready(());
             }
 
             // At this point, an unpark request is pending, so there will be an
@@ -723,12 +698,7 @@ impl<T> Sender<T> {
         if let Some(inner) = &mut self.0 {
             inner.try_send(msg)
         } else {
-            Err(TrySendError {
-                err: SendError {
-                    kind: SendErrorKind::Disconnected,
-                },
-                val: msg,
-            })
+            Err(TrySendError { err: SendError { kind: SendErrorKind::Disconnected }, val: msg })
         }
     }
 
@@ -738,8 +708,7 @@ impl<T> Sender<T> {
     /// [`poll_ready`](Sender::poll_ready) has reported that the channel is
     /// ready to receive a message.
     pub fn start_send(&mut self, msg: T) -> Result<(), SendError> {
-        self.try_send(msg)
-            .map_err(|e| e.err)
+        self.try_send(msg).map_err(|e| e.err)
     }
 
     /// Polls the channel to determine if there is guaranteed capacity to send
@@ -754,13 +723,8 @@ impl<T> Sender<T> {
     ///   capacity, in which case the current task is queued to be notified once
     ///   capacity is available;
     /// - `Poll::Ready(Err(SendError))` if the receiver has been dropped.
-    pub fn poll_ready(
-        &mut self,
-        cx: &mut Context<'_>,
-    ) -> Poll<Result<(), SendError>> {
-        let inner = self.0.as_mut().ok_or(SendError {
-            kind: SendErrorKind::Disconnected,
-        })?;
+    pub fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), SendError>> {
+        let inner = self.0.as_mut().ok_or(SendError { kind: SendErrorKind::Disconnected })?;
         inner.poll_ready(cx)
     }
 
@@ -798,7 +762,10 @@ impl<T> Sender<T> {
     }
 
     /// Hashes the receiver into the provided hasher
-    pub fn hash_receiver<H>(&self, hasher: &mut H) where H: std::hash::Hasher {
+    pub fn hash_receiver<H>(&self, hasher: &mut H)
+    where
+        H: std::hash::Hasher,
+    {
         use std::hash::Hash;
 
         let ptr = self.0.as_ref().map(|inner| inner.ptr());
@@ -808,13 +775,8 @@ impl<T> Sender<T> {
 
 impl<T> UnboundedSender<T> {
     /// Check if the channel is ready to receive a message.
-    pub fn poll_ready(
-        &self,
-        _: &mut Context<'_>,
-    ) -> Poll<Result<(), SendError>> {
-        let inner = self.0.as_ref().ok_or(SendError {
-            kind: SendErrorKind::Disconnected,
-        })?;
+    pub fn poll_ready(&self, _: &mut Context<'_>) -> Poll<Result<(), SendError>> {
+        let inner = self.0.as_ref().ok_or(SendError { kind: SendErrorKind::Disconnected })?;
         inner.poll_ready_nb()
     }
 
@@ -844,12 +806,7 @@ impl<T> UnboundedSender<T> {
             }
         }
 
-        Err(TrySendError {
-            err: SendError {
-                kind: SendErrorKind::Disconnected,
-            },
-            val: msg,
-        })
+        Err(TrySendError { err: SendError { kind: SendErrorKind::Disconnected }, val: msg })
     }
 
     /// Send a message on the channel.
@@ -857,8 +814,7 @@ impl<T> UnboundedSender<T> {
     /// This method should only be called after `poll_ready` has been used to
     /// verify that the channel is ready to receive a message.
     pub fn start_send(&mut self, msg: T) -> Result<(), SendError> {
-        self.do_send_nb(msg)
-            .map_err(|e| e.err)
+        self.do_send_nb(msg).map_err(|e| e.err)
     }
 
     /// Sends a message along this channel.
@@ -887,7 +843,10 @@ impl<T> UnboundedSender<T> {
     }
 
     /// Hashes the receiver into the provided hasher
-    pub fn hash_receiver<H>(&self, hasher: &mut H) where H: std::hash::Hasher {
+    pub fn hash_receiver<H>(&self, hasher: &mut H)
+    where
+        H: std::hash::Hasher,
+    {
         use std::hash::Hash;
 
         let ptr = self.0.as_ref().map(|inner| inner.ptr());
@@ -927,9 +886,7 @@ impl<T> Clone for UnboundedSenderInner<T> {
                 Ok(_) => {
                     // The ABA problem doesn't matter here. We only care that the
                     // number of senders never exceeds the maximum.
-                    return Self {
-                        inner: self.inner.clone(),
-                    };
+                    return Self { inner: self.inner.clone() };
                 }
                 Err(actual) => curr = actual,
             }
@@ -1020,19 +977,22 @@ impl<T> Receiver<T> {
     /// only when you've otherwise arranged to be notified when the channel is
     /// no longer empty.
     ///
-    /// This function will panic if called after `try_next` or `poll_next` has
-    /// returned `None`.
+    /// This function returns:
+    /// * `Ok(Some(t))` when message is fetched
+    /// * `Ok(None)` when channel is closed and no messages left in the queue
+    /// * `Err(e)` when there are no messages available, but channel is not yet closed
     pub fn try_next(&mut self) -> Result<Option<T>, TryRecvError> {
         match self.next_message() {
-            Poll::Ready(msg) => {
-                Ok(msg)
-            },
+            Poll::Ready(msg) => Ok(msg),
             Poll::Pending => Err(TryRecvError { _priv: () }),
         }
     }
 
     fn next_message(&mut self) -> Poll<Option<T>> {
-        let inner = self.inner.as_mut().expect("Receiver::next_message called after `None`");
+        let inner = match self.inner.as_mut() {
+            None => return Poll::Ready(None),
+            Some(inner) => inner,
+        };
         // Pop off a message
         match unsafe { inner.message_queue.pop_spin() } {
             Some(msg) => {
@@ -1047,7 +1007,12 @@ impl<T> Receiver<T> {
             }
             None => {
                 let state = decode_state(inner.state.load(SeqCst));
-                if state.is_open || state.num_messages != 0 {
+                if state.is_closed() {
+                    // If closed flag is set AND there are no pending messages
+                    // it means end of stream
+                    self.inner = None;
+                    Poll::Ready(None)
+                } else {
                     // If queue is open, we need to return Pending
                     // to be woken up when new messages arrive.
                     // If queue is closed but num_messages is non-zero,
@@ -1056,11 +1021,6 @@ impl<T> Receiver<T> {
                     // so we need to park until sender unparks the task
                     // after queueing the message.
                     Poll::Pending
-                } else {
-                    // If closed flag is set AND there are no pending messages
-                    // it means end of stream
-                    self.inner = None;
-                    Poll::Ready(None)
                 }
             }
         }
@@ -1097,18 +1057,15 @@ impl<T> FusedStream for Receiver<T> {
 impl<T> Stream for Receiver<T> {
     type Item = T;
 
-    fn poll_next(
-        mut self: Pin<&mut Self>,
-        cx: &mut Context<'_>,
-    ) -> Poll<Option<T>> {
-            // Try to read a message off of the message queue.
+    fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<T>> {
+        // Try to read a message off of the message queue.
         match self.next_message() {
             Poll::Ready(msg) => {
                 if msg.is_none() {
                     self.inner = None;
                 }
                 Poll::Ready(msg)
-            },
+            }
             Poll::Pending => {
                 // There are no messages to read, in this case, park.
                 self.inner.as_ref().unwrap().recv_task.register(cx.waker());
@@ -1126,8 +1083,26 @@ impl<T> Drop for Receiver<T> {
         // Drain the channel of all pending messages
         self.close();
         if self.inner.is_some() {
-            while let Poll::Ready(Some(..)) = self.next_message() {
-                // ...
+            loop {
+                match self.next_message() {
+                    Poll::Ready(Some(_)) => {}
+                    Poll::Ready(None) => break,
+                    Poll::Pending => {
+                        let state = decode_state(self.inner.as_ref().unwrap().state.load(SeqCst));
+
+                        // If the channel is closed, then there is no need to park.
+                        if state.is_closed() {
+                            break;
+                        }
+
+                        // TODO: Spinning isn't ideal, it might be worth
+                        // investigating using a condvar or some other strategy
+                        // here. That said, if this case is hit, then another thread
+                        // is about to push the value into the queue and this isn't
+                        // the only spinlock in the impl right now.
+                        thread::yield_now();
+                    }
+                }
             }
         }
     }
@@ -1150,19 +1125,22 @@ impl<T> UnboundedReceiver<T> {
     /// only when you've otherwise arranged to be notified when the channel is
     /// no longer empty.
     ///
-    /// This function will panic if called after `try_next` or `poll_next` has
-    /// returned `None`.
+    /// This function returns:
+    /// * `Ok(Some(t))` when message is fetched
+    /// * `Ok(None)` when channel is closed and no messages left in the queue
+    /// * `Err(e)` when there are no messages available, but channel is not yet closed
     pub fn try_next(&mut self) -> Result<Option<T>, TryRecvError> {
         match self.next_message() {
-            Poll::Ready(msg) => {
-                Ok(msg)
-            },
+            Poll::Ready(msg) => Ok(msg),
             Poll::Pending => Err(TryRecvError { _priv: () }),
         }
     }
 
     fn next_message(&mut self) -> Poll<Option<T>> {
-        let inner = self.inner.as_mut().expect("Receiver::next_message called after `None`");
+        let inner = match self.inner.as_mut() {
+            None => return Poll::Ready(None),
+            Some(inner) => inner,
+        };
         // Pop off a message
         match unsafe { inner.message_queue.pop_spin() } {
             Some(msg) => {
@@ -1173,7 +1151,12 @@ impl<T> UnboundedReceiver<T> {
             }
             None => {
                 let state = decode_state(inner.state.load(SeqCst));
-                if state.is_open || state.num_messages != 0 {
+                if state.is_closed() {
+                    // If closed flag is set AND there are no pending messages
+                    // it means end of stream
+                    self.inner = None;
+                    Poll::Ready(None)
+                } else {
                     // If queue is open, we need to return Pending
                     // to be woken up when new messages arrive.
                     // If queue is closed but num_messages is non-zero,
@@ -1182,11 +1165,6 @@ impl<T> UnboundedReceiver<T> {
                     // so we need to park until sender unparks the task
                     // after queueing the message.
                     Poll::Pending
-                } else {
-                    // If closed flag is set AND there are no pending messages
-                    // it means end of stream
-                    self.inner = None;
-                    Poll::Ready(None)
                 }
             }
         }
@@ -1211,10 +1189,7 @@ impl<T> FusedStream for UnboundedReceiver<T> {
 impl<T> Stream for UnboundedReceiver<T> {
     type Item = T;
 
-    fn poll_next(
-        mut self: Pin<&mut Self>,
-        cx: &mut Context<'_>,
-    ) -> Poll<Option<T>> {
+    fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<T>> {
         // Try to read a message off of the message queue.
         match self.next_message() {
             Poll::Ready(msg) => {
@@ -1222,7 +1197,7 @@ impl<T> Stream for UnboundedReceiver<T> {
                     self.inner = None;
                 }
                 Poll::Ready(msg)
-            },
+            }
             Poll::Pending => {
                 // There are no messages to read, in this case, park.
                 self.inner.as_ref().unwrap().recv_task.register(cx.waker());
@@ -1240,8 +1215,26 @@ impl<T> Drop for UnboundedReceiver<T> {
         // Drain the channel of all pending messages
         self.close();
         if self.inner.is_some() {
-            while let Poll::Ready(Some(..)) = self.next_message() {
-                // ...
+            loop {
+                match self.next_message() {
+                    Poll::Ready(Some(_)) => {}
+                    Poll::Ready(None) => break,
+                    Poll::Pending => {
+                        let state = decode_state(self.inner.as_ref().unwrap().state.load(SeqCst));
+
+                        // If the channel is closed, then there is no need to park.
+                        if state.is_closed() {
+                            break;
+                        }
+
+                        // TODO: Spinning isn't ideal, it might be worth
+                        // investigating using a condvar or some other strategy
+                        // here. That said, if this case is hit, then another thread
+                        // is about to push the value into the queue and this isn't
+                        // the only spinlock in the impl right now.
+                        thread::yield_now();
+                    }
+                }
             }
         }
     }
@@ -1289,6 +1282,12 @@ unsafe impl<T: Send> Sync for UnboundedInner<T> {}
 unsafe impl<T: Send> Send for BoundedInner<T> {}
 unsafe impl<T: Send> Sync for BoundedInner<T> {}
 
+impl State {
+    fn is_closed(&self) -> bool {
+        !self.is_open && self.num_messages == 0
+    }
+}
+
 /*
  *
  * ===== Helpers =====
@@ -1296,10 +1295,7 @@ unsafe impl<T: Send> Sync for BoundedInner<T> {}
  */
 
 fn decode_state(num: usize) -> State {
-    State {
-        is_open: num & OPEN_MASK == OPEN_MASK,
-        num_messages: num & MAX_CAPACITY,
-    }
+    State { is_open: num & OPEN_MASK == OPEN_MASK, num_messages: num & MAX_CAPACITY }
 }
 
 fn encode_state(state: &State) -> usize {
diff --git a/third_party/rust/futures-channel/src/mpsc/queue.rs b/third_party/rust/futures-channel/src/mpsc/queue.rs
index b00e1b17555e67d0708d9d55f845ee132b7e1833..57dc7f5654d70a38a86e3fe2a69cd67e8d57d128 100644
--- a/third_party/rust/futures-channel/src/mpsc/queue.rs
+++ b/third_party/rust/futures-channel/src/mpsc/queue.rs
@@ -43,10 +43,10 @@
 
 pub(super) use self::PopResult::*;
 
-use std::thread;
 use std::cell::UnsafeCell;
 use std::ptr;
 use std::sync::atomic::{AtomicPtr, Ordering};
+use std::thread;
 
 /// A result of the `pop` function.
 pub(super) enum PopResult<T> {
@@ -76,15 +76,12 @@ pub(super) struct Queue<T> {
     tail: UnsafeCell<*mut Node<T>>,
 }
 
-unsafe impl<T: Send> Send for Queue<T> { }
-unsafe impl<T: Send> Sync for Queue<T> { }
+unsafe impl<T: Send> Send for Queue<T> {}
+unsafe impl<T: Send> Sync for Queue<T> {}
 
 impl<T> Node<T> {
     unsafe fn new(v: Option<T>) -> *mut Self {
-        Box::into_raw(Box::new(Self {
-            next: AtomicPtr::new(ptr::null_mut()),
-            value: v,
-        }))
+        Box::into_raw(Box::new(Self { next: AtomicPtr::new(ptr::null_mut()), value: v }))
     }
 }
 
@@ -93,10 +90,7 @@ impl<T> Queue<T> {
     /// one consumer.
     pub(super) fn new() -> Self {
         let stub = unsafe { Node::new(None) };
-        Self {
-            head: AtomicPtr::new(stub),
-            tail: UnsafeCell::new(stub),
-        }
+        Self { head: AtomicPtr::new(stub), tail: UnsafeCell::new(stub) }
     }
 
     /// Pushes a new value onto this queue.
@@ -133,7 +127,11 @@ impl<T> Queue<T> {
             return Data(ret);
         }
 
-        if self.head.load(Ordering::Acquire) == tail {Empty} else {Inconsistent}
+        if self.head.load(Ordering::Acquire) == tail {
+            Empty
+        } else {
+            Inconsistent
+        }
     }
 
     /// Pop an element similarly to `pop` function, but spin-wait on inconsistent
diff --git a/third_party/rust/futures-channel/src/mpsc/sink_impl.rs b/third_party/rust/futures-channel/src/mpsc/sink_impl.rs
index 4ce66b4e59087b468eb0a3402dfd21422392ec4b..1be20162c2ef1ce5f00f0646d27c73020937be25 100644
--- a/third_party/rust/futures-channel/src/mpsc/sink_impl.rs
+++ b/third_party/rust/futures-channel/src/mpsc/sink_impl.rs
@@ -6,24 +6,15 @@ use std::pin::Pin;
 impl<T> Sink<T> for Sender<T> {
     type Error = SendError;
 
-    fn poll_ready(
-        mut self: Pin<&mut Self>,
-        cx: &mut Context<'_>,
-    ) -> Poll<Result<(), Self::Error>> {
+    fn poll_ready(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
         (*self).poll_ready(cx)
     }
 
-    fn start_send(
-        mut self: Pin<&mut Self>,
-        msg: T,
-    ) -> Result<(), Self::Error> {
+    fn start_send(mut self: Pin<&mut Self>, msg: T) -> Result<(), Self::Error> {
         (*self).start_send(msg)
     }
 
-    fn poll_flush(
-        mut self: Pin<&mut Self>,
-        cx: &mut Context<'_>,
-    ) -> Poll<Result<(), Self::Error>> {
+    fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
         match (*self).poll_ready(cx) {
             Poll::Ready(Err(ref e)) if e.is_disconnected() => {
                 // If the receiver disconnected, we consider the sink to be flushed.
@@ -33,10 +24,7 @@ impl<T> Sink<T> for Sender<T> {
         }
     }
 
-    fn poll_close(
-        mut self: Pin<&mut Self>,
-        _: &mut Context<'_>,
-    ) -> Poll<Result<(), Self::Error>> {
+    fn poll_close(mut self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
         self.disconnect();
         Poll::Ready(Ok(()))
     }
@@ -45,31 +33,19 @@ impl<T> Sink<T> for Sender<T> {
 impl<T> Sink<T> for UnboundedSender<T> {
     type Error = SendError;
 
-    fn poll_ready(
-        self: Pin<&mut Self>,
-        cx: &mut Context<'_>,
-    ) -> Poll<Result<(), Self::Error>> {
+    fn poll_ready(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
         Self::poll_ready(&*self, cx)
     }
 
-    fn start_send(
-        mut self: Pin<&mut Self>,
-        msg: T,
-    ) -> Result<(), Self::Error> {
+    fn start_send(mut self: Pin<&mut Self>, msg: T) -> Result<(), Self::Error> {
         Self::start_send(&mut *self, msg)
     }
 
-    fn poll_flush(
-        self: Pin<&mut Self>,
-        _: &mut Context<'_>,
-    ) -> Poll<Result<(), Self::Error>> {
+    fn poll_flush(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
         Poll::Ready(Ok(()))
     }
 
-    fn poll_close(
-        mut self: Pin<&mut Self>,
-        _: &mut Context<'_>,
-    ) -> Poll<Result<(), Self::Error>> {
+    fn poll_close(mut self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
         self.disconnect();
         Poll::Ready(Ok(()))
     }
@@ -78,29 +54,19 @@ impl<T> Sink<T> for UnboundedSender<T> {
 impl<T> Sink<T> for &UnboundedSender<T> {
     type Error = SendError;
 
-    fn poll_ready(
-        self: Pin<&mut Self>,
-        cx: &mut Context<'_>,
-    ) -> Poll<Result<(), Self::Error>> {
+    fn poll_ready(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
         UnboundedSender::poll_ready(*self, cx)
     }
 
     fn start_send(self: Pin<&mut Self>, msg: T) -> Result<(), Self::Error> {
-        self.unbounded_send(msg)
-            .map_err(TrySendError::into_send_error)
+        self.unbounded_send(msg).map_err(TrySendError::into_send_error)
     }
 
-    fn poll_flush(
-        self: Pin<&mut Self>,
-        _: &mut Context<'_>,
-    ) -> Poll<Result<(), Self::Error>> {
+    fn poll_flush(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
         Poll::Ready(Ok(()))
     }
 
-    fn poll_close(
-        self: Pin<&mut Self>,
-        _: &mut Context<'_>,
-    ) -> Poll<Result<(), Self::Error>> {
+    fn poll_close(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
         self.close_channel();
         Poll::Ready(Ok(()))
     }
diff --git a/third_party/rust/futures-channel/src/oneshot.rs b/third_party/rust/futures-channel/src/oneshot.rs
index dbbce8112b1ba4d57078926b7d2df82a9aba16c5..5af651b913b5d33f539d03cfd155c326a1a12efa 100644
--- a/third_party/rust/futures-channel/src/oneshot.rs
+++ b/third_party/rust/futures-channel/src/oneshot.rs
@@ -7,7 +7,7 @@ use core::fmt;
 use core::pin::Pin;
 use core::sync::atomic::AtomicBool;
 use core::sync::atomic::Ordering::SeqCst;
-use futures_core::future::{Future, FusedFuture};
+use futures_core::future::{FusedFuture, Future};
 use futures_core::task::{Context, Poll, Waker};
 
 use crate::lock::Lock;
@@ -16,7 +16,6 @@ use crate::lock::Lock;
 ///
 /// This is created by the [`channel`](channel) function.
 #[must_use = "futures do nothing unless you `.await` or poll them"]
-#[derive(Debug)]
 pub struct Receiver<T> {
     inner: Arc<Inner<T>>,
 }
@@ -24,7 +23,6 @@ pub struct Receiver<T> {
 /// A means of transmitting a single value to another task.
 ///
 /// This is created by the [`channel`](channel) function.
-#[derive(Debug)]
 pub struct Sender<T> {
     inner: Arc<Inner<T>>,
 }
@@ -35,7 +33,6 @@ impl<T> Unpin for Sender<T> {}
 
 /// Internal state of the `Receiver`/`Sender` pair above. This is all used as
 /// the internal synchronization between the two for send/recv operations.
-#[derive(Debug)]
 struct Inner<T> {
     /// Indicates whether this oneshot is complete yet. This is filled in both
     /// by `Sender::drop` and by `Receiver::drop`, and both sides interpret it
@@ -106,12 +103,8 @@ struct Inner<T> {
 /// ```
 pub fn channel<T>() -> (Sender<T>, Receiver<T>) {
     let inner = Arc::new(Inner::new());
-    let receiver = Receiver {
-        inner: inner.clone(),
-    };
-    let sender = Sender {
-        inner,
-    };
+    let receiver = Receiver { inner: inner.clone() };
+    let sender = Sender { inner };
     (sender, receiver)
 }
 
@@ -127,7 +120,7 @@ impl<T> Inner<T> {
 
     fn send(&self, t: T) -> Result<(), T> {
         if self.complete.load(SeqCst) {
-            return Err(t)
+            return Err(t);
         }
 
         // Note that this lock acquisition may fail if the receiver
@@ -164,7 +157,7 @@ impl<T> Inner<T> {
         // destructor, but our destructor hasn't run yet so if it's set then the
         // oneshot is gone.
         if self.complete.load(SeqCst) {
-            return Poll::Ready(())
+            return Poll::Ready(());
         }
 
         // If our other half is not gone then we need to park our current task
@@ -273,7 +266,10 @@ impl<T> Inner<T> {
         } else {
             let task = cx.waker().clone();
             match self.rx_task.try_lock() {
-                Some(mut slot) => { *slot = Some(task); false },
+                Some(mut slot) => {
+                    *slot = Some(task);
+                    false
+                }
                 None => true,
             }
         };
@@ -394,6 +390,12 @@ impl<T> Drop for Sender<T> {
     }
 }
 
+impl<T: fmt::Debug> fmt::Debug for Sender<T> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        f.debug_struct("Sender").field("complete", &self.inner.complete).finish()
+    }
+}
+
 /// A future that resolves when the receiving end of a channel has hung up.
 ///
 /// This is an `.await`-friendly interface around [`poll_canceled`](Sender::poll_canceled).
@@ -453,10 +455,7 @@ impl<T> Receiver<T> {
 impl<T> Future for Receiver<T> {
     type Output = Result<T, Canceled>;
 
-    fn poll(
-        self: Pin<&mut Self>,
-        cx: &mut Context<'_>,
-    ) -> Poll<Result<T, Canceled>> {
+    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<T, Canceled>> {
         self.inner.recv(cx)
     }
 }
@@ -481,3 +480,9 @@ impl<T> Drop for Receiver<T> {
         self.inner.drop_rx()
     }
 }
+
+impl<T: fmt::Debug> fmt::Debug for Receiver<T> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        f.debug_struct("Receiver").field("complete", &self.inner.complete).finish()
+    }
+}
diff --git a/third_party/rust/futures-channel/tests/channel.rs b/third_party/rust/futures-channel/tests/channel.rs
index 73dac645b1b37c1b4f764b217344ef831ce9e237..5f01a8ef4c1ca1c6494ca7aeeaf290843c336070 100644
--- a/third_party/rust/futures-channel/tests/channel.rs
+++ b/third_party/rust/futures-channel/tests/channel.rs
@@ -1,8 +1,8 @@
 use futures::channel::mpsc;
 use futures::executor::block_on;
 use futures::future::poll_fn;
-use futures::stream::StreamExt;
 use futures::sink::SinkExt;
+use futures::stream::StreamExt;
 use std::sync::atomic::{AtomicUsize, Ordering};
 use std::thread;
 
@@ -11,9 +11,7 @@ fn sequence() {
     let (tx, rx) = mpsc::channel(1);
 
     let amt = 20;
-    let t = thread::spawn(move || {
-        block_on(send_sequence(amt, tx))
-    });
+    let t = thread::spawn(move || block_on(send_sequence(amt, tx)));
     let list: Vec<_> = block_on(rx.collect());
     let mut list = list.into_iter();
     for i in (1..=amt).rev() {
@@ -34,9 +32,7 @@ async fn send_sequence(n: u32, mut sender: mpsc::Sender<u32>) {
 fn drop_sender() {
     let (tx, mut rx) = mpsc::channel::<u32>(1);
     drop(tx);
-    let f = poll_fn(|cx| {
-        rx.poll_next_unpin(cx)
-    });
+    let f = poll_fn(|cx| rx.poll_next_unpin(cx));
     assert_eq!(block_on(f), None)
 }
 
diff --git a/third_party/rust/futures-channel/tests/mpsc-close.rs b/third_party/rust/futures-channel/tests/mpsc-close.rs
index 50852eb71d7943a5724d2c3f7b5eeff93d60bbed..81203d33483edaa125577c1db2a4cfcb15c7e801 100644
--- a/third_party/rust/futures-channel/tests/mpsc-close.rs
+++ b/third_party/rust/futures-channel/tests/mpsc-close.rs
@@ -1,17 +1,19 @@
 use futures::channel::mpsc;
 use futures::executor::block_on;
+use futures::future::Future;
 use futures::sink::SinkExt;
 use futures::stream::StreamExt;
-use std::sync::Arc;
+use futures::task::{Context, Poll};
+use std::pin::Pin;
+use std::sync::{Arc, Weak};
 use std::thread;
+use std::time::{Duration, Instant};
 
 #[test]
 fn smoke() {
     let (mut sender, receiver) = mpsc::channel(1);
 
-    let t = thread::spawn(move || {
-        while let Ok(()) = block_on(sender.send(42)) {}
-    });
+    let t = thread::spawn(move || while let Ok(()) = block_on(sender.send(42)) {});
 
     // `receiver` needs to be dropped for `sender` to stop sending and therefore before the join.
     block_on(receiver.take(3).for_each(|_| futures::future::ready(())));
@@ -142,3 +144,155 @@ fn single_receiver_drop_closes_channel_and_drains() {
         assert!(sender.is_closed());
     }
 }
+
+// Stress test that `try_send()`s occurring concurrently with receiver
+// close/drops don't appear as successful sends.
+#[test]
+fn stress_try_send_as_receiver_closes() {
+    const AMT: usize = 10000;
+    // To provide variable timing characteristics (in the hopes of
+    // reproducing the collision that leads to a race), we busy-re-poll
+    // the test MPSC receiver a variable number of times before actually
+    // stopping.  We vary this countdown between 1 and the following
+    // value.
+    const MAX_COUNTDOWN: usize = 20;
+    // When we detect that a successfully sent item is still in the
+    // queue after a disconnect, we spin for up to 100ms to confirm that
+    // it is a persistent condition and not a concurrency illusion.
+    const SPIN_TIMEOUT_S: u64 = 10;
+    const SPIN_SLEEP_MS: u64 = 10;
+    struct TestRx {
+        rx: mpsc::Receiver<Arc<()>>,
+        // The number of times to query `rx` before dropping it.
+        poll_count: usize,
+    }
+    struct TestTask {
+        command_rx: mpsc::Receiver<TestRx>,
+        test_rx: Option<mpsc::Receiver<Arc<()>>>,
+        countdown: usize,
+    }
+    impl TestTask {
+        /// Create a new TestTask
+        fn new() -> (TestTask, mpsc::Sender<TestRx>) {
+            let (command_tx, command_rx) = mpsc::channel::<TestRx>(0);
+            (
+                TestTask {
+                    command_rx,
+                    test_rx: None,
+                    countdown: 0, // 0 means no countdown is in progress.
+                },
+                command_tx,
+            )
+        }
+    }
+    impl Future for TestTask {
+        type Output = ();
+
+        fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
+            // Poll the test channel, if one is present.
+            if let Some(rx) = &mut self.test_rx {
+                if let Poll::Ready(v) = rx.poll_next_unpin(cx) {
+                    let _ = v.expect("test finished unexpectedly!");
+                }
+                self.countdown -= 1;
+                // Busy-poll until the countdown is finished.
+                cx.waker().wake_by_ref();
+            }
+            // Accept any newly submitted MPSC channels for testing.
+            match self.command_rx.poll_next_unpin(cx) {
+                Poll::Ready(Some(TestRx { rx, poll_count })) => {
+                    self.test_rx = Some(rx);
+                    self.countdown = poll_count;
+                    cx.waker().wake_by_ref();
+                }
+                Poll::Ready(None) => return Poll::Ready(()),
+                Poll::Pending => {}
+            }
+            if self.countdown == 0 {
+                // Countdown complete -- drop the Receiver.
+                self.test_rx = None;
+            }
+            Poll::Pending
+        }
+    }
+    let (f, mut cmd_tx) = TestTask::new();
+    let bg = thread::spawn(move || block_on(f));
+    for i in 0..AMT {
+        let (mut test_tx, rx) = mpsc::channel(0);
+        let poll_count = i % MAX_COUNTDOWN;
+        cmd_tx.try_send(TestRx { rx, poll_count }).unwrap();
+        let mut prev_weak: Option<Weak<()>> = None;
+        let mut attempted_sends = 0;
+        let mut successful_sends = 0;
+        loop {
+            // Create a test item.
+            let item = Arc::new(());
+            let weak = Arc::downgrade(&item);
+            match test_tx.try_send(item) {
+                Ok(_) => {
+                    prev_weak = Some(weak);
+                    successful_sends += 1;
+                }
+                Err(ref e) if e.is_full() => {}
+                Err(ref e) if e.is_disconnected() => {
+                    // Test for evidence of the race condition.
+                    if let Some(prev_weak) = prev_weak {
+                        if prev_weak.upgrade().is_some() {
+                            // The previously sent item is still allocated.
+                            // However, there appears to be some aspect of the
+                            // concurrency that can legitimately cause the Arc
+                            // to be momentarily valid.  Spin for up to 100ms
+                            // waiting for the previously sent item to be
+                            // dropped.
+                            let t0 = Instant::now();
+                            let mut spins = 0;
+                            loop {
+                                if prev_weak.upgrade().is_none() {
+                                    break;
+                                }
+                                assert!(
+                                    t0.elapsed() < Duration::from_secs(SPIN_TIMEOUT_S),
+                                    "item not dropped on iteration {} after \
+                                     {} sends ({} successful). spin=({})",
+                                    i,
+                                    attempted_sends,
+                                    successful_sends,
+                                    spins
+                                );
+                                spins += 1;
+                                thread::sleep(Duration::from_millis(SPIN_SLEEP_MS));
+                            }
+                        }
+                    }
+                    break;
+                }
+                Err(ref e) => panic!("unexpected error: {}", e),
+            }
+            attempted_sends += 1;
+        }
+    }
+    drop(cmd_tx);
+    bg.join().expect("background thread join");
+}
+
+#[test]
+fn unbounded_try_next_after_none() {
+    let (tx, mut rx) = mpsc::unbounded::<String>();
+    // Drop the sender, close the channel.
+    drop(tx);
+    // Receive the end of channel.
+    assert_eq!(Ok(None), rx.try_next().map_err(|_| ()));
+    // None received, check we can call `try_next` again.
+    assert_eq!(Ok(None), rx.try_next().map_err(|_| ()));
+}
+
+#[test]
+fn bounded_try_next_after_none() {
+    let (tx, mut rx) = mpsc::channel::<String>(17);
+    // Drop the sender, close the channel.
+    drop(tx);
+    // Receive the end of channel.
+    assert_eq!(Ok(None), rx.try_next().map_err(|_| ()));
+    // None received, check we can call `try_next` again.
+    assert_eq!(Ok(None), rx.try_next().map_err(|_| ()));
+}
diff --git a/third_party/rust/futures-channel/tests/mpsc.rs b/third_party/rust/futures-channel/tests/mpsc.rs
index 61c5a5024681aaf5d2e442cdfd67ebe8f90aa478..88cdef13d672187c51d7cb8314d6093bef3ba50e 100644
--- a/third_party/rust/futures-channel/tests/mpsc.rs
+++ b/third_party/rust/futures-channel/tests/mpsc.rs
@@ -1,13 +1,13 @@
 use futures::channel::{mpsc, oneshot};
 use futures::executor::{block_on, block_on_stream};
-use futures::future::{FutureExt, poll_fn};
-use futures::stream::{Stream, StreamExt};
+use futures::future::{poll_fn, FutureExt};
+use futures::pin_mut;
 use futures::sink::{Sink, SinkExt};
+use futures::stream::{Stream, StreamExt};
 use futures::task::{Context, Poll};
-use futures::pin_mut;
 use futures_test::task::{new_count_waker, noop_context};
-use std::sync::{Arc, Mutex};
 use std::sync::atomic::{AtomicUsize, Ordering};
+use std::sync::{Arc, Mutex};
 use std::thread;
 
 trait AssertSend: Send {}
@@ -77,7 +77,7 @@ fn send_shared_recv() {
 fn send_recv_threads() {
     let (mut tx, rx) = mpsc::channel::<i32>(16);
 
-    let t = thread::spawn(move|| {
+    let t = thread::spawn(move || {
         block_on(tx.send(1)).unwrap();
     });
 
@@ -204,7 +204,7 @@ fn stress_shared_unbounded() {
     const NTHREADS: u32 = 8;
     let (tx, rx) = mpsc::unbounded::<i32>();
 
-    let t = thread::spawn(move|| {
+    let t = thread::spawn(move || {
         let result: Vec<_> = block_on(rx.collect());
         assert_eq!(result.len(), (AMT * NTHREADS) as usize);
         for item in result {
@@ -215,7 +215,7 @@ fn stress_shared_unbounded() {
     for _ in 0..NTHREADS {
         let tx = tx.clone();
 
-        thread::spawn(move|| {
+        thread::spawn(move || {
             for _ in 0..AMT {
                 tx.unbounded_send(1).unwrap();
             }
@@ -233,7 +233,7 @@ fn stress_shared_bounded_hard() {
     const NTHREADS: u32 = 8;
     let (tx, rx) = mpsc::channel::<i32>(0);
 
-    let t = thread::spawn(move|| {
+    let t = thread::spawn(move || {
         let result: Vec<_> = block_on(rx.collect());
         assert_eq!(result.len(), (AMT * NTHREADS) as usize);
         for item in result {
@@ -297,9 +297,9 @@ fn stress_receiver_multi_task_bounded_hard() {
                             }
                             Poll::Ready(None) => {
                                 *rx_opt = None;
-                                break
-                            },
-                            Poll::Pending => {},
+                                break;
+                            }
+                            Poll::Pending => {}
                         }
                     }
                 } else {
@@ -311,7 +311,6 @@ fn stress_receiver_multi_task_bounded_hard() {
         th.push(t);
     }
 
-
     for i in 0..AMT {
         block_on(tx.send(i)).unwrap();
     }
@@ -328,7 +327,7 @@ fn stress_receiver_multi_task_bounded_hard() {
 /// after sender dropped.
 #[test]
 fn stress_drop_sender() {
-    fn list() -> impl Stream<Item=i32> {
+    fn list() -> impl Stream<Item = i32> {
         let (tx, rx) = mpsc::channel(1);
         thread::spawn(move || {
             block_on(send_one_two_three(tx));
@@ -407,9 +406,7 @@ fn stress_poll_ready() {
         let mut threads = Vec::new();
         for _ in 0..NTHREADS {
             let sender = tx.clone();
-            threads.push(thread::spawn(move || {
-                block_on(stress_poll_ready_sender(sender, AMT))
-            }));
+            threads.push(thread::spawn(move || block_on(stress_poll_ready_sender(sender, AMT))));
         }
         drop(tx);
 
@@ -436,7 +433,7 @@ fn try_send_1() {
         for i in 0..N {
             loop {
                 if tx.try_send(i).is_ok() {
-                    break
+                    break;
                 }
             }
         }
@@ -542,8 +539,8 @@ fn is_connected_to() {
 
 #[test]
 fn hash_receiver() {
-    use std::hash::Hasher;
     use std::collections::hash_map::DefaultHasher;
+    use std::hash::Hasher;
 
     let mut hasher_a1 = DefaultHasher::new();
     let mut hasher_a2 = DefaultHasher::new();
diff --git a/third_party/rust/futures-channel/tests/oneshot.rs b/third_party/rust/futures-channel/tests/oneshot.rs
index a22d039e4023cc01d8d12b6397742552ee08da4e..979cd8a15a674bab3c8386dc50b5d6ad5da9deff 100644
--- a/third_party/rust/futures-channel/tests/oneshot.rs
+++ b/third_party/rust/futures-channel/tests/oneshot.rs
@@ -1,6 +1,6 @@
 use futures::channel::oneshot::{self, Sender};
 use futures::executor::block_on;
-use futures::future::{FutureExt, poll_fn};
+use futures::future::{poll_fn, FutureExt};
 use futures::task::{Context, Poll};
 use futures_test::task::panic_waker_ref;
 use std::sync::mpsc;
@@ -70,7 +70,7 @@ fn close() {
     rx.close();
     block_on(poll_fn(|cx| {
         match rx.poll_unpin(cx) {
-            Poll::Ready(Err(_)) => {},
+            Poll::Ready(Err(_)) => {}
             _ => panic!(),
         };
         assert!(tx.poll_canceled(cx).is_ready());
diff --git a/third_party/rust/futures-core/.cargo-checksum.json b/third_party/rust/futures-core/.cargo-checksum.json
index 90342386502c6d3595c28176518dfc3340c39be4..e6ad45d20a560772000b812258763916b482f130 100644
--- a/third_party/rust/futures-core/.cargo-checksum.json
+++ b/third_party/rust/futures-core/.cargo-checksum.json
@@ -1 +1 @@
-{"files":{"Cargo.toml":"c44c003671b907c1582b6d3658beb348a2a1b5d62f65b889ba15236f486f473d","LICENSE-APACHE":"275c491d6d1160553c32fd6127061d7f9606c3ea25abfad6ca3f6ed088785427","LICENSE-MIT":"6652c868f35dfe5e8ef636810a4e576b9d663f3a17fb0f5613ad73583e1b88fd","src/future.rs":"6888856ecb09746b3610eb0818309c318ed3475021bdd4274691dc40803136af","src/lib.rs":"97990a26be132054507c9afc538ac01f7fcae0283c2bafb7574f49ce23359d86","src/stream.rs":"ae0c90b45e44c0690824d84be19927d4f8e950835ff9e7586dae4f0cf6102b36","src/task/__internal/atomic_waker.rs":"cc22cf315a639bdf469538c47128113295195dba86ee325f8b017f2bf3f04a20","src/task/__internal/mod.rs":"c9dc3f5f75274b1c682f62f3cf04d2c1755aceefffd9f4bfdad59d8cbb4c4768","src/task/mod.rs":"4afe3c116b928afe49b4a445baa16c3816867e057f91bb0ed3b26ddf3b6b4487","src/task/poll.rs":"da03409f230c63f5226402217007d853116a9d6bf0e35572e60005acb032b6ef"},"package":"79e5145dde8da7d1b3892dad07a9c98fc04bc39892b1ecc9692cf53e2b780a65"}
\ No newline at end of file
+{"files":{"Cargo.toml":"ad61516d2e5efb15d8dba555634cf1b6f15ecd1c7511e34830d301472f48caf9","LICENSE-APACHE":"275c491d6d1160553c32fd6127061d7f9606c3ea25abfad6ca3f6ed088785427","LICENSE-MIT":"6652c868f35dfe5e8ef636810a4e576b9d663f3a17fb0f5613ad73583e1b88fd","build.rs":"eacc35149926db46503723d9f2aab180691571f2ea68b6f6e7b0d1d4d0d7baef","no_atomic_cas.rs":"1b1d0f659624ba744e83a20204f4f5b2b658bb7c934543851c2d569792b4b825","src/future.rs":"0cb559fad0d43566dab959e929c4631c25cf749e2e29a5444fbcad464c9262ae","src/lib.rs":"98df99dc9f8401655bb44ee123c73f2cbca6e7f6963faf07b8ffff304e356fda","src/stream.rs":"f1c7ab84161c5d5b424655b257fc3183eb6f2ed5324ba4006a70f9a4b0dc8872","src/task/__internal/atomic_waker.rs":"4ca94b25d3bcf4db863f008224cc4797dbbe7c93495a1abb232048846694a716","src/task/__internal/mod.rs":"7d0d297f58987b05ffa152605feb78ddc9b6e5168e7d621ec36dfbee558e4bec","src/task/mod.rs":"e213602a2fe5ae78ad5f1ca20e6d32dcbab17aba5b6b072fb927a72da99b4a11","src/task/poll.rs":"7021960bdee64dc3fd8aab4fb49006a34f4ba841701da5610d23756620d79f9b"},"package":"0402f765d8a89a26043b889b26ce3c4679d268fa6bb22cd7c6aad98340e179d1"}
\ No newline at end of file
diff --git a/third_party/rust/futures-core/Cargo.toml b/third_party/rust/futures-core/Cargo.toml
index 663ad8a9fdde19cc581245b83b2dd74a226f9e95..6c480c43af6e40dafe620e33c8d8b6917be24e23 100644
--- a/third_party/rust/futures-core/Cargo.toml
+++ b/third_party/rust/futures-core/Cargo.toml
@@ -13,7 +13,7 @@
 [package]
 edition = "2018"
 name = "futures-core"
-version = "0.3.12"
+version = "0.3.15"
 authors = ["Alex Crichton <alex@alexcrichton.com>"]
 description = "The core traits and types in for the `futures` library.\n"
 homepage = "https://rust-lang.github.io/futures-rs"
diff --git a/third_party/rust/futures-core/build.rs b/third_party/rust/futures-core/build.rs
new file mode 100644
index 0000000000000000000000000000000000000000..c4f341d4806b12c6af8cf1223014f47691ca5013
--- /dev/null
+++ b/third_party/rust/futures-core/build.rs
@@ -0,0 +1,42 @@
+#![warn(rust_2018_idioms, single_use_lifetimes)]
+
+use std::env;
+
+include!("no_atomic_cas.rs");
+
+// The rustc-cfg listed below are considered public API, but it is *unstable*
+// and outside of the normal semver guarantees:
+//
+// - `futures_no_atomic_cas`
+//      Assume the target does not have atomic CAS (compare-and-swap).
+//      This is usually detected automatically by the build script, but you may
+//      need to enable it manually when building for custom targets or using
+//      non-cargo build systems that don't run the build script.
+//
+// With the exceptions mentioned above, the rustc-cfg strings below are
+// *not* public API. Please let us know by opening a GitHub issue if your build
+// environment requires some way to enable these cfgs other than by executing
+// our build script.
+fn main() {
+    let target = match env::var("TARGET") {
+        Ok(target) => target,
+        Err(e) => {
+            println!(
+                "cargo:warning={}: unable to get TARGET environment variable: {}",
+                env!("CARGO_PKG_NAME"),
+                e
+            );
+            return;
+        }
+    };
+
+    // Note that this is `no_*`, not `has_*`. This allows treating
+    // `cfg(target_has_atomic = "ptr")` as true when the build script doesn't
+    // run. This is needed for compatibility with non-cargo build systems that
+    // don't run the build script.
+    if NO_ATOMIC_CAS_TARGETS.contains(&&*target) {
+        println!("cargo:rustc-cfg=futures_no_atomic_cas");
+    }
+
+    println!("cargo:rerun-if-changed=no_atomic_cas.rs");
+}
diff --git a/third_party/rust/futures-core/no_atomic_cas.rs b/third_party/rust/futures-core/no_atomic_cas.rs
new file mode 100644
index 0000000000000000000000000000000000000000..0819af1a45093532034d0042a15a3d460f208d7c
--- /dev/null
+++ b/third_party/rust/futures-core/no_atomic_cas.rs
@@ -0,0 +1,11 @@
+// This file is @generated by no_atomic_cas.sh.
+// It is not intended for manual editing.
+
+const NO_ATOMIC_CAS_TARGETS: &[&str] = &[
+    "avr-unknown-gnu-atmega328",
+    "msp430-none-elf",
+    "riscv32i-unknown-none-elf",
+    "riscv32imc-unknown-none-elf",
+    "thumbv4t-none-eabi",
+    "thumbv6m-none-eabi",
+];
diff --git a/third_party/rust/futures-core/src/future.rs b/third_party/rust/futures-core/src/future.rs
index 02460cc5a35e1965f79d48d1d3dbcd2061d7ec33..7540cd027eb16bbb423c18042516fcf6b247ea0b 100644
--- a/third_party/rust/futures-core/src/future.rs
+++ b/third_party/rust/futures-core/src/future.rs
@@ -4,6 +4,7 @@ use core::ops::DerefMut;
 use core::pin::Pin;
 use core::task::{Context, Poll};
 
+#[doc(no_inline)]
 pub use core::future::Future;
 
 /// An owned dynamically typed [`Future`] for use in cases where you can't
@@ -66,14 +67,12 @@ pub trait TryFuture: Future + private_try_future::Sealed {
     /// This method is a stopgap for a compiler limitation that prevents us from
     /// directly inheriting from the `Future` trait; in the future it won't be
     /// needed.
-    fn try_poll(
-        self: Pin<&mut Self>,
-        cx: &mut Context<'_>,
-    ) -> Poll<Result<Self::Ok, Self::Error>>;
+    fn try_poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<Self::Ok, Self::Error>>;
 }
 
 impl<F, T, E> TryFuture for F
-    where F: ?Sized + Future<Output = Result<T, E>>
+where
+    F: ?Sized + Future<Output = Result<T, E>>,
 {
     type Ok = T;
     type Error = E;
@@ -86,8 +85,8 @@ impl<F, T, E> TryFuture for F
 
 #[cfg(feature = "alloc")]
 mod if_alloc {
-    use alloc::boxed::Box;
     use super::*;
+    use alloc::boxed::Box;
 
     impl<F: FusedFuture + ?Sized + Unpin> FusedFuture for Box<F> {
         fn is_terminated(&self) -> bool {
diff --git a/third_party/rust/futures-core/src/lib.rs b/third_party/rust/futures-core/src/lib.rs
index ec14adba2296da3e8a050296e56525344706e5cb..e363ff777d18e63dc17dfbddf23b3d95cfa2d410 100644
--- a/third_party/rust/futures-core/src/lib.rs
+++ b/third_party/rust/futures-core/src/lib.rs
@@ -1,26 +1,22 @@
 //! Core traits and types for asynchronous operations in Rust.
 
-#![cfg_attr(feature = "cfg-target-has-atomic", feature(cfg_target_has_atomic))]
-
 #![cfg_attr(not(feature = "std"), no_std)]
-
 #![warn(missing_docs, missing_debug_implementations, rust_2018_idioms, unreachable_pub)]
 // It cannot be included in the published code because this lints have false positives in the minimum required version.
 #![cfg_attr(test, warn(single_use_lifetimes))]
 #![warn(clippy::all)]
 #![doc(test(attr(deny(warnings), allow(dead_code, unused_assignments, unused_variables))))]
 
-#[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");
-
 #[cfg(feature = "alloc")]
 extern crate alloc;
 
 pub mod future;
-#[doc(hidden)] pub use self::future::{Future, FusedFuture, TryFuture};
+#[doc(hidden)]
+pub use self::future::{FusedFuture, Future, TryFuture};
 
 pub mod stream;
-#[doc(hidden)] pub use self::stream::{Stream, FusedStream, TryStream};
+#[doc(hidden)]
+pub use self::stream::{FusedStream, Stream, TryStream};
 
 #[macro_use]
 pub mod task;
diff --git a/third_party/rust/futures-core/src/stream.rs b/third_party/rust/futures-core/src/stream.rs
index 4a13e3bd7dc7f0357c447e3f3bf0294527aea522..ad5350b7958863bde4bde735248b5580791220f7 100644
--- a/third_party/rust/futures-core/src/stream.rs
+++ b/third_party/rust/futures-core/src/stream.rs
@@ -63,10 +63,7 @@ pub trait Stream {
     /// calls.
     ///
     /// [`fuse`]: https://docs.rs/futures/0.3/futures/stream/trait.StreamExt.html#method.fuse
-    fn poll_next(
-        self: Pin<&mut Self>,
-        cx: &mut Context<'_>,
-    ) -> Poll<Option<Self::Item>>;
+    fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>>;
 
     /// Returns the bounds on the remaining length of the stream.
     ///
@@ -103,10 +100,7 @@ pub trait Stream {
 impl<S: ?Sized + Stream + Unpin> Stream for &mut S {
     type Item = S::Item;
 
-    fn poll_next(
-        mut self: Pin<&mut Self>,
-        cx: &mut Context<'_>,
-    ) -> Poll<Option<Self::Item>> {
+    fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
         S::poll_next(Pin::new(&mut **self), cx)
     }
 
@@ -122,10 +116,7 @@ where
 {
     type Item = <P::Target as Stream>::Item;
 
-    fn poll_next(
-        self: Pin<&mut Self>,
-        cx: &mut Context<'_>,
-    ) -> Poll<Option<Self::Item>> {
+    fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
         self.get_mut().as_mut().poll_next(cx)
     }
 
@@ -185,35 +176,36 @@ pub trait TryStream: Stream + private_try_stream::Sealed {
     /// This method is a stopgap for a compiler limitation that prevents us from
     /// directly inheriting from the `Stream` trait; in the future it won't be
     /// needed.
-    fn try_poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>)
-        -> Poll<Option<Result<Self::Ok, Self::Error>>>;
+    fn try_poll_next(
+        self: Pin<&mut Self>,
+        cx: &mut Context<'_>,
+    ) -> Poll<Option<Result<Self::Ok, Self::Error>>>;
 }
 
 impl<S, T, E> TryStream for S
-    where S: ?Sized + Stream<Item = Result<T, E>>
+where
+    S: ?Sized + Stream<Item = Result<T, E>>,
 {
     type Ok = T;
     type Error = E;
 
-    fn try_poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>)
-        -> Poll<Option<Result<Self::Ok, Self::Error>>>
-    {
+    fn try_poll_next(
+        self: Pin<&mut Self>,
+        cx: &mut Context<'_>,
+    ) -> Poll<Option<Result<Self::Ok, Self::Error>>> {
         self.poll_next(cx)
     }
 }
 
 #[cfg(feature = "alloc")]
 mod if_alloc {
-    use alloc::boxed::Box;
     use super::*;
+    use alloc::boxed::Box;
 
     impl<S: ?Sized + Stream + Unpin> Stream for Box<S> {
         type Item = S::Item;
 
-        fn poll_next(
-            mut self: Pin<&mut Self>,
-            cx: &mut Context<'_>,
-        ) -> Poll<Option<Self::Item>> {
+        fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
             Pin::new(&mut **self).poll_next(cx)
         }
 
@@ -226,10 +218,7 @@ mod if_alloc {
     impl<S: Stream> Stream for std::panic::AssertUnwindSafe<S> {
         type Item = S::Item;
 
-        fn poll_next(
-            self: Pin<&mut Self>,
-            cx: &mut Context<'_>,
-        ) -> Poll<Option<S::Item>> {
+        fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<S::Item>> {
             unsafe { self.map_unchecked_mut(|x| &mut x.0) }.poll_next(cx)
         }
 
diff --git a/third_party/rust/futures-core/src/task/__internal/atomic_waker.rs b/third_party/rust/futures-core/src/task/__internal/atomic_waker.rs
index 213355bc6b59a81dbd45baaf21df4d05b8ce50d3..d49d043619fb13a887f56e40b9c8e5df9339b137 100644
--- a/third_party/rust/futures-core/src/task/__internal/atomic_waker.rs
+++ b/third_party/rust/futures-core/src/task/__internal/atomic_waker.rs
@@ -1,7 +1,7 @@
 use core::cell::UnsafeCell;
 use core::fmt;
 use core::sync::atomic::AtomicUsize;
-use core::sync::atomic::Ordering::{Acquire, Release, AcqRel};
+use core::sync::atomic::Ordering::{AcqRel, Acquire, Release};
 use core::task::Waker;
 
 /// A synchronization primitive for task wakeup.
@@ -202,10 +202,7 @@ impl AtomicWaker {
         trait AssertSync: Sync {}
         impl AssertSync for Waker {}
 
-        Self {
-            state: AtomicUsize::new(WAITING),
-            waker: UnsafeCell::new(None),
-        }
+        Self { state: AtomicUsize::new(WAITING), waker: UnsafeCell::new(None) }
     }
 
     /// Registers the waker to be notified on calls to `wake`.
@@ -279,8 +276,7 @@ impl AtomicWaker {
                     // nothing to acquire, only release. In case of concurrent
                     // wakers, we need to acquire their releases, so success needs
                     // to do both.
-                    let res = self.state.compare_exchange(
-                        REGISTERING, WAITING, AcqRel, Acquire);
+                    let res = self.state.compare_exchange(REGISTERING, WAITING, AcqRel, Acquire);
 
                     match res {
                         Ok(_) => {
@@ -344,9 +340,7 @@ impl AtomicWaker {
                 //
                 // We just want to maintain memory safety. It is ok to drop the
                 // call to `register`.
-                debug_assert!(
-                    state == REGISTERING ||
-                    state == REGISTERING | WAKING);
+                debug_assert!(state == REGISTERING || state == REGISTERING | WAKING);
             }
         }
     }
@@ -391,9 +385,8 @@ impl AtomicWaker {
                 // not.
                 //
                 debug_assert!(
-                    state == REGISTERING ||
-                    state == REGISTERING | WAKING ||
-                    state == WAKING);
+                    state == REGISTERING || state == REGISTERING | WAKING || state == WAKING
+                );
                 None
             }
         }
diff --git a/third_party/rust/futures-core/src/task/__internal/mod.rs b/third_party/rust/futures-core/src/task/__internal/mod.rs
index 77e367807593a3d7e5adbd97e7a49d65e5dc18d0..c902eb4bfbb51d9340f23b353ee61833791003dc 100644
--- a/third_party/rust/futures-core/src/task/__internal/mod.rs
+++ b/third_party/rust/futures-core/src/task/__internal/mod.rs
@@ -1,4 +1,4 @@
-#[cfg_attr(feature = "cfg-target-has-atomic", cfg(target_has_atomic = "ptr"))]
+#[cfg(not(futures_no_atomic_cas))]
 mod atomic_waker;
-#[cfg_attr(feature = "cfg-target-has-atomic", cfg(target_has_atomic = "ptr"))]
+#[cfg(not(futures_no_atomic_cas))]
 pub use self::atomic_waker::AtomicWaker;
diff --git a/third_party/rust/futures-core/src/task/mod.rs b/third_party/rust/futures-core/src/task/mod.rs
index 362b376e0446f8e3506ef4fcbcbcebf2fe857039..19e4eaecdd6b8340c079ca20aae459600fa8b8d0 100644
--- a/third_party/rust/futures-core/src/task/mod.rs
+++ b/third_party/rust/futures-core/src/task/mod.rs
@@ -6,4 +6,5 @@ mod poll;
 #[doc(hidden)]
 pub mod __internal;
 
-pub use core::task::{Context, Poll, Waker, RawWaker, RawWakerVTable};
+#[doc(no_inline)]
+pub use core::task::{Context, Poll, RawWaker, RawWakerVTable, Waker};
diff --git a/third_party/rust/futures-core/src/task/poll.rs b/third_party/rust/futures-core/src/task/poll.rs
index 8fe294c580f1683dbe353ac20676a16bc1d35acf..930d888d2d14580eb21370629fabae385cacdde1 100644
--- a/third_party/rust/futures-core/src/task/poll.rs
+++ b/third_party/rust/futures-core/src/task/poll.rs
@@ -3,9 +3,10 @@
 /// This macro bakes in propagation of `Pending` signals by returning early.
 #[macro_export]
 macro_rules! ready {
-    ($e:expr $(,)?) => (match $e {
-        $crate::__private::Poll::Ready(t) => t,
-        $crate::__private::Poll::Pending =>
-            return $crate::__private::Poll::Pending,
-    })
+    ($e:expr $(,)?) => {
+        match $e {
+            $crate::__private::Poll::Ready(t) => t,
+            $crate::__private::Poll::Pending => return $crate::__private::Poll::Pending,
+        }
+    };
 }
diff --git a/third_party/rust/futures-io/.cargo-checksum.json b/third_party/rust/futures-io/.cargo-checksum.json
index 83015980788abb4b4a5a655452f482ad1a53bb1e..099a9a8477482e0497a1bb60bbe9c0e7c1ed9be6 100644
--- a/third_party/rust/futures-io/.cargo-checksum.json
+++ b/third_party/rust/futures-io/.cargo-checksum.json
@@ -1 +1 @@
-{"files":{"Cargo.toml":"e5a275fa288df930796e8799ed62332309ce38f00cce58bcf1937ac1405fca3b","LICENSE-APACHE":"275c491d6d1160553c32fd6127061d7f9606c3ea25abfad6ca3f6ed088785427","LICENSE-MIT":"6652c868f35dfe5e8ef636810a4e576b9d663f3a17fb0f5613ad73583e1b88fd","src/lib.rs":"48d906b2cd49cd9182c814fcc4dcc6ed4ef09b7d9c0fcce4e4e3b64ebfb8eb3b"},"package":"28be053525281ad8259d47e4de5de657b25e7bac113458555bb4b70bc6870500"}
\ No newline at end of file
+{"files":{"Cargo.toml":"d5e370a10289c1bab305dd02deda447edf371816ae31b58b1778feb59bc42aba","LICENSE-APACHE":"275c491d6d1160553c32fd6127061d7f9606c3ea25abfad6ca3f6ed088785427","LICENSE-MIT":"6652c868f35dfe5e8ef636810a4e576b9d663f3a17fb0f5613ad73583e1b88fd","src/lib.rs":"ea27ca17d047a9bd7f9c7f357cb77b2b69bb1856316b8a58ce64fa2194e41aab"},"package":"acc499defb3b348f8d8f3f66415835a9131856ff7714bf10dadfc4ec4bdb29a1"}
\ No newline at end of file
diff --git a/third_party/rust/futures-io/Cargo.toml b/third_party/rust/futures-io/Cargo.toml
index 6d0ce1720bd36a74b5d796b06da903fc38988483..e7e5ce0433e94eb063415a833bdf0a5fe8435abb 100644
--- a/third_party/rust/futures-io/Cargo.toml
+++ b/third_party/rust/futures-io/Cargo.toml
@@ -13,7 +13,7 @@
 [package]
 edition = "2018"
 name = "futures-io"
-version = "0.3.12"
+version = "0.3.15"
 authors = ["Alex Crichton <alex@alexcrichton.com>"]
 description = "The `AsyncRead`, `AsyncWrite`, `AsyncSeek`, and `AsyncBufRead` traits for the futures-rs library.\n"
 homepage = "https://rust-lang.github.io/futures-rs"
diff --git a/third_party/rust/futures-io/src/lib.rs b/third_party/rust/futures-io/src/lib.rs
index 1468ea0facb1191c6fc432a17bad41b85fa5cfd5..998042d2998226ee1e1faed275e6c02cb770b910 100644
--- a/third_party/rust/futures-io/src/lib.rs
+++ b/third_party/rust/futures-io/src/lib.rs
@@ -9,15 +9,12 @@
 //! library is activated, and it is activated by default.
 
 #![cfg_attr(all(feature = "read-initializer", feature = "std"), feature(read_initializer))]
-
 #![cfg_attr(not(feature = "std"), no_std)]
-
 #![warn(missing_docs, missing_debug_implementations, rust_2018_idioms, unreachable_pub)]
 // It cannot be included in the published code because this lints have false positives in the minimum required version.
 #![cfg_attr(test, warn(single_use_lifetimes))]
 #![warn(clippy::all)]
 #![doc(test(attr(deny(warnings), allow(dead_code, unused_assignments, unused_variables))))]
-
 #![cfg_attr(docsrs, feature(doc_cfg))]
 
 #[cfg(all(feature = "read-initializer", not(feature = "unstable")))]
@@ -32,20 +29,14 @@ mod if_std {
 
     // Re-export some types from `std::io` so that users don't have to deal
     // with conflicts when `use`ing `futures::io` and `std::io`.
-    #[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411
-    pub use io::{
-        Error as Error,
-        ErrorKind as ErrorKind,
-        Result as Result,
-        IoSlice as IoSlice,
-        IoSliceMut as IoSliceMut,
-        SeekFrom as SeekFrom,
-    };
-
     #[cfg(feature = "read-initializer")]
     #[cfg_attr(docsrs, doc(cfg(feature = "read-initializer")))]
+    #[doc(no_inline)]
+    #[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411
+    pub use io::Initializer;
     #[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411
-    pub use io::Initializer as Initializer;
+    #[doc(no_inline)]
+    pub use io::{Error, ErrorKind, IoSlice, IoSliceMut, Result, SeekFrom};
 
     /// Read bytes asynchronously.
     ///
@@ -91,8 +82,11 @@ mod if_std {
         /// `Interrupted`.  Implementations must convert `WouldBlock` into
         /// `Poll::Pending` and either internally retry or convert
         /// `Interrupted` into another error kind.
-        fn poll_read(self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &mut [u8])
-            -> Poll<Result<usize>>;
+        fn poll_read(
+            self: Pin<&mut Self>,
+            cx: &mut Context<'_>,
+            buf: &mut [u8],
+        ) -> Poll<Result<usize>>;
 
         /// Attempt to read from the `AsyncRead` into `bufs` using vectored
         /// IO operations.
@@ -116,9 +110,11 @@ mod if_std {
         /// `Interrupted`.  Implementations must convert `WouldBlock` into
         /// `Poll::Pending` and either internally retry or convert
         /// `Interrupted` into another error kind.
-        fn poll_read_vectored(self: Pin<&mut Self>, cx: &mut Context<'_>, bufs: &mut [IoSliceMut<'_>])
-            -> Poll<Result<usize>>
-        {
+        fn poll_read_vectored(
+            self: Pin<&mut Self>,
+            cx: &mut Context<'_>,
+            bufs: &mut [IoSliceMut<'_>],
+        ) -> Poll<Result<usize>> {
             for b in bufs {
                 if !b.is_empty() {
                     return self.poll_read(cx, b);
@@ -155,8 +151,11 @@ mod if_std {
         ///
         /// `poll_write` must try to make progress by flushing the underlying object if
         /// that is the only way the underlying object can become writable again.
-        fn poll_write(self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &[u8])
-            -> Poll<Result<usize>>;
+        fn poll_write(
+            self: Pin<&mut Self>,
+            cx: &mut Context<'_>,
+            buf: &[u8],
+        ) -> Poll<Result<usize>>;
 
         /// Attempt to write bytes from `bufs` into the object using vectored
         /// IO operations.
@@ -181,9 +180,11 @@ mod if_std {
         /// `Interrupted`.  Implementations must convert `WouldBlock` into
         /// `Poll::Pending` and either internally retry or convert
         /// `Interrupted` into another error kind.
-        fn poll_write_vectored(self: Pin<&mut Self>, cx: &mut Context<'_>, bufs: &[IoSlice<'_>])
-            -> Poll<Result<usize>>
-        {
+        fn poll_write_vectored(
+            self: Pin<&mut Self>,
+            cx: &mut Context<'_>,
+            bufs: &[IoSlice<'_>],
+        ) -> Poll<Result<usize>> {
             for b in bufs {
                 if !b.is_empty() {
                     return self.poll_write(cx, b);
@@ -258,8 +259,11 @@ mod if_std {
         /// `Interrupted`.  Implementations must convert `WouldBlock` into
         /// `Poll::Pending` and either internally retry or convert
         /// `Interrupted` into another error kind.
-        fn poll_seek(self: Pin<&mut Self>, cx: &mut Context<'_>, pos: SeekFrom)
-            -> Poll<Result<u64>>;
+        fn poll_seek(
+            self: Pin<&mut Self>,
+            cx: &mut Context<'_>,
+            pos: SeekFrom,
+        ) -> Poll<Result<u64>>;
     }
 
     /// Read bytes asynchronously.
@@ -298,8 +302,7 @@ mod if_std {
         /// `Interrupted`.  Implementations must convert `WouldBlock` into
         /// `Poll::Pending` and either internally retry or convert
         /// `Interrupted` into another error kind.
-        fn poll_fill_buf(self: Pin<&mut Self>, cx: &mut Context<'_>)
-            -> Poll<Result<&[u8]>>;
+        fn poll_fill_buf(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<&[u8]>>;
 
         /// Tells this buffer that `amt` bytes have been consumed from the buffer,
         /// so they should no longer be returned in calls to [`poll_read`].
@@ -326,18 +329,22 @@ mod if_std {
                 (**self).initializer()
             }
 
-            fn poll_read(mut self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &mut [u8])
-                -> Poll<Result<usize>>
-            {
+            fn poll_read(
+                mut self: Pin<&mut Self>,
+                cx: &mut Context<'_>,
+                buf: &mut [u8],
+            ) -> Poll<Result<usize>> {
                 Pin::new(&mut **self).poll_read(cx, buf)
             }
 
-            fn poll_read_vectored(mut self: Pin<&mut Self>, cx: &mut Context<'_>, bufs: &mut [IoSliceMut<'_>])
-                -> Poll<Result<usize>>
-            {
+            fn poll_read_vectored(
+                mut self: Pin<&mut Self>,
+                cx: &mut Context<'_>,
+                bufs: &mut [IoSliceMut<'_>],
+            ) -> Poll<Result<usize>> {
                 Pin::new(&mut **self).poll_read_vectored(cx, bufs)
             }
-        }
+        };
     }
 
     impl<T: ?Sized + AsyncRead + Unpin> AsyncRead for Box<T> {
@@ -358,15 +365,19 @@ mod if_std {
             (**self).initializer()
         }
 
-        fn poll_read(self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &mut [u8])
-            -> Poll<Result<usize>>
-        {
+        fn poll_read(
+            self: Pin<&mut Self>,
+            cx: &mut Context<'_>,
+            buf: &mut [u8],
+        ) -> Poll<Result<usize>> {
             self.get_mut().as_mut().poll_read(cx, buf)
         }
 
-        fn poll_read_vectored(self: Pin<&mut Self>, cx: &mut Context<'_>, bufs: &mut [IoSliceMut<'_>])
-            -> Poll<Result<usize>>
-        {
+        fn poll_read_vectored(
+            self: Pin<&mut Self>,
+            cx: &mut Context<'_>,
+            bufs: &mut [IoSliceMut<'_>],
+        ) -> Poll<Result<usize>> {
             self.get_mut().as_mut().poll_read_vectored(cx, bufs)
         }
     }
@@ -378,18 +389,22 @@ mod if_std {
                 io::Read::initializer(self)
             }
 
-            fn poll_read(mut self: Pin<&mut Self>, _: &mut Context<'_>, buf: &mut [u8])
-                -> Poll<Result<usize>>
-            {
+            fn poll_read(
+                mut self: Pin<&mut Self>,
+                _: &mut Context<'_>,
+                buf: &mut [u8],
+            ) -> Poll<Result<usize>> {
                 Poll::Ready(io::Read::read(&mut *self, buf))
             }
 
-            fn poll_read_vectored(mut self: Pin<&mut Self>, _: &mut Context<'_>, bufs: &mut [IoSliceMut<'_>])
-                -> Poll<Result<usize>>
-            {
+            fn poll_read_vectored(
+                mut self: Pin<&mut Self>,
+                _: &mut Context<'_>,
+                bufs: &mut [IoSliceMut<'_>],
+            ) -> Poll<Result<usize>> {
                 Poll::Ready(io::Read::read_vectored(&mut *self, bufs))
             }
-        }
+        };
     }
 
     impl AsyncRead for &[u8] {
@@ -398,15 +413,19 @@ mod if_std {
 
     macro_rules! deref_async_write {
         () => {
-            fn poll_write(mut self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &[u8])
-                -> Poll<Result<usize>>
-            {
+            fn poll_write(
+                mut self: Pin<&mut Self>,
+                cx: &mut Context<'_>,
+                buf: &[u8],
+            ) -> Poll<Result<usize>> {
                 Pin::new(&mut **self).poll_write(cx, buf)
             }
 
-            fn poll_write_vectored(mut self: Pin<&mut Self>, cx: &mut Context<'_>, bufs: &[IoSlice<'_>])
-                -> Poll<Result<usize>>
-            {
+            fn poll_write_vectored(
+                mut self: Pin<&mut Self>,
+                cx: &mut Context<'_>,
+                bufs: &[IoSlice<'_>],
+            ) -> Poll<Result<usize>> {
                 Pin::new(&mut **self).poll_write_vectored(cx, bufs)
             }
 
@@ -417,7 +436,7 @@ mod if_std {
             fn poll_close(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<()>> {
                 Pin::new(&mut **self).poll_close(cx)
             }
-        }
+        };
     }
 
     impl<T: ?Sized + AsyncWrite + Unpin> AsyncWrite for Box<T> {
@@ -433,15 +452,19 @@ mod if_std {
         P: DerefMut + Unpin,
         P::Target: AsyncWrite,
     {
-        fn poll_write(self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &[u8])
-            -> Poll<Result<usize>>
-        {
+        fn poll_write(
+            self: Pin<&mut Self>,
+            cx: &mut Context<'_>,
+            buf: &[u8],
+        ) -> Poll<Result<usize>> {
             self.get_mut().as_mut().poll_write(cx, buf)
         }
 
-        fn poll_write_vectored(self: Pin<&mut Self>, cx: &mut Context<'_>, bufs: &[IoSlice<'_>])
-            -> Poll<Result<usize>>
-        {
+        fn poll_write_vectored(
+            self: Pin<&mut Self>,
+            cx: &mut Context<'_>,
+            bufs: &[IoSlice<'_>],
+        ) -> Poll<Result<usize>> {
             self.get_mut().as_mut().poll_write_vectored(cx, bufs)
         }
 
@@ -456,15 +479,19 @@ mod if_std {
 
     macro_rules! delegate_async_write_to_stdio {
         () => {
-            fn poll_write(mut self: Pin<&mut Self>, _: &mut Context<'_>, buf: &[u8])
-                -> Poll<Result<usize>>
-            {
+            fn poll_write(
+                mut self: Pin<&mut Self>,
+                _: &mut Context<'_>,
+                buf: &[u8],
+            ) -> Poll<Result<usize>> {
                 Poll::Ready(io::Write::write(&mut *self, buf))
             }
 
-            fn poll_write_vectored(mut self: Pin<&mut Self>, _: &mut Context<'_>, bufs: &[IoSlice<'_>])
-                -> Poll<Result<usize>>
-            {
+            fn poll_write_vectored(
+                mut self: Pin<&mut Self>,
+                _: &mut Context<'_>,
+                bufs: &[IoSlice<'_>],
+            ) -> Poll<Result<usize>> {
                 Poll::Ready(io::Write::write_vectored(&mut *self, bufs))
             }
 
@@ -475,7 +502,7 @@ mod if_std {
             fn poll_close(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<()>> {
                 self.poll_flush(cx)
             }
-        }
+        };
     }
 
     impl AsyncWrite for Vec<u8> {
@@ -484,12 +511,14 @@ mod if_std {
 
     macro_rules! deref_async_seek {
         () => {
-            fn poll_seek(mut self: Pin<&mut Self>, cx: &mut Context<'_>, pos: SeekFrom)
-                -> Poll<Result<u64>>
-            {
+            fn poll_seek(
+                mut self: Pin<&mut Self>,
+                cx: &mut Context<'_>,
+                pos: SeekFrom,
+            ) -> Poll<Result<u64>> {
                 Pin::new(&mut **self).poll_seek(cx, pos)
             }
-        }
+        };
     }
 
     impl<T: ?Sized + AsyncSeek + Unpin> AsyncSeek for Box<T> {
@@ -505,25 +534,25 @@ mod if_std {
         P: DerefMut + Unpin,
         P::Target: AsyncSeek,
     {
-        fn poll_seek(self: Pin<&mut Self>, cx: &mut Context<'_>, pos: SeekFrom)
-            -> Poll<Result<u64>>
-        {
+        fn poll_seek(
+            self: Pin<&mut Self>,
+            cx: &mut Context<'_>,
+            pos: SeekFrom,
+        ) -> Poll<Result<u64>> {
             self.get_mut().as_mut().poll_seek(cx, pos)
         }
     }
 
     macro_rules! deref_async_buf_read {
         () => {
-            fn poll_fill_buf(self: Pin<&mut Self>, cx: &mut Context<'_>)
-                -> Poll<Result<&[u8]>>
-            {
+            fn poll_fill_buf(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<&[u8]>> {
                 Pin::new(&mut **self.get_mut()).poll_fill_buf(cx)
             }
 
             fn consume(mut self: Pin<&mut Self>, amt: usize) {
                 Pin::new(&mut **self).consume(amt)
             }
-        }
+        };
     }
 
     impl<T: ?Sized + AsyncBufRead + Unpin> AsyncBufRead for Box<T> {
@@ -539,9 +568,7 @@ mod if_std {
         P: DerefMut + Unpin,
         P::Target: AsyncBufRead,
     {
-        fn poll_fill_buf(self: Pin<&mut Self>, cx: &mut Context<'_>)
-            -> Poll<Result<&[u8]>>
-        {
+        fn poll_fill_buf(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<&[u8]>> {
             self.get_mut().as_mut().poll_fill_buf(cx)
         }
 
@@ -552,16 +579,14 @@ mod if_std {
 
     macro_rules! delegate_async_buf_read_to_stdio {
         () => {
-            fn poll_fill_buf(self: Pin<&mut Self>, _: &mut Context<'_>)
-                -> Poll<Result<&[u8]>>
-            {
+            fn poll_fill_buf(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<Result<&[u8]>> {
                 Poll::Ready(io::BufRead::fill_buf(self.get_mut()))
             }
 
             fn consume(self: Pin<&mut Self>, amt: usize) {
                 io::BufRead::consume(self.get_mut(), amt)
             }
-        }
+        };
     }
 
     impl AsyncBufRead for &[u8] {
diff --git a/third_party/rust/futures-sink/.cargo-checksum.json b/third_party/rust/futures-sink/.cargo-checksum.json
index 8081670298f3f6afc0d2ec883424964990ec2e9a..d454150f7632692326c380e7a89396cb197568cb 100644
--- a/third_party/rust/futures-sink/.cargo-checksum.json
+++ b/third_party/rust/futures-sink/.cargo-checksum.json
@@ -1 +1 @@
-{"files":{"Cargo.toml":"e9a23319c9510deace8844371158dd8d4fa628fd82ad1941908da24c4e9e4865","LICENSE-APACHE":"275c491d6d1160553c32fd6127061d7f9606c3ea25abfad6ca3f6ed088785427","LICENSE-MIT":"6652c868f35dfe5e8ef636810a4e576b9d663f3a17fb0f5613ad73583e1b88fd","src/lib.rs":"55f82ed20e82a7e3098daa2b27f6f44ebfb44084e179889fb6e28b6b5ccef094"},"package":"caf5c69029bda2e743fddd0582d1083951d65cc9539aebf8812f36c3491342d6"}
\ No newline at end of file
+{"files":{"Cargo.toml":"c8672b3d01ce6871ccbc1a8c92b1338a2b4769ea3456201493b924d287be0dd5","LICENSE-APACHE":"275c491d6d1160553c32fd6127061d7f9606c3ea25abfad6ca3f6ed088785427","LICENSE-MIT":"6652c868f35dfe5e8ef636810a4e576b9d663f3a17fb0f5613ad73583e1b88fd","src/lib.rs":"544fa41af99cc7492723583ac71b494fbd0a0cdc1b1b6ee8f418eea79ec23a1a"},"package":"a57bead0ceff0d6dde8f465ecd96c9338121bb7717d3e7b108059531870c4282"}
\ No newline at end of file
diff --git a/third_party/rust/futures-sink/Cargo.toml b/third_party/rust/futures-sink/Cargo.toml
index 38daaa42b1cd42294e59cc0af14458f5be0216ae..35839be6772288f518b92931627668c6a2a10e37 100644
--- a/third_party/rust/futures-sink/Cargo.toml
+++ b/third_party/rust/futures-sink/Cargo.toml
@@ -13,7 +13,7 @@
 [package]
 edition = "2018"
 name = "futures-sink"
-version = "0.3.12"
+version = "0.3.15"
 authors = ["Alex Crichton <alex@alexcrichton.com>"]
 description = "The asynchronous `Sink` trait for the futures-rs library.\n"
 homepage = "https://rust-lang.github.io/futures-rs"
diff --git a/third_party/rust/futures-sink/src/lib.rs b/third_party/rust/futures-sink/src/lib.rs
index 6193f51d6bd72b6107d1cdc5c14475e21ad1719b..4dc2fb3d37eadbdb7adc50963edc3cd28954a574 100644
--- a/third_party/rust/futures-sink/src/lib.rs
+++ b/third_party/rust/futures-sink/src/lib.rs
@@ -207,7 +207,10 @@ mod if_alloc {
     impl<S: ?Sized + Sink<Item> + Unpin, Item> Sink<Item> for alloc::boxed::Box<S> {
         type Error = S::Error;
 
-        fn poll_ready(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
+        fn poll_ready(
+            mut self: Pin<&mut Self>,
+            cx: &mut Context<'_>,
+        ) -> Poll<Result<(), Self::Error>> {
             Pin::new(&mut **self).poll_ready(cx)
         }
 
@@ -215,11 +218,17 @@ mod if_alloc {
             Pin::new(&mut **self).start_send(item)
         }
 
-        fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
+        fn poll_flush(
+            mut self: Pin<&mut Self>,
+            cx: &mut Context<'_>,
+        ) -> Poll<Result<(), Self::Error>> {
             Pin::new(&mut **self).poll_flush(cx)
         }
 
-        fn poll_close(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
+        fn poll_close(
+            mut self: Pin<&mut Self>,
+            cx: &mut Context<'_>,
+        ) -> Poll<Result<(), Self::Error>> {
             Pin::new(&mut **self).poll_close(cx)
         }
     }
diff --git a/third_party/rust/futures-task/.cargo-checksum.json b/third_party/rust/futures-task/.cargo-checksum.json
index 78a67098c40db4db62d926971c59752f74329529..784152a58479aec431db29be244baf51e74784e8 100644
--- a/third_party/rust/futures-task/.cargo-checksum.json
+++ b/third_party/rust/futures-task/.cargo-checksum.json
@@ -1 +1 @@
-{"files":{"Cargo.toml":"94e891480585672d81a3633666e1f3efdad0dfd6e002c5b2b898198281c50e97","LICENSE-APACHE":"275c491d6d1160553c32fd6127061d7f9606c3ea25abfad6ca3f6ed088785427","LICENSE-MIT":"6652c868f35dfe5e8ef636810a4e576b9d663f3a17fb0f5613ad73583e1b88fd","src/arc_wake.rs":"0e3f7d7883b75337b0b92ff55e477f0bf96f6eb08def7d953676a289fd9696ec","src/future_obj.rs":"761fdb79771d37c5ac7bf71188b1fee6a6c7456b490f3e6ad6891995f79ee5e9","src/lib.rs":"59a259e7da18edfc0596b6b4a30812e85bac58c7a404ba99534ccda27b8606b5","src/noop_waker.rs":"094c2b701420bdcffaff44563c1eef8da3e0fc424f87eb665074c9a0a48bd301","src/spawn.rs":"37c7753e724d8346af5bb43462b1cf605e23bc5a3209feb2a6f33a018e9fa262","src/waker.rs":"fd951d3498739178c4b684ddb8d1a351b094bd300b52c1ccb0b9284affbcfed7","src/waker_ref.rs":"4189e2ad0ed1c1e73b374da6de448587bb39154efbd30b5c20ff92f95e91c3ad"},"package":"13de07eb8ea81ae445aca7b69f5f7bf15d7bf4912d8ca37d6645c77ae8a58d86"}
\ No newline at end of file
+{"files":{"Cargo.toml":"8cd1524537c3c7105708c37c7bb57307048e3ef940740a6b6fb0fabaf9dc8eb8","LICENSE-APACHE":"275c491d6d1160553c32fd6127061d7f9606c3ea25abfad6ca3f6ed088785427","LICENSE-MIT":"6652c868f35dfe5e8ef636810a4e576b9d663f3a17fb0f5613ad73583e1b88fd","build.rs":"eacc35149926db46503723d9f2aab180691571f2ea68b6f6e7b0d1d4d0d7baef","no_atomic_cas.rs":"1b1d0f659624ba744e83a20204f4f5b2b658bb7c934543851c2d569792b4b825","src/arc_wake.rs":"0e3f7d7883b75337b0b92ff55e477f0bf96f6eb08def7d953676a289fd9696ec","src/future_obj.rs":"10dab39a613d938823f09c3ecdbf7e199ac173a775fd8c5db675c7ecb3b429a2","src/lib.rs":"3570aa1888d8440521ff69bb2da4612230865b8d008aece3b914aac0a50c3763","src/noop_waker.rs":"41246601dab77f69bf09257afc3321031a5a31a7eda51787029870eda9922356","src/spawn.rs":"fbf70b975c8414687c30c1a7642055309743810732c28249a7d4597bf485241a","src/waker.rs":"748d4a045ea9be605a67f3c20607cc3a5ba20036942c0016cc4299df0446507c","src/waker_ref.rs":"8e3ce1aea4f433ce04c2d15eb065d89582527c1a3a15886c445eb3a78f4fd0d6"},"package":"8a16bef9fc1a4dddb5bee51c989e3fbba26569cbb0e31f5b303c184e3dd33dae"}
\ No newline at end of file
diff --git a/third_party/rust/futures-task/Cargo.toml b/third_party/rust/futures-task/Cargo.toml
index 85fce8d4983f5f6e93b6214b91701d2180b00288..d5187dba029419bf2f86b5555cb7a53e12c9c54b 100644
--- a/third_party/rust/futures-task/Cargo.toml
+++ b/third_party/rust/futures-task/Cargo.toml
@@ -13,7 +13,7 @@
 [package]
 edition = "2018"
 name = "futures-task"
-version = "0.3.12"
+version = "0.3.15"
 authors = ["Alex Crichton <alex@alexcrichton.com>"]
 description = "Tools for working with tasks.\n"
 homepage = "https://rust-lang.github.io/futures-rs"
@@ -22,11 +22,8 @@ license = "MIT OR Apache-2.0"
 repository = "https://github.com/rust-lang/futures-rs"
 [package.metadata.docs.rs]
 all-features = true
-[dependencies.once_cell]
-version = "1.3.1"
-features = ["std"]
-optional = true
-default-features = false
+
+[dependencies]
 
 [dev-dependencies]
 
@@ -34,5 +31,5 @@ default-features = false
 alloc = []
 cfg-target-has-atomic = []
 default = ["std"]
-std = ["alloc", "once_cell"]
+std = ["alloc"]
 unstable = []
diff --git a/third_party/rust/futures-task/build.rs b/third_party/rust/futures-task/build.rs
new file mode 100644
index 0000000000000000000000000000000000000000..c4f341d4806b12c6af8cf1223014f47691ca5013
--- /dev/null
+++ b/third_party/rust/futures-task/build.rs
@@ -0,0 +1,42 @@
+#![warn(rust_2018_idioms, single_use_lifetimes)]
+
+use std::env;
+
+include!("no_atomic_cas.rs");
+
+// The rustc-cfg listed below are considered public API, but it is *unstable*
+// and outside of the normal semver guarantees:
+//
+// - `futures_no_atomic_cas`
+//      Assume the target does not have atomic CAS (compare-and-swap).
+//      This is usually detected automatically by the build script, but you may
+//      need to enable it manually when building for custom targets or using
+//      non-cargo build systems that don't run the build script.
+//
+// With the exceptions mentioned above, the rustc-cfg strings below are
+// *not* public API. Please let us know by opening a GitHub issue if your build
+// environment requires some way to enable these cfgs other than by executing
+// our build script.
+fn main() {
+    let target = match env::var("TARGET") {
+        Ok(target) => target,
+        Err(e) => {
+            println!(
+                "cargo:warning={}: unable to get TARGET environment variable: {}",
+                env!("CARGO_PKG_NAME"),
+                e
+            );
+            return;
+        }
+    };
+
+    // Note that this is `no_*`, not `has_*`. This allows treating
+    // `cfg(target_has_atomic = "ptr")` as true when the build script doesn't
+    // run. This is needed for compatibility with non-cargo build systems that
+    // don't run the build script.
+    if NO_ATOMIC_CAS_TARGETS.contains(&&*target) {
+        println!("cargo:rustc-cfg=futures_no_atomic_cas");
+    }
+
+    println!("cargo:rerun-if-changed=no_atomic_cas.rs");
+}
diff --git a/third_party/rust/futures-task/no_atomic_cas.rs b/third_party/rust/futures-task/no_atomic_cas.rs
new file mode 100644
index 0000000000000000000000000000000000000000..0819af1a45093532034d0042a15a3d460f208d7c
--- /dev/null
+++ b/third_party/rust/futures-task/no_atomic_cas.rs
@@ -0,0 +1,11 @@
+// This file is @generated by no_atomic_cas.sh.
+// It is not intended for manual editing.
+
+const NO_ATOMIC_CAS_TARGETS: &[&str] = &[
+    "avr-unknown-gnu-atmega328",
+    "msp430-none-elf",
+    "riscv32i-unknown-none-elf",
+    "riscv32imc-unknown-none-elf",
+    "thumbv4t-none-eabi",
+    "thumbv6m-none-eabi",
+];
diff --git a/third_party/rust/futures-task/src/future_obj.rs b/third_party/rust/futures-task/src/future_obj.rs
index 373be244cd42723a99df4e66fed83abbe187257b..48ec12beb2b3b3f6cdcc7588f267d4e63684baa6 100644
--- a/third_party/rust/futures-task/src/future_obj.rs
+++ b/third_party/rust/futures-task/src/future_obj.rs
@@ -1,8 +1,8 @@
 use core::{
-    mem,
     fmt,
     future::Future,
     marker::PhantomData,
+    mem,
     pin::Pin,
     task::{Context, Poll},
 };
@@ -26,16 +26,16 @@ impl<T> Unpin for LocalFutureObj<'_, T> {}
 
 #[allow(single_use_lifetimes)]
 #[allow(clippy::transmute_ptr_to_ptr)]
-unsafe fn remove_future_lifetime<'a, T>(ptr: *mut (dyn Future<Output = T> + 'a))
-    -> *mut (dyn Future<Output = T> + 'static)
-{
+unsafe fn remove_future_lifetime<'a, T>(
+    ptr: *mut (dyn Future<Output = T> + 'a),
+) -> *mut (dyn Future<Output = T> + 'static) {
     mem::transmute(ptr)
 }
 
 #[allow(single_use_lifetimes)]
-unsafe fn remove_drop_lifetime<'a, T>(ptr: unsafe fn (*mut (dyn Future<Output = T> + 'a)))
-    -> unsafe fn(*mut (dyn Future<Output = T> + 'static))
-{
+unsafe fn remove_drop_lifetime<'a, T>(
+    ptr: unsafe fn(*mut (dyn Future<Output = T> + 'a)),
+) -> unsafe fn(*mut (dyn Future<Output = T> + 'static)) {
     mem::transmute(ptr)
 }
 
@@ -65,8 +65,7 @@ impl<'a, T> LocalFutureObj<'a, T> {
 
 impl<T> fmt::Debug for LocalFutureObj<'_, T> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.debug_struct("LocalFutureObj")
-            .finish()
+        f.debug_struct("LocalFutureObj").finish()
     }
 }
 
@@ -82,17 +81,13 @@ impl<T> Future for LocalFutureObj<'_, T> {
 
     #[inline]
     fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<T> {
-        unsafe {
-            Pin::new_unchecked(&mut *self.future).poll(cx)
-        }
+        unsafe { Pin::new_unchecked(&mut *self.future).poll(cx) }
     }
 }
 
 impl<T> Drop for LocalFutureObj<'_, T> {
     fn drop(&mut self) {
-        unsafe {
-            (self.drop_fn)(self.future)
-        }
+        unsafe { (self.drop_fn)(self.future) }
     }
 }
 
@@ -120,8 +115,7 @@ impl<'a, T> FutureObj<'a, T> {
 
 impl<T> fmt::Debug for FutureObj<'_, T> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.debug_struct("FutureObj")
-            .finish()
+        f.debug_struct("FutureObj").finish()
     }
 }
 
@@ -130,7 +124,7 @@ impl<T> Future for FutureObj<'_, T> {
 
     #[inline]
     fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<T> {
-        Pin::new( &mut self.0 ).poll(cx)
+        Pin::new(&mut self.0).poll(cx)
     }
 }
 
@@ -180,7 +174,7 @@ pub unsafe trait UnsafeFutureObj<'a, T>: 'a {
 
 unsafe impl<'a, T, F> UnsafeFutureObj<'a, T> for &'a mut F
 where
-    F: Future<Output = T> + Unpin + 'a
+    F: Future<Output = T> + Unpin + 'a,
 {
     fn into_raw(self) -> *mut (dyn Future<Output = T> + 'a) {
         self as *mut dyn Future<Output = T>
@@ -189,8 +183,7 @@ where
     unsafe fn drop(_ptr: *mut (dyn Future<Output = T> + 'a)) {}
 }
 
-unsafe impl<'a, T> UnsafeFutureObj<'a, T> for &'a mut (dyn Future<Output = T> + Unpin + 'a)
-{
+unsafe impl<'a, T> UnsafeFutureObj<'a, T> for &'a mut (dyn Future<Output = T> + Unpin + 'a) {
     fn into_raw(self) -> *mut (dyn Future<Output = T> + 'a) {
         self as *mut dyn Future<Output = T>
     }
@@ -200,7 +193,7 @@ unsafe impl<'a, T> UnsafeFutureObj<'a, T> for &'a mut (dyn Future<Output = T> +
 
 unsafe impl<'a, T, F> UnsafeFutureObj<'a, T> for Pin<&'a mut F>
 where
-    F: Future<Output = T> + 'a
+    F: Future<Output = T> + 'a,
 {
     fn into_raw(self) -> *mut (dyn Future<Output = T> + 'a) {
         unsafe { self.get_unchecked_mut() as *mut dyn Future<Output = T> }
@@ -209,8 +202,7 @@ where
     unsafe fn drop(_ptr: *mut (dyn Future<Output = T> + 'a)) {}
 }
 
-unsafe impl<'a, T> UnsafeFutureObj<'a, T> for Pin<&'a mut (dyn Future<Output = T> + 'a)>
-{
+unsafe impl<'a, T> UnsafeFutureObj<'a, T> for Pin<&'a mut (dyn Future<Output = T> + 'a)> {
     fn into_raw(self) -> *mut (dyn Future<Output = T> + 'a) {
         unsafe { self.get_unchecked_mut() as *mut dyn Future<Output = T> }
     }
@@ -224,7 +216,8 @@ mod if_alloc {
     use alloc::boxed::Box;
 
     unsafe impl<'a, T, F> UnsafeFutureObj<'a, T> for Box<F>
-        where F: Future<Output = T> + 'a
+    where
+        F: Future<Output = T> + 'a,
     {
         fn into_raw(self) -> *mut (dyn Future<Output = T> + 'a) {
             Box::into_raw(self)
@@ -257,7 +250,7 @@ mod if_alloc {
 
     unsafe impl<'a, T, F> UnsafeFutureObj<'a, T> for Pin<Box<F>>
     where
-        F: Future<Output = T> + 'a
+        F: Future<Output = T> + 'a,
     {
         fn into_raw(mut self) -> *mut (dyn Future<Output = T> + 'a) {
             let ptr = unsafe { self.as_mut().get_unchecked_mut() as *mut _ };
diff --git a/third_party/rust/futures-task/src/lib.rs b/third_party/rust/futures-task/src/lib.rs
index 92b4ad0d2538300703a70b799d0a2ae1a8a77e8e..439af135af274cd7cbdaea3e07fb8a7671b48d51 100644
--- a/third_party/rust/futures-task/src/lib.rs
+++ b/third_party/rust/futures-task/src/lib.rs
@@ -1,30 +1,24 @@
 //! Tools for working with tasks.
 
-#![cfg_attr(feature = "cfg-target-has-atomic", feature(cfg_target_has_atomic))]
-
 #![cfg_attr(not(feature = "std"), no_std)]
-
 #![warn(missing_docs, missing_debug_implementations, rust_2018_idioms, unreachable_pub)]
 // It cannot be included in the published code because this lints have false positives in the minimum required version.
 #![cfg_attr(test, warn(single_use_lifetimes))]
 #![warn(clippy::all)]
 #![doc(test(attr(deny(warnings), allow(dead_code, unused_assignments, unused_variables))))]
 
-#[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");
-
 #[cfg(feature = "alloc")]
 extern crate alloc;
 
 macro_rules! cfg_target_has_atomic {
     ($($item:item)*) => {$(
-        #[cfg_attr(feature = "cfg-target-has-atomic", cfg(target_has_atomic = "ptr"))]
+        #[cfg(not(futures_no_atomic_cas))]
         $item
     )*};
 }
 
 mod spawn;
-pub use crate::spawn::{Spawn, SpawnError, LocalSpawn};
+pub use crate::spawn::{LocalSpawn, Spawn, SpawnError};
 
 cfg_target_has_atomic! {
     #[cfg(feature = "alloc")]
@@ -48,7 +42,7 @@ pub use crate::future_obj::{FutureObj, LocalFutureObj, UnsafeFutureObj};
 
 mod noop_waker;
 pub use crate::noop_waker::noop_waker;
-#[cfg(feature = "std")]
 pub use crate::noop_waker::noop_waker_ref;
 
-pub use core::task::{Context, Poll, Waker, RawWaker, RawWakerVTable};
+#[doc(no_inline)]
+pub use core::task::{Context, Poll, RawWaker, RawWakerVTable, Waker};
diff --git a/third_party/rust/futures-task/src/noop_waker.rs b/third_party/rust/futures-task/src/noop_waker.rs
index 2a84bcd6f3991e59cd61d19ee95655505152cd61..f76a8a2e95d8e2502a9a53d910dfba54643b298a 100644
--- a/third_party/rust/futures-task/src/noop_waker.rs
+++ b/third_party/rust/futures-task/src/noop_waker.rs
@@ -1,9 +1,7 @@
 //! Utilities for creating zero-cost wakers that don't do anything.
 
-use core::task::{RawWaker, RawWakerVTable, Waker};
 use core::ptr::null;
-#[cfg(feature = "std")]
-use once_cell::sync::Lazy;
+use core::task::{RawWaker, RawWakerVTable, Waker};
 
 unsafe fn noop_clone(_data: *const ()) -> RawWaker {
     noop_raw_waker()
@@ -13,7 +11,7 @@ unsafe fn noop(_data: *const ()) {}
 
 const NOOP_WAKER_VTABLE: RawWakerVTable = RawWakerVTable::new(noop_clone, noop, noop, noop);
 
-fn noop_raw_waker() -> RawWaker {
+const fn noop_raw_waker() -> RawWaker {
     RawWaker::new(null(), &NOOP_WAKER_VTABLE)
 }
 
@@ -29,9 +27,8 @@ fn noop_raw_waker() -> RawWaker {
 /// ```
 #[inline]
 pub fn noop_waker() -> Waker {
-    unsafe {
-        Waker::from_raw(noop_raw_waker())
-    }
+    // FIXME: Since 1.46.0 we can use transmute in consts, allowing this function to be const.
+    unsafe { Waker::from_raw(noop_raw_waker()) }
 }
 
 /// Get a static reference to a [`Waker`] which
@@ -45,10 +42,14 @@ pub fn noop_waker() -> Waker {
 /// waker.wake_by_ref();
 /// ```
 #[inline]
-#[cfg(feature = "std")]
 pub fn noop_waker_ref() -> &'static Waker {
-    static NOOP_WAKER_INSTANCE: Lazy<Waker> = Lazy::new(noop_waker);
-    &*NOOP_WAKER_INSTANCE
+    struct SyncRawWaker(RawWaker);
+    unsafe impl Sync for SyncRawWaker {}
+
+    static NOOP_WAKER_INSTANCE: SyncRawWaker = SyncRawWaker(noop_raw_waker());
+
+    // SAFETY: `Waker` is #[repr(transparent)] over its `RawWaker`.
+    unsafe { &*(&NOOP_WAKER_INSTANCE.0 as *const RawWaker as *const Waker) }
 }
 
 #[cfg(test)]
diff --git a/third_party/rust/futures-task/src/spawn.rs b/third_party/rust/futures-task/src/spawn.rs
index a515dd4e188e5e41abdbf859a29a34860dcdf22d..50f5d0d56acc038e6683db0aaf514eeb70aee5f0 100644
--- a/third_party/rust/futures-task/src/spawn.rs
+++ b/third_party/rust/futures-task/src/spawn.rs
@@ -126,7 +126,7 @@ impl<Sp: ?Sized + LocalSpawn> LocalSpawn for &mut Sp {
 #[cfg(feature = "alloc")]
 mod if_alloc {
     use super::*;
-    use alloc::{ boxed::Box, rc::Rc };
+    use alloc::{boxed::Box, rc::Rc};
 
     impl<Sp: ?Sized + Spawn> Spawn for Box<Sp> {
         fn spawn_obj(&self, future: FutureObj<'static, ()>) -> Result<(), SpawnError> {
diff --git a/third_party/rust/futures-task/src/waker.rs b/third_party/rust/futures-task/src/waker.rs
index 265a445d9193d7c98995b82bb9550bb6f858d395..a7310a07af2fcefb56b182c32a2cbfe392489bd3 100644
--- a/third_party/rust/futures-task/src/waker.rs
+++ b/third_party/rust/futures-task/src/waker.rs
@@ -1,7 +1,7 @@
 use super::arc_wake::ArcWake;
-use core::mem;
-use core::task::{Waker, RawWaker, RawWakerVTable};
 use alloc::sync::Arc;
+use core::mem;
+use core::task::{RawWaker, RawWakerVTable, Waker};
 
 pub(super) fn waker_vtable<W: ArcWake>() -> &'static RawWakerVTable {
     &RawWakerVTable::new(
@@ -22,9 +22,7 @@ where
 {
     let ptr = Arc::into_raw(wake) as *const ();
 
-    unsafe {
-        Waker::from_raw(RawWaker::new(ptr, waker_vtable::<W>()))
-    }
+    unsafe { Waker::from_raw(RawWaker::new(ptr, waker_vtable::<W>())) }
 }
 
 // FIXME: panics on Arc::clone / refcount changes could wreak havoc on the
diff --git a/third_party/rust/futures-task/src/waker_ref.rs b/third_party/rust/futures-task/src/waker_ref.rs
index 76d849ac1b92520844c15838a9fbc999ec39cc13..791c69012010e95d89655e52533f870eeae4dbf1 100644
--- a/third_party/rust/futures-task/src/waker_ref.rs
+++ b/third_party/rust/futures-task/src/waker_ref.rs
@@ -1,10 +1,10 @@
-use super::arc_wake::{ArcWake};
+use super::arc_wake::ArcWake;
 use super::waker::waker_vtable;
 use alloc::sync::Arc;
-use core::mem::ManuallyDrop;
 use core::marker::PhantomData;
+use core::mem::ManuallyDrop;
 use core::ops::Deref;
-use core::task::{Waker, RawWaker};
+use core::task::{RawWaker, Waker};
 
 /// A [`Waker`] that is only valid for a given lifetime.
 ///
@@ -22,10 +22,7 @@ impl<'a> WakerRef<'a> {
         // copy the underlying (raw) waker without calling a clone,
         // as we won't call Waker::drop either.
         let waker = ManuallyDrop::new(unsafe { core::ptr::read(waker) });
-        Self {
-            waker,
-            _marker: PhantomData,
-        }
+        Self { waker, _marker: PhantomData }
     }
 
     /// Create a new [`WakerRef`] from a [`Waker`] that must not be dropped.
@@ -35,10 +32,7 @@ impl<'a> WakerRef<'a> {
     /// by the caller), and the [`Waker`] doesn't need to or must not be
     /// destroyed.
     pub fn new_unowned(waker: ManuallyDrop<Waker>) -> Self {
-        Self {
-            waker,
-            _marker: PhantomData,
-        }
+        Self { waker, _marker: PhantomData }
     }
 }
 
@@ -57,14 +51,13 @@ impl Deref for WakerRef<'_> {
 #[inline]
 pub fn waker_ref<W>(wake: &Arc<W>) -> WakerRef<'_>
 where
-    W: ArcWake
+    W: ArcWake,
 {
     // simply copy the pointer instead of using Arc::into_raw,
     // as we don't actually keep a refcount by using ManuallyDrop.<
     let ptr = (&**wake as *const W) as *const ();
 
-    let waker = ManuallyDrop::new(unsafe {
-        Waker::from_raw(RawWaker::new(ptr, waker_vtable::<W>()))
-    });
+    let waker =
+        ManuallyDrop::new(unsafe { Waker::from_raw(RawWaker::new(ptr, waker_vtable::<W>())) });
     WakerRef::new_unowned(waker)
 }
diff --git a/third_party/rust/futures-util/.cargo-checksum.json b/third_party/rust/futures-util/.cargo-checksum.json
index b2d29fdc6b0e9aff16be99307a6473f9b28c8cc6..b6a78fc953232bb6a4e473b70fac32a4737aad4d 100644
--- a/third_party/rust/futures-util/.cargo-checksum.json
+++ b/third_party/rust/futures-util/.cargo-checksum.json
@@ -1 +1 @@
-{"files":{"Cargo.toml":"5c47cc6dd32ca9a93ecc428c3d85c704db3d851b017da957305bf4f6d825ae21","LICENSE-APACHE":"275c491d6d1160553c32fd6127061d7f9606c3ea25abfad6ca3f6ed088785427","LICENSE-MIT":"6652c868f35dfe5e8ef636810a4e576b9d663f3a17fb0f5613ad73583e1b88fd","benches/futures_unordered.rs":"ff5b88edf9eb221f72ab14580d1367b96c190d52f023ebff9f99a00fa6d163bb","benches_disabled/bilock.rs":"35d0740e11dcc4e0bc6dce594cfd56c13817cce829e51027a9905f1c855b0fd6","src/async_await/join_mod.rs":"9bf0341faad58403a6e62ad701234dfe03bd397ac474a949a4c367782ee56a17","src/async_await/mod.rs":"7ec8e3ce2e42c5be4625a04b645562d049977547306f04eb6637a4e4f17e5aaa","src/async_await/pending.rs":"083cc78fe066e1ba69adf4c6452ee552ff3fc8e325f40989cc87096f412bc3c0","src/async_await/poll.rs":"3cfa551feb7bca2c72eb5624731dee88ae8f9b9daab368ed59834b36174f5dfc","src/async_await/random.rs":"daf229cd01595d38ef0f6284865fe2f60ed3b8134f7a15c82564b97ff3a5be98","src/async_await/select_mod.rs":"6a708df67f6b6d262efd362ad7acef82b2c3a0e4a91a0b2c65df5d6fb9c89903","src/compat/compat01as03.rs":"ed5afcedaf9e2dd591828e2c31dd7ae96f8a26f628d6cefb8df301199361920c","src/compat/compat03as01.rs":"4cccf1efdab1ceb0f707616a6aa94c22d64b3c62ccd39bbdbcaa96de5ec1aeca","src/compat/executor.rs":"46ad23758e667e7032f7d42769950276b52ff7be1d4ffd45006a3e6cc4ffee18","src/compat/mod.rs":"10927f4b700387ca468a2cd6518cbbe5ec14b29b6cf74ba6071d4eabf86f49ed","src/fns.rs":"81b625324be965331a10c09086d7039a9b3bcafac1100137def8554c0379fdf1","src/future/abortable.rs":"b9997782e1d31c1a66d02912f7345669fe61abb6280e006d629a0060e76b8c13","src/future/either.rs":"e033d8a05e50f161ee46641d35bfef241482c63270fabf0c0ae34314f72330e0","src/future/future/catch_unwind.rs":"0ae8feca3e0358854c1b9da6807dd239eac5a8f84a56b660f3a00fb572cb2093","src/future/future/flatten.rs":"4aa95e21d6c9a42b6894b314de014e56cae1973c15f455a2cf5fb1cce142f54d","src/future/future/fuse.rs":"7f42ab4313e4ea6af0e3502ac6431ed356d3e2de4816538987da5a14aca5eb20","src/future/future/map.rs":"de607c2a4d80d2bddb590781c37328ddd294bb9d5064a9ecb99455244239b597","src/future/future/mod.rs":"efbbe361e018c7cfe0b28dce5480b7d60bd905219fcae5857ad029606cadedd3","src/future/future/remote_handle.rs":"a18f3ff0369cb2f7ee2bbccb46bc91f67f8e46317e23372f3faa6262a870bad1","src/future/future/shared.rs":"62d7b68dca18fdc520195768b34248dbda3aec64040f0732b62da3e70c2905d3","src/future/join.rs":"a5bc00ad9d1e35c9d035efce14fe1bb126695a937cd5bbbedc3d42919a1a000f","src/future/join_all.rs":"1b01c6eb7a71971897afe56aa96dd67526a73c3b6a17f9c52931c1b7c245d07f","src/future/lazy.rs":"207589a5bc9d7c12f015f02f63d84db65e9422c2e21ff641f7aabd00fe469e3a","src/future/maybe_done.rs":"238e47e82592087d8fdae1cba9d0dcc7c0c098db37a72d735f3fe8cd155e3dc7","src/future/mod.rs":"24f2814fc1ff238e70d99570cd57f4de8abeab9de2f797ebd4dea0c7b3b48766","src/future/option.rs":"66bd98555acd129c8cf4bcdd392f1ed20113af35857a601233afe13ad314ebb7","src/future/pending.rs":"0b8dc16550735fff67ea223368028b2f41753c1a7c8d498fd7d7689917b02874","src/future/poll_fn.rs":"fef68fa7acab026464460d78cda09b30950ab044c52af0916869d6feeeefe562","src/future/ready.rs":"ae4ba19d7b56b55a67847cdb9c703b4057df46693ad3bed45013185e2c8582a2","src/future/select.rs":"ac311b2069f6fdb8c0686ed16161cff84f62827f62c09e999cb41086961e7b4d","src/future/select_all.rs":"1ac0171dc8bd0b875d4fd06ecd55744492702d15f2ce52c86cf7cfbd81f124c1","src/future/select_ok.rs":"671f2d072a575558403374544827695b9c03e75e1023c8a317bfe4e750391c09","src/future/try_future/into_future.rs":"f80bfb9960bf15ccc59af708e94fb09f99a402013d9b12cec56729e5e07c6b95","src/future/try_future/mod.rs":"c276f07c72534a374ac3ba20d8e3bd04d6acbee4071fc1e032e904bd143d2a47","src/future/try_future/try_flatten.rs":"c6a35e83557119ed654a9f597b7da5a24d2c68365275ed8877d765301e85e8e2","src/future/try_future/try_flatten_err.rs":"5ff35b1eaf59fb02dae3cee9d38991c7d550db21fddb76c85a74ab6f8867b02f","src/future/try_join.rs":"97f93006bd910419991450bd021c205510bc2c86258d0362e0825114b0b168a1","src/future/try_join_all.rs":"28503eee3e8b372076d5c69271a35d0f51b2c5ca935d68d8842b1882be878709","src/future/try_maybe_done.rs":"3ff2cebec8fd112deee178875ec8e64ec71aeccaffb51c62cd4c069526d09eeb","src/future/try_select.rs":"181e7dddb008271e8340d68be9501d1c84fab81aa923ad1457a230414426f97c","src/io/allow_std.rs":"cc1397c155c1cfd0fa719d1f31ca30b6cdc9fcecf4a6559421250ad7f96d99cd","src/io/buf_reader.rs":"031cbc495e52da63a31a66fd3b88f39cd037124f18b48f0ef7812ca0b0c5bf23","src/io/buf_writer.rs":"668aa5a086b82ef5c8478995c6992cb3cb9cacfca157f517f4e3154247cad17e","src/io/chain.rs":"4e0b3e3b69a93ef3d8841ea4396b8e4e7ffe102434b9d79087b5d13458b32e1d","src/io/close.rs":"9832210a870637198fa58642cdf2779afab71f2e31a9953e663fa6854bd73ac7","src/io/copy.rs":"546013afa0267fa6827a38456c3a5a24d30337b142562e2ad7453f0fab37e9e0","src/io/copy_buf.rs":"d83c48af60f47ea8450e0f9f66e5f3b807ce9b45837add04d86389ebe92a8b6d","src/io/cursor.rs":"ba8fee9dd705ecff03a224b4b20af7be594c20aa3d044e18df70e9f6771e0adc","src/io/empty.rs":"5c16ca08f04f08f06ee8e3a8c08a41497522ff30d25bb7b5d6fd538fe029c476","src/io/fill_buf.rs":"82ec73d8f2a8bef21696b03f6d77796c7817f2b851ecedf773255a4b84d83ed6","src/io/flush.rs":"215b1469c15a1b5e8c4bfc734ecd3440571aebec2f4d06c3208d4cea3a2f8ad5","src/io/into_sink.rs":"7c00b19bbd4e78c6bf25fe24034694091e38ff204fbec949fbae70a25a7377b1","src/io/lines.rs":"c91e6c766cea3cd92f0a08d6e9ec47b2ecc52175f729bd3df84e1982e5b0751e","src/io/mod.rs":"44fcb38116317b254c67ae8da0ce5826b361c0c53853d590c9881b4ef35cbd31","src/io/read.rs":"4ea675a83cec98a22c9c4731ff980209f0cf67f63c71871cd1deed53c1266345","src/io/read_exact.rs":"d8bf936a58ee857e329a4bf3714977bc349486bafd2daa3576e7563e115106d5","src/io/read_line.rs":"aa3ad91b007903bd00b2d3c7a6a2216161642c56f37fce0fffb49c44e9e29c68","src/io/read_to_end.rs":"1b3b285a198d0efd41d984e9fe873556bbea27c452c3dacadae8b23a4e9f818a","src/io/read_to_string.rs":"6f24760224f831ba892221814a03a43bc312bc9c3a04778d63e64e60e673aabd","src/io/read_until.rs":"354507ce95242a735940f0aaa6ef11cc7d6d0505ae148f05277ce6e7537f168a","src/io/read_vectored.rs":"bd7f442c92f2cb320075d0983b0d08d51c23078898d72e6c2857cf6c7ad4cec7","src/io/repeat.rs":"f5e41529699076687c37d52ae673ea2b38a2e306624526a2a9d4fe9794341bf0","src/io/seek.rs":"9863e9fb6495eb6e1f8c45c283c8a6993b9bdb1462f75a3e525e135c6840dec7","src/io/sink.rs":"30a503631d196e5da92c386d0afc1af9656a5f7682456cfa2489a2c30a05cac5","src/io/split.rs":"b34e57385bb16cdfea99e0d117bf0d5ef1618d5103c2784557043cd5a5024562","src/io/take.rs":"3f5e61eebc2b2689ef36d7ef5ced1d2b92a5cfbb8395f9667308bcef453b6ef4","src/io/window.rs":"32a186c79ad4f2d10e5643f5912f5487d2a5a9b5f71078b09bf2ffef3da34083","src/io/write.rs":"60670eb00f999f2e2c43b099759a7fb030325b323744d88c9d20f75926ec30df","src/io/write_all.rs":"c88930fd23c88cc01fef2c6118d53d33996c011c4abf28778a27646fe1f7896a","src/io/write_all_vectored.rs":"0e2c2d8917d92f49cf77315805917b77efd820f43176a6819e132ee4f9da8556","src/io/write_vectored.rs":"bc98ff4a709cb75cd9ffedefa8ef251089a49906b98e142d76447ddf4ac098bb","src/lib.rs":"4de076395ec9798f936c06e1009a8b3f9f88f5cd66db4207b9c0f3c6ad9ad576","src/lock/bilock.rs":"cbba1cc14ecba08cca5b785ea8361d9718430ac4b81c3243a8a9a1e2815061f8","src/lock/mod.rs":"0f5994d2a8addb1b331477739a216bc66584d15d8e312da27b0482b5f8b52b96","src/lock/mutex.rs":"873859095e5495793df4e09c3fa369a3963b0b84e6138a7dde416c03805c1ebd","src/never.rs":"2066481ab04921269cfa768cb8b778a035ab6aa49ec404d9ac0aeb07a4bf6094","src/sink/buffer.rs":"309f4ee9beb6cea9ab6fc42078e863cacd4d9413fdcfdf352be20dc46252b601","src/sink/close.rs":"9caf7b84e167da72674077729d9023ada96d89573d67c2936ba21276addf9d87","src/sink/drain.rs":"c9ed8df8216e83a7153f10a57ce05945ff2c67b0b91435014afc3fb0ac7090d5","src/sink/err_into.rs":"c6c524e2900bcae8627ef2dc1802ecbf398c930d7281d0b7bccc160cc536f09d","src/sink/fanout.rs":"91a28bf3b1994d29d120283edece99f9e634e1f0c8696ff8a133862cab461072","src/sink/feed.rs":"a86f0ac7bc6d6c6f85f50e1b11de9f0c96ce20605155d2fc0a6b3780e65eb563","src/sink/flush.rs":"3b8b43040577e9976212b44bd664d8f108bfbc6e0d90129363a9b670298a0446","src/sink/map_err.rs":"4a6153fcb199d43a54bc2f2f1d05b5325acb72a2d1ec0617cde1283275ed10a0","src/sink/mod.rs":"50314d2c0b45987a35ddc66a306f3ff0f985f090739c1e55bcef171e572cf7c6","src/sink/send.rs":"e2580687ab8a2276b75ef1361cce324c9f9ad49fffdcc8bd1c55c2650d7f97b9","src/sink/send_all.rs":"6cb76d32481947fa22448e7c482b5be94ca70155e0ec8d05043168011a808848","src/sink/unfold.rs":"de2c6a2a979342408c0049404adc77a84cd1121a10e4416139e9193802812bf5","src/sink/with.rs":"b7be549a6d35e04bfab25e1efd738bc21b85ce09cf7de93096c8f8d5287f5f5f","src/sink/with_flat_map.rs":"0e255d29360b757ba9fb23a133f385db266e33bea7a97deef496511802e802e8","src/stream/empty.rs":"ea81fbdd9e03f94064c5338f559c76a607a939de3aa498b8cb061926bdb8cca8","src/stream/futures_ordered.rs":"684e9abadd893dccecf85c5608c15f5f5c22ca61499d4ca09c366f32eec88b91","src/stream/futures_unordered/abort.rs":"bdfece9f91accafd5122be36d628c37c5b219ac0eecec181267840fbb1e95a45","src/stream/futures_unordered/iter.rs":"34e8f8c3ba19a60465ee3d1ab363c2b1b6493904955fc98f93f2d279465f3f25","src/stream/futures_unordered/mod.rs":"6c2726c5e3528df60b66db3b0c62839140805a53a4786841e045cdeabc4683b7","src/stream/futures_unordered/ready_to_run_queue.rs":"97b1ae664c56697f861f6a37a994ec86a5b2ca83226c50c2948cdbaf379288ce","src/stream/futures_unordered/task.rs":"5cce7a18fa5a7bbfaa29a2de7af7beae707a3945e6e9f5d6121fa493665c5f33","src/stream/iter.rs":"ba511a7799d8adc4b155834e821c51b7506dcfac7358dbe1fa00b3ab3c0c716c","src/stream/mod.rs":"7d899c1fb38610f01e1007c3f9e4acbfaf7e549e70100f04e44d357fda6d08a8","src/stream/once.rs":"53cc4dd961a14291ae5ec8373f8fe1322939733ea51dcce3a9333d1fe351c303","src/stream/pending.rs":"db32b36f1f20c0c5a014df2a128ddd8a793e029403687a17bc7b1b9552686f61","src/stream/poll_fn.rs":"eb1acc01131f67465bd93c362406cbeda17d0d0c2d8f81f5379f393e096b0c19","src/stream/repeat.rs":"fae222f2d7881365bfabcdc99c5ab6f0e555bd35934c69da25a9e901ee1593e6","src/stream/repeat_with.rs":"8a2de4927faeac2b8a24c1305b5da948202dfac88f7db1b5a3c27e12244b2dc2","src/stream/select.rs":"29623db5ba3fa5d815fef00cc8c43bf70ce61776180c9189db2372020b999f6b","src/stream/select_all.rs":"8a7e0c5a995ca9dcab9a1b98c433ff4eb23865c07b2021f4fa013d66e1220788","src/stream/stream/buffer_unordered.rs":"04ff51ca7c697a68674834961dcdc366c61dda253862e148ea157c6096b277c0","src/stream/stream/buffered.rs":"1d3ede946056f80ba89b7fd900cf1a7fa0927b1244bdc3138cf9f625ce820cb6","src/stream/stream/catch_unwind.rs":"86ea00dd78bb392068bc0562a856642e68e279f8c009dfbabe28f62fc63d5c0a","src/stream/stream/chain.rs":"0b0bce524a08c08ed7b12af48a152327f72f1bd2dc48f768957c9504b8518842","src/stream/stream/chunks.rs":"5c30b89fd997b17aef281eb599b725f6bc27e445c520767d09d22524a55b23d4","src/stream/stream/collect.rs":"5cce3f06b323277a823f10df42ffcf1b682807b897b061c0c80afbd195ebdba9","src/stream/stream/concat.rs":"9016ed00e7359b9823f8fd709395a455fc5a504a027ae569df74a552d53c00d7","src/stream/stream/cycle.rs":"a9e02dcdd90b7dc333ff7a72ee738b85f488c22220fe24e4a7ec6d7c678f6f0e","src/stream/stream/enumerate.rs":"5692ead51d99742649dff1e78e42b5ef70e18dbbb25b40a86775da867ba74f4e","src/stream/stream/filter.rs":"7b8842cb89895e87b88cfafd1e49bdf59410439071e0740d303419dbda2079f3","src/stream/stream/filter_map.rs":"e502d9145f6bbfd596026fd03bf726f01bf39249eef92a105cb3a1f1abb5f0d7","src/stream/stream/flatten.rs":"69493fc106a1447abe109fd54375bb30363f7bc419463a8f835e4c80d97f2186","src/stream/stream/fold.rs":"6e1191f4b34ef0f63f0026cb5f74866629113e51d95cbec8d6abb36133934572","src/stream/stream/for_each.rs":"ba5c644146dfacd505d04a21f118912a5a5a736c78276fbcc13af15d99be2cab","src/stream/stream/for_each_concurrent.rs":"3beb23f40e09a5b274ceb6fa69071f281cdae0d07cdd1b0e07b7822f4723d2ef","src/stream/stream/forward.rs":"ebcdf6b1dc38d473e3ed78913202037b61d2097c39803b4c8bf3f96d057ce103","src/stream/stream/fuse.rs":"784b9d89c5ed6a4e3a611b01bd36b422e8c4c8429094a73929be777b5b7445e0","src/stream/stream/into_future.rs":"8028efda9b416ac723f47a3beb53fc8c1c9ff5b05c3fb16eeadbc07a2e31c5f4","src/stream/stream/map.rs":"a36fb89b3fb69e4d9e51912ff91b8a8c03380cf743e7090736d5845121409253","src/stream/stream/mod.rs":"0768b60c4870bf5c5117e991dfd832a6275370caea24347079a652db147989ad","src/stream/stream/next.rs":"fc1734de6295c8b2d240b13e46084a0e9a6eff803c24ca4e4d267f56fba75554","src/stream/stream/peek.rs":"632488bcb36ff4d9f5cbf6848a89e6e9113a8936035836e9b97b0c23b8d9f199","src/stream/stream/ready_chunks.rs":"d8f52869c2b01df2aa93136914341668016cde8d268151bb8bd222a8b03bdabe","src/stream/stream/scan.rs":"402e6b90b0ec452d1cec182abbc7c687fed27f2bad39b8e0b2fac892367dfa40","src/stream/stream/select_next_some.rs":"bcb3e2ff8b2c3dc1d95ac627b97e31759978762781dffd6f9b20212a99f06a4c","src/stream/stream/skip.rs":"13d24094172d65ec051db3cfd336541a661e71718ab8e0ecadbb0bc97e45b628","src/stream/stream/skip_while.rs":"54e49e7dd44509d68b409a8cb5d1104a924abbecdf31313803895d209c6f425f","src/stream/stream/split.rs":"9298a52d17865ff5b60fb152cc3bc9133139f7f30309369f89a5c9b5537c2f7c","src/stream/stream/take.rs":"a7cafe951ca4a13e9bb2b1b1c9654820245c7e0bedc02fbb4e52ee30b2ceee1f","src/stream/stream/take_until.rs":"a90b65d89a1aaabf0888339dafaf518bf9651d9d5c87c41ec5b237b4d580d2b6","src/stream/stream/take_while.rs":"d378c24236db70428ddd598f59b1418ee8bcfa0a699839df8befee67284999ca","src/stream/stream/then.rs":"e3c207a38b41ec46e59f0a9789c53cf52c49aead6ba2ea7902f1367e2f6ef99f","src/stream/stream/unzip.rs":"752b774d8f32a575091233ba568485826c8758067b7a349e4c56e52d845d1239","src/stream/stream/zip.rs":"49a19d77f92fd0e5c3662bb82a6946d94b7e6d70f3c08bcb9c4ddacf0bbaccf0","src/stream/try_stream/and_then.rs":"a909cf70e64febaa425dc03e50a9a8bd100c49b0543efffc7a13de1d32bd0cb2","src/stream/try_stream/into_async_read.rs":"7ead783215bdc025709acfbc42205a299cdd9b10c65467cfe6ac875dc6601030","src/stream/try_stream/into_stream.rs":"95bbb5226930a8874b7a287ee1a2331ddb28e1eae7458c20a18b1599c339e95d","src/stream/try_stream/mod.rs":"7bda9a74003b389c6d31f832bfd16930caecbf3e71ab151092166378706240d1","src/stream/try_stream/or_else.rs":"6f84ff8fdc667fc3340f5e92338e9a3252e2ff02afc8bdcd85c3cff9d7b2cf0b","src/stream/try_stream/try_buffer_unordered.rs":"a35e5179841627022c0ff886d6f65720bd8462cfda2e0c6d41cb364ef595570a","src/stream/try_stream/try_buffered.rs":"b056b3e3c02e6016f9df274b6fc9926f244c4ab1e91ed740ce8a08f79205bbaf","src/stream/try_stream/try_collect.rs":"5561309b246bc983f25a6c1c54f538a0268aee462b09b7533fdc285ea8b6eec4","src/stream/try_stream/try_concat.rs":"b053ff9a890386e144bd3d18355cd418531dd284f73c22e36d41c75a087913a7","src/stream/try_stream/try_filter.rs":"8f50c05878b65db73fd94e51ed2d7fc8a147630042614176016fee56ce5e6a1d","src/stream/try_stream/try_filter_map.rs":"73141c377e511b78fad4446567895a4b24818c7de6695903c71f83027b39da5f","src/stream/try_stream/try_flatten.rs":"e05614d86a27ab8386476eea35fd424c07e5f7f99cf0401d63a6655eb7ca1247","src/stream/try_stream/try_fold.rs":"9a5a88b65d91237344366cc9451ba833818e9584d174e4e417db3812835835a4","src/stream/try_stream/try_for_each.rs":"931b3a1f11982928d9434176e54a055abd5a42a1f486c1bffa2f634b35c483c2","src/stream/try_stream/try_for_each_concurrent.rs":"9c2562173303371682e688810d1ed1a4a5667f232c5eb647bd4e0f2669641050","src/stream/try_stream/try_next.rs":"019b5e2e3dc0f222c97608264368fd8538518e4664d3bcbd320aa1157a2ddd55","src/stream/try_stream/try_skip_while.rs":"d144d89b5de8e471f3387fa57ac1b35d385da812eaaaff55af508c0a0d38cd17","src/stream/try_stream/try_take_while.rs":"0382bf4192e5fd8b62209bb65fb562a84fbd7a363231717d26509af8dbe68e9d","src/stream/try_stream/try_unfold.rs":"9a0bc26e931d674f1896bee1a1201a101c49fc83a3c96d4a2302d669031f5cf5","src/stream/unfold.rs":"db0ddcd9471d300b8a2eead0553fa631d4b6991b816d143c71c00b9b36f21776","src/task/mod.rs":"d9521b319af905e3a24947669a5c96035854ef5c4ba36b48578f903d1bcac5ad","src/task/spawn.rs":"26bbcf1d65e1467de0ecdad2b56f464a510cda7c1933427d69a1b50459836489","src/unfold_state.rs":"ffe848071a99d6afcdbe8281a8a77a559a7dde434fc41f734c90e6b9b5d8a5af"},"package":"632a8cd0f2a4b3fdea1657f08bde063848c3bd00f9bbf6e256b8be78802e624b"}
\ No newline at end of file
+{"files":{"Cargo.toml":"4ca92285deef3b5c18e79c8784d6fe2b3aa248228eec5eaca85d56caa0e4031e","LICENSE-APACHE":"275c491d6d1160553c32fd6127061d7f9606c3ea25abfad6ca3f6ed088785427","LICENSE-MIT":"6652c868f35dfe5e8ef636810a4e576b9d663f3a17fb0f5613ad73583e1b88fd","benches/futures_unordered.rs":"5eb8280be8d8fb7bd5fb103ce20db10f618f47e180a402105e0d5e9f8c9fe35a","benches_disabled/bilock.rs":"ab8b47fba5cfa5366477ef1034a042efde9b0aff6b77110d1f3a2715ab7508e8","build.rs":"87cb3d0349b302eadc2fc783fdbc6366a49d803da3a71e6dabaecdc309eafd02","no_atomic_cas.rs":"1b1d0f659624ba744e83a20204f4f5b2b658bb7c934543851c2d569792b4b825","src/abortable.rs":"d88dd2501ed379b3540bd971d367b4629755d6d9f264e7b54ae59eea0ff83623","src/async_await/join_mod.rs":"e923d2eb28cb3525022c17235ebbe937cfad77aacff5ede3e3da604c09916fd3","src/async_await/mod.rs":"e75246d6e15f052d8f68cfa9a4a25f25b595a70dd4412b29a5a5d1ec23d3c120","src/async_await/pending.rs":"7971ec1d5d89ad80390e2a0c51e396257b2e78f1436cce79ea2b55ac2f13b328","src/async_await/poll.rs":"440c19a89fd42b12da09ff48a69523b5a8a5baea0bcd2f860589a0ab996ed781","src/async_await/random.rs":"daf229cd01595d38ef0f6284865fe2f60ed3b8134f7a15c82564b97ff3a5be98","src/async_await/select_mod.rs":"bfcab2ac3e89e03a3639154d96067a32b95c0cef9c9c5c8caffc8daef2cdf4d2","src/compat/compat01as03.rs":"2af3b3d01aef53dba521f34f6be1cdde34923851c283eeb6fcbac001ef98aee8","src/compat/compat03as01.rs":"ccec9ddf4e9a34693f0729f4ba05f33a5fc87c57469458686f6f85fa5b7e6ca8","src/compat/executor.rs":"a0edd7baa2192daa14a5a26bf53bd229defaeac538d2ec771c60992c6dfeb393","src/compat/mod.rs":"6cf3412f6a3f9ee8406118ea75de65468a83febc6ba61bdbad69261f0cfea02e","src/fns.rs":"f8e396128791169098a38a82c3c28aaa6dd5d40718635f7cc30b59b32f7110b8","src/future/abortable.rs":"373ce61c0c7c31718ff572113503bb88f55e3b49ed5d028a3dfafd69070f44c1","src/future/either.rs":"572b24dec74db18a390f13ed044b7fc000632728315c87ea1430a454551f7546","src/future/future/catch_unwind.rs":"08b0ac049cdee28325d378209aa5bb4d91b14a29ddd9c2b0e5c661b61f9cfcfe","src/future/future/flatten.rs":"5bf9846cef8dec5dcc38b992653e11146bc149a0d3efc09b1f8268bd29de0b2b","src/future/future/fuse.rs":"6531a95dc1917b2a5724b35e364faa741143811afc654a45c360111e9807864c","src/future/future/map.rs":"de607c2a4d80d2bddb590781c37328ddd294bb9d5064a9ecb99455244239b597","src/future/future/mod.rs":"ecfac09dcba801cede7c58acfaa76a9ab76d26a3f4c968d66c2a49caa57faefe","src/future/future/remote_handle.rs":"2ae17a409569b32c78e20026a8ecdf667352c2597a4a0a8deefa4761fafcb223","src/future/future/shared.rs":"ebf46b4bf428676bf553015e384f7f41da03558481aaa38deb1e8a896d212dae","src/future/join.rs":"38b55fc7cdbbdaaa525e51f8ce09783dbbcb65eabfd7de9f46610593e0bbef17","src/future/join_all.rs":"619bd513354659c935e85bce6097f5208e180845383461469d8578926222e1f2","src/future/lazy.rs":"d161fc4108a97348c1becbbd5ba8fccb7225dcf1d81c097666f5c8b40718251d","src/future/maybe_done.rs":"559e41cb170f9fe7246d2a5b112527a9f9cbca63b8a5a872b3aa9c861f70f307","src/future/mod.rs":"a0e33d143459325d5dcd20d23260e38034ec9dc58617215cfa96387263c89799","src/future/option.rs":"a2253c43a558395e7827a568ef341a6bb76a4074dc054804e84be38541b77dda","src/future/pending.rs":"86598a5d5ade7c0416566deb280150bac34bd4703c997d2c7af572342d8d6d02","src/future/poll_fn.rs":"8e54bf57d60e01d496ae31df35e0b96868f4bda504c024a14f51ab723d67885f","src/future/ready.rs":"c9860ccd8ac529f44f66dee73ca9b9d7f1b1b3e5e9e4dc70c59640c752553d58","src/future/select.rs":"a582b1ed9c1e6cd8dcaa80b5f45e2176ed4a1740fe303f7143e29cab8e0dbc22","src/future/select_all.rs":"179b8168370e2c7105e348fdfbeb965eb746336d9660aa7fbc9185d681ae8c2d","src/future/select_ok.rs":"fed28e1fd368cdd465d297a84ea9436a00757eff4b34e592d94d7747b3bf4996","src/future/try_future/into_future.rs":"d966bde7b06a88443f0efd877e95f91541778c4e713f3f4b66e00ca5d3f352b6","src/future/try_future/mod.rs":"4733167d93e8f728e87f79b7d4dfe66de6afb306735ca76f9f843270286b3f6b","src/future/try_future/try_flatten.rs":"16c02e1780bd312b8b386e41c1d9dd4bcc4e8ef10f26007364f857b3adcc6e99","src/future/try_future/try_flatten_err.rs":"130f3fc3fd95a19f4e4a50e69301106fab02f77d0faf3aac9c473a92b826c2ca","src/future/try_join.rs":"1836931f8ba32da41c6810e6acc0ea2fee75b74b3153e760c4542cb12b220540","src/future/try_join_all.rs":"d4f262e80bb5347597c75b25de3c7784ffb4bd766227d6dc70cdeb77a38f4a5d","src/future/try_maybe_done.rs":"1cce46b2ee43ad51b7c5f9c02bc90a890af32bc549ce99098a2c8813508051e1","src/future/try_select.rs":"2e1b7e0b0cb7343f766fade87269093558db206f7fbe7dddfa3143885e17bac4","src/io/allow_std.rs":"88a25cfcd436a7c113d781d81b8d7b4c241fb350d2524df66d9c5ae0277b30b4","src/io/buf_reader.rs":"54bef22f08e446944537575b9f4ec2846c4cde5e85e8fbd1afb55d2cfa7e05c8","src/io/buf_writer.rs":"1b62cf025e7f0823114a1269465c4aa8ea9605717d8736a5504bfb500fff7a0c","src/io/chain.rs":"c2c1b56201f7f75f5e6f980fb1cf1733e124e891ae844b411f2f19cc90d99531","src/io/close.rs":"9832210a870637198fa58642cdf2779afab71f2e31a9953e663fa6854bd73ac7","src/io/copy.rs":"cb2466dcd7ea8bb1f07d00c03e66ed55abf71fe4be6937adc9f533ef9d99fb2d","src/io/copy_buf.rs":"e9a5f6aac8375e298bddb332f23d8b626d056ce452b58f772a05df7e2cd326cf","src/io/cursor.rs":"612bdb8b4055d26816fb0e4c3e9859b06b3d08c99e4a27ed4946c95e219a29ab","src/io/empty.rs":"5c16ca08f04f08f06ee8e3a8c08a41497522ff30d25bb7b5d6fd538fe029c476","src/io/fill_buf.rs":"073e4acb637117c5a09c5d90c9e32348b4bf859dfdc36bc005e3597052046456","src/io/flush.rs":"0c9b588dfd9da039dc123ba9448ac31ca21ee3da0a164a21f6c2c182183d43e2","src/io/into_sink.rs":"2e769734ddffba120ab1604f9b2ee1ad67a1d97c7fd0017c72644eb2b1c96f78","src/io/lines.rs":"ccfa24e212a610aad0c81042cfa64ada820c4305ba0e911a2c16221d7867468e","src/io/mod.rs":"fc69a87977354daac4fcbb5bbaa1a169e6f01d97881f50b8c56ef8450bc047a0","src/io/read.rs":"4ea675a83cec98a22c9c4731ff980209f0cf67f63c71871cd1deed53c1266345","src/io/read_exact.rs":"d27d5ec082ccb1b051d1292e029e398926a164c82e1f0c983ca9928410aa2abe","src/io/read_line.rs":"a3c62ca2034089a22ea9567e0b3cab0dfe09309782fcf151d92311a77223e37c","src/io/read_to_end.rs":"5e9e38dc087623dac5a3ae3ad329ed44ffe4f6205a78e546adadc3ffb76703fc","src/io/read_to_string.rs":"2c073d05f0361acda1f0172b24fd4c5da61840ac925a5bdfae9111c697759d1b","src/io/read_until.rs":"354507ce95242a735940f0aaa6ef11cc7d6d0505ae148f05277ce6e7537f168a","src/io/read_vectored.rs":"bd7f442c92f2cb320075d0983b0d08d51c23078898d72e6c2857cf6c7ad4cec7","src/io/repeat.rs":"f5e41529699076687c37d52ae673ea2b38a2e306624526a2a9d4fe9794341bf0","src/io/seek.rs":"9863e9fb6495eb6e1f8c45c283c8a6993b9bdb1462f75a3e525e135c6840dec7","src/io/sink.rs":"30a503631d196e5da92c386d0afc1af9656a5f7682456cfa2489a2c30a05cac5","src/io/split.rs":"2aa567452b713497d5b85813980b69e888aee32be14492c92404d261fd50eb09","src/io/take.rs":"1fb2eee12ea10fad0018b69a1f9eecc7d9ee53a3e4bb3cce0762a66655b275e1","src/io/window.rs":"295d7dc18ad101642003cd67687242e4bdba11552cfb7f18c521cbff369e6f71","src/io/write.rs":"60670eb00f999f2e2c43b099759a7fb030325b323744d88c9d20f75926ec30df","src/io/write_all.rs":"c88930fd23c88cc01fef2c6118d53d33996c011c4abf28778a27646fe1f7896a","src/io/write_all_vectored.rs":"3f7803245aef66710f816fe7c2042b04e9536788b2b9339c63f93c21144372e7","src/io/write_vectored.rs":"bc98ff4a709cb75cd9ffedefa8ef251089a49906b98e142d76447ddf4ac098bb","src/lib.rs":"d6d8ba3aa3c0bb8cfb16623b769adc0ed4e062fd85458371d47c2765056a8838","src/lock/bilock.rs":"f1b955cb2e10c906933e63bbfb8e953af634428ce15faf3696b07d11da0cc279","src/lock/mod.rs":"0f5994d2a8addb1b331477739a216bc66584d15d8e312da27b0482b5f8b52b96","src/lock/mutex.rs":"43e59e11994d1c41c6a372c1f34f984c4f22bfa91f6d6e8114dd80d693088865","src/never.rs":"2066481ab04921269cfa768cb8b778a035ab6aa49ec404d9ac0aeb07a4bf6094","src/sink/buffer.rs":"855dc313d8af6b2f3b01300ff501bf8c64bac45b41e93c59ed7e3ba336acd400","src/sink/close.rs":"f2f31c884f048163abebd4f5a877b7b4306f7d02beae428325636fd00ed42ca9","src/sink/drain.rs":"392d9487003fcd55a3373c3e2558f6549b9633b82fc08b5a665a573b137ae9f7","src/sink/err_into.rs":"ced2998b2b0b792d80f7543523c9e07e8f5d20a4336cae93084b995e46671b15","src/sink/fanout.rs":"66dcde056e0bbee4e0074d331838ed2743dc872ea1597f05d61970523dc34926","src/sink/feed.rs":"64b9d296d37aedde37e1421c459ebcd9a7e8814db905996996167850124f3b3f","src/sink/flush.rs":"fbba344f428ca7636541ba013f7db2ece480b404a9e0b421c5537552d61e2492","src/sink/map_err.rs":"0f68f444ef13fe7115164be855c3b7b1d269e1119e69fcdad1706988255641f1","src/sink/mod.rs":"37cf379170f3099992eb59f3181be4c4e4a5c2d3581dbe424d22ab360840d321","src/sink/send.rs":"56aaba9aa4a562e0af39473a5779206d91b0acb1fced4fc06cd8b959d1897524","src/sink/send_all.rs":"a8e4956604fe73e321b0a3896c2018bc5c27149f2862f8406112db140b3aa2dd","src/sink/unfold.rs":"428080b76213b504fcc981d2f05840f1a93c8db305301af1cf5852b6c47c4be5","src/sink/with.rs":"850cd3b96304df1f38360a0bc60b02d485535e399ef7642acdd9add7876867d8","src/sink/with_flat_map.rs":"5e0f527b33ee8f1cc6a6a46d45b6d74dad5c735d88b2cb24e1cb34fdc6ef501b","src/stream/abortable.rs":"935d79aa44d793f4abe87ca27a9e4a20891500488cf942693cd2756d65b3aab2","src/stream/empty.rs":"5000c856186408a17f68bbef432d4a1a3edb7fb5a07ed8699342fef04b10a181","src/stream/futures_ordered.rs":"46217ed3802d052724a4a3166370f74e6d5fcd248d6f983caea10bc3335a1f0e","src/stream/futures_unordered/abort.rs":"bdfece9f91accafd5122be36d628c37c5b219ac0eecec181267840fbb1e95a45","src/stream/futures_unordered/iter.rs":"e8862300ddb0504090c059b3dba2425af6335874cb6ef393fef26e87788b6d3e","src/stream/futures_unordered/mod.rs":"95afa64d560117df256afc8b3930ac1f491250087677b042a0e1fa75292a0a12","src/stream/futures_unordered/ready_to_run_queue.rs":"6223c67519c1ae35cbc449dd5654fda422aaba61a2344cc0b190c73b4b1e9f80","src/stream/futures_unordered/task.rs":"ab2de99b2a42c1da70d56e4be43c0ef72e8d5a4504adc0f870f8d28afd332a37","src/stream/iter.rs":"609fa821a460e901a54ae51f8da58220881157cef02b8b7b8c9e4321c2d05a23","src/stream/mod.rs":"e2946061d0ea5b3572079696f8b4fd361531f6ce83a076298c00755f3f3b180d","src/stream/once.rs":"d7b70adabad1f10af711ac3dcef33fd4c287e9852fdb678406e7ff350ba8fd47","src/stream/pending.rs":"84aaa15c8bbb17a250da5b1b5f0c7f6717410915d63340a3fcbf098bebe19d6f","src/stream/poll_fn.rs":"35952ea514b8aade14a3934d7777006475f50bbf0c5b50141710e31637f980be","src/stream/repeat.rs":"e4e4a9b6f2fca72bcbf098c3ac0c4a41323a840741d4dce9d9416464b7e8bd0d","src/stream/repeat_with.rs":"525780d24f3f99152b879765ca6eab99bcc0c757dc6654b6635c099b93ea654d","src/stream/select.rs":"0ed166a3fe703bb1f98cc3c7f595afb942dce2d1be171c3735b16e5e27850506","src/stream/select_all.rs":"4358fa26cfe8c1b56f19d077b841bbdfe22f7adc043034fd6313b004e94e310d","src/stream/stream/buffer_unordered.rs":"66c3f4bd2fabfbdf6a4033dfaed44dd0262b68e6533509029c984ae037e35392","src/stream/stream/buffered.rs":"eabd0c0e50eaaaf0a92a7b39fdb5b77e068bbfbbfd5e216a09c3a6e0c1fc102d","src/stream/stream/catch_unwind.rs":"b2e801ff744d5d9e17177ec1156b0ab67bdd56b94c618ed8590344ec8a0f35e7","src/stream/stream/chain.rs":"ba1a206b3ce0160186021f5c1e4c95a770d26b843e3640e52609a2facaf756ac","src/stream/stream/chunks.rs":"d3aaddc05779ef70e2f0e59570cf6d5a1d231ae4885c8b8b2e4813fc02832562","src/stream/stream/collect.rs":"977ed1970b46029517ecc45f4af924b8e585d3770f01b2a0d2df0e01519ca50f","src/stream/stream/concat.rs":"171ea941b45c0295ed978c3f318a449ea295e33cb4ea82c764f4e9e7c48ad5de","src/stream/stream/cycle.rs":"ed7e3d15e7b1adec5ad5789b0d3186b5995a3353cc974fb7f41a72f6d8ad4cbb","src/stream/stream/enumerate.rs":"fc7565d21d39565790859eeac9ae8dd74123a9d15b88258d3abe894f1876cc39","src/stream/stream/filter.rs":"3dd080914e6770f8790455fc9cbedf30c5f44a589ef99b19112344c75f9e9042","src/stream/stream/filter_map.rs":"3a8a3e06dfac48dd3f7b6b1a552a51a3e31ea943e012dd35729d461a1fcfad80","src/stream/stream/flatten.rs":"69493fc106a1447abe109fd54375bb30363f7bc419463a8f835e4c80d97f2186","src/stream/stream/fold.rs":"75d61d4321db1bcbbdd1a0102d9ad60206275777167c008fc8953e50cd978a09","src/stream/stream/for_each.rs":"07bca889821bad18ff083e54abe679fbeb8cd19c086581c2f2722cba6b42263f","src/stream/stream/for_each_concurrent.rs":"4e1e7eb3d4ccfae0e8000651b75834e2960a7f9c62ab92dba35a0bdbbf5bbb21","src/stream/stream/forward.rs":"cd024ba1a3d5098d3ff2d5178a12e068916cc4307284b00c18dbc54b554a5560","src/stream/stream/fuse.rs":"061c5385f12f80c7906cb15ddb8f455ced6ce21d1de9a97de9db2616407c0cac","src/stream/stream/into_future.rs":"b46ad45cc03ddd778a9ffaa0d603c8ee0b411f49333100160959942cde9588bd","src/stream/stream/map.rs":"b91bdd5b33821a50c9b5034261a14f89ff1a9d541ab99b9d9a6921b12a5d434e","src/stream/stream/mod.rs":"16957f40ba0fdb95b81072531fa3019bf76cf8f9b898d400179f4c9a5cea844e","src/stream/stream/next.rs":"7b4d5a22b5e00aa191ea82346bb1f392121cc68692864a8230e462d59e622928","src/stream/stream/peek.rs":"f39d1e548257c487b8447e22791729a65b6e1ab90a785f7fd23b2307bb3a2ac9","src/stream/stream/ready_chunks.rs":"4e6deb3a6d453fd4e982bdba416188311a72daca1b218d4e9ef20819fc09b5b2","src/stream/stream/scan.rs":"1db439088e1e8fd75cd8f23b5d316de40c38a5f1867237237a4931068ec9bd22","src/stream/stream/select_next_some.rs":"0094eccc96cfe78d9b6d0a9bdb82cada8fb7929770a3ac00ffcb5441d7dc4f51","src/stream/stream/skip.rs":"61f7ec7fe25663d2c87cffaad19ed27eda032842edb8af731b521025b244f120","src/stream/stream/skip_while.rs":"75ee580e0111200758d0c0fe154276007ff233db6b63a8223f0baeac1db18874","src/stream/stream/split.rs":"fa4adea18708dad384eb347260cfb965d30c40a677e15f9267f97aa382c6306c","src/stream/stream/take.rs":"505f83d341dc84eeab46f5e66adfa21a36207cb66f2394dd6a256576db665827","src/stream/stream/take_until.rs":"0f1fa7d158192a5dee32392dfdd062c15dab6d246b0ca267e91aae490d7d7fdb","src/stream/stream/take_while.rs":"51007dbde8434fd22c5ef2481a99463f11b3785e4bdeb73fa583a17f29f5c228","src/stream/stream/then.rs":"9dcfdc741d1d7dea0100aa9f1feadb932f8530f7a7d3071befc1e490a6cb50ed","src/stream/stream/unzip.rs":"9ad4db7522f66a9133e464c13d6c95682c797ae5a986e60d3aba358c65031fe8","src/stream/stream/zip.rs":"56f30f513e11754f59ead5ca4112014cba9278d02796eb8fe0937ae8bb4d44cd","src/stream/try_stream/and_then.rs":"22ca6e547d0db2e07b0a928c48118a532adaf28d85c60ab84b8366dbfeab9161","src/stream/try_stream/into_async_read.rs":"f584fd8dfdab90328fc89eac78306caa308d43f3035c1c5489e55384007e77ed","src/stream/try_stream/into_stream.rs":"4fee94e89956a42871fc4a0cdba7ae1b7d4265e884528799cd227c9dd851acce","src/stream/try_stream/mod.rs":"7ae4319a02e11b97d95eb0c92f192dcd33d9e16203d0348943ab0da6798becb8","src/stream/try_stream/or_else.rs":"8cc7f602da1ffee21bf06c5203aa0427514a83b67941ae264459f1eff8dc8aec","src/stream/try_stream/try_buffer_unordered.rs":"64e698ea6aefbe7e32d48e737553b20b9cde5c258963bb20486b48b7d6899660","src/stream/try_stream/try_buffered.rs":"7546d396026bf700d3f37f55d5a4e39abe5fb05919e6a269feeb8be7af19256c","src/stream/try_stream/try_collect.rs":"1132751055a51b936ed28b83c4eed7dee3f40a4be13ea374b30086e864e1ee09","src/stream/try_stream/try_concat.rs":"f2330ebeeab30273e9ac0e8600bfe2f405ce671f6386e688b3afb1d2fdd7c2c6","src/stream/try_stream/try_filter.rs":"7c2a09cdb1753ecb49a44d1d84742cb2050a999a8148448b31bb404eb2d17154","src/stream/try_stream/try_filter_map.rs":"5afc6ab35e2b425e37ed217a6bb038459c8828d6bcd6a3699883d6df071dc7e7","src/stream/try_stream/try_flatten.rs":"e05614d86a27ab8386476eea35fd424c07e5f7f99cf0401d63a6655eb7ca1247","src/stream/try_stream/try_fold.rs":"b96aa2fe1a16f625d5045028a86ff8684dcf5198ef8c7c072f52f39aeaa8b619","src/stream/try_stream/try_for_each.rs":"3f3901d618333b740d470eb02fcbb645df92483493872298bb7bd0382646028a","src/stream/try_stream/try_for_each_concurrent.rs":"78a94a77f329862c2a245ec3add97e49c534985f0d9da98f205b7fa3c7c08df3","src/stream/try_stream/try_next.rs":"6e29473153db1435906e79f7eaa13ce9da842d4528ba9eb1c0034665feacc565","src/stream/try_stream/try_skip_while.rs":"c0259ec70bdf4a81c1fa569275766e3e65db9d5715c81e93ada04817c1835add","src/stream/try_stream/try_take_while.rs":"54927dfa95ff58b542a1d7382f564eeae5e02e633c948b1a39ac09bc7e92f5f5","src/stream/try_stream/try_unfold.rs":"aaf0f4857a4ec8233ac842ae509f29e5a210827a0bb40cfc0dc3e858f153d2b4","src/stream/unfold.rs":"8b2feb00f979562b43064eb078d53a160cdb3c65deed17ec25a05938df2d370f","src/task/mod.rs":"186a75506faa9118ca670c8230a220895f8f8cd40de4dd5678bdbf12c55e7cfe","src/task/spawn.rs":"26bbcf1d65e1467de0ecdad2b56f464a510cda7c1933427d69a1b50459836489","src/unfold_state.rs":"ffe848071a99d6afcdbe8281a8a77a559a7dde434fc41f734c90e6b9b5d8a5af"},"package":"feb5c238d27e2bf94ffdfd27b2c29e3df4a68c4193bb6427384259e2bf191967"}
\ No newline at end of file
diff --git a/third_party/rust/futures-util/Cargo.toml b/third_party/rust/futures-util/Cargo.toml
index 1b96b8f95fc7bd734177249dfdf188f21216bdcd..d4b56649e0cb7e96c4d6227f304b879c0d731cbd 100644
--- a/third_party/rust/futures-util/Cargo.toml
+++ b/third_party/rust/futures-util/Cargo.toml
@@ -13,7 +13,7 @@
 [package]
 edition = "2018"
 name = "futures-util"
-version = "0.3.12"
+version = "0.3.15"
 authors = ["Alex Crichton <alex@alexcrichton.com>"]
 description = "Common utilities and extension traits for the futures-rs library.\n"
 homepage = "https://rust-lang.github.io/futures-rs"
@@ -24,33 +24,33 @@ repository = "https://github.com/rust-lang/futures-rs"
 all-features = true
 rustdoc-args = ["--cfg", "docsrs"]
 [dependencies.futures-channel]
-version = "0.3.12"
+version = "0.3.15"
 features = ["std"]
 optional = true
 default-features = false
 
 [dependencies.futures-core]
-version = "0.3.12"
+version = "0.3.15"
 default-features = false
 
 [dependencies.futures-io]
-version = "0.3.12"
+version = "0.3.15"
 features = ["std"]
 optional = true
 default-features = false
 
 [dependencies.futures-macro]
-version = "=0.3.12"
+version = "=0.3.15"
 optional = true
 default-features = false
 
 [dependencies.futures-sink]
-version = "0.3.12"
+version = "0.3.15"
 optional = true
 default-features = false
 
 [dependencies.futures-task]
-version = "0.3.12"
+version = "0.3.15"
 default-features = false
 
 [dependencies.futures_01]
@@ -85,13 +85,15 @@ version = "0.1.9"
 optional = true
 [dev-dependencies.tokio]
 version = "0.1.11"
+[build-dependencies.autocfg]
+version = "1"
 
 [features]
 alloc = ["futures-core/alloc", "futures-task/alloc"]
 async-await = []
 async-await-macro = ["async-await", "futures-macro", "proc-macro-hack", "proc-macro-nested"]
 bilock = []
-cfg-target-has-atomic = ["futures-core/cfg-target-has-atomic", "futures-task/cfg-target-has-atomic"]
+cfg-target-has-atomic = []
 channel = ["std", "futures-channel"]
 compat = ["std", "futures_01"]
 default = ["std", "async-await", "async-await-macro"]
diff --git a/third_party/rust/futures-util/benches/futures_unordered.rs b/third_party/rust/futures-util/benches/futures_unordered.rs
index 05e9eadb79cf59e0ba8feacfd21c6422c4d16071..d5fe7a59deff25d4085d6f00297bf9bff4f88df8 100644
--- a/third_party/rust/futures-util/benches/futures_unordered.rs
+++ b/third_party/rust/futures-util/benches/futures_unordered.rs
@@ -6,7 +6,7 @@ use crate::test::Bencher;
 use futures::channel::oneshot;
 use futures::executor::block_on;
 use futures::future;
-use futures::stream::{StreamExt, FuturesUnordered};
+use futures::stream::{FuturesUnordered, StreamExt};
 use futures::task::Poll;
 use std::collections::VecDeque;
 use std::thread;
@@ -34,7 +34,7 @@ fn oneshots(b: &mut Bencher) {
         block_on(future::poll_fn(move |cx| {
             loop {
                 if let Poll::Ready(None) = rxs.poll_next_unpin(cx) {
-                    break
+                    break;
                 }
             }
             Poll::Ready(())
diff --git a/third_party/rust/futures-util/benches_disabled/bilock.rs b/third_party/rust/futures-util/benches_disabled/bilock.rs
index 48afe3c55189d018965e0071400cbd488f0dbe1e..417f75d31e7222b49ec3b036a578aa2676139c00 100644
--- a/third_party/rust/futures-util/benches_disabled/bilock.rs
+++ b/third_party/rust/futures-util/benches_disabled/bilock.rs
@@ -2,125 +2,121 @@
 
 #[cfg(feature = "bilock")]
 mod bench {
-use futures::task::{Context, Waker};
-use futures::executor::LocalPool;
-use futures_util::lock::BiLock;
-use futures_util::lock::BiLockAcquire;
-use futures_util::lock::BiLockAcquired;
-use futures_util::task::ArcWake;
+    use futures::executor::LocalPool;
+    use futures::task::{Context, Waker};
+    use futures_util::lock::BiLock;
+    use futures_util::lock::BiLockAcquire;
+    use futures_util::lock::BiLockAcquired;
+    use futures_util::task::ArcWake;
 
-use std::sync::Arc;
-use test::Bencher;
+    use std::sync::Arc;
+    use test::Bencher;
 
-fn notify_noop() -> Waker {
-    struct Noop;
+    fn notify_noop() -> Waker {
+        struct Noop;
 
-    impl ArcWake for Noop {
-        fn wake(_: &Arc<Self>) {}
-    }
-
-    ArcWake::into_waker(Arc::new(Noop))
-}
-
-
-/// Pseudo-stream which simply calls `lock.poll()` on `poll`
-struct LockStream {
-    lock: BiLockAcquire<u32>,
-}
-
-impl LockStream {
-    fn new(lock: BiLock<u32>) -> Self {
-        Self {
-            lock: lock.lock()
+        impl ArcWake for Noop {
+            fn wake(_: &Arc<Self>) {}
         }
-    }
 
-    /// Release a lock after it was acquired in `poll`,
-    /// so `poll` could be called again.
-    fn release_lock(&mut self, guard: BiLockAcquired<u32>) {
-        self.lock = guard.unlock().lock()
+        ArcWake::into_waker(Arc::new(Noop))
     }
-}
-
-impl Stream for LockStream {
-    type Item = BiLockAcquired<u32>;
-    type Error = ();
 
-    fn poll_next(&mut self, cx: &mut Context<'_>) -> Poll<Option<Self::Item>, Self::Error> {
-        self.lock.poll(cx).map(|a| a.map(Some))
+    /// Pseudo-stream which simply calls `lock.poll()` on `poll`
+    struct LockStream {
+        lock: BiLockAcquire<u32>,
     }
-}
-
-
-#[bench]
-fn contended(b: &mut Bencher) {
-    let pool = LocalPool::new();
-    let mut exec = pool.executor();
-    let waker = notify_noop();
-    let mut map = task::LocalMap::new();
-    let mut waker = task::Context::new(&mut map, &waker, &mut exec);
-
-    b.iter(|| {
-        let (x, y) = BiLock::new(1);
-
-        let mut x = LockStream::new(x);
-        let mut y = LockStream::new(y);
 
-        for _ in 0..1000 {
-            let x_guard = match x.poll_next(&mut waker) {
-                Ok(Poll::Ready(Some(guard))) => guard,
-                _ => panic!(),
-            };
-
-            // Try poll second lock while first lock still holds the lock
-            match y.poll_next(&mut waker) {
-                Ok(Poll::Pending) => (),
-                _ => panic!(),
-            };
-
-            x.release_lock(x_guard);
-
-            let y_guard = match y.poll_next(&mut waker) {
-                Ok(Poll::Ready(Some(guard))) => guard,
-                _ => panic!(),
-            };
-
-            y.release_lock(y_guard);
+    impl LockStream {
+        fn new(lock: BiLock<u32>) -> Self {
+            Self { lock: lock.lock() }
         }
-        (x, y)
-    });
-}
-
-#[bench]
-fn lock_unlock(b: &mut Bencher) {
-    let pool = LocalPool::new();
-    let mut exec = pool.executor();
-    let waker = notify_noop();
-    let mut map = task::LocalMap::new();
-    let mut waker = task::Context::new(&mut map, &waker, &mut exec);
 
-    b.iter(|| {
-        let (x, y) = BiLock::new(1);
-
-        let mut x = LockStream::new(x);
-        let mut y = LockStream::new(y);
+        /// Release a lock after it was acquired in `poll`,
+        /// so `poll` could be called again.
+        fn release_lock(&mut self, guard: BiLockAcquired<u32>) {
+            self.lock = guard.unlock().lock()
+        }
+    }
 
-        for _ in 0..1000 {
-            let x_guard = match x.poll_next(&mut waker) {
-                Ok(Poll::Ready(Some(guard))) => guard,
-                _ => panic!(),
-            };
+    impl Stream for LockStream {
+        type Item = BiLockAcquired<u32>;
+        type Error = ();
 
-            x.release_lock(x_guard);
+        fn poll_next(&mut self, cx: &mut Context<'_>) -> Poll<Option<Self::Item>, Self::Error> {
+            self.lock.poll(cx).map(|a| a.map(Some))
+        }
+    }
 
-            let y_guard = match y.poll_next(&mut waker) {
-                Ok(Poll::Ready(Some(guard))) => guard,
-                _ => panic!(),
-            };
+    #[bench]
+    fn contended(b: &mut Bencher) {
+        let pool = LocalPool::new();
+        let mut exec = pool.executor();
+        let waker = notify_noop();
+        let mut map = task::LocalMap::new();
+        let mut waker = task::Context::new(&mut map, &waker, &mut exec);
+
+        b.iter(|| {
+            let (x, y) = BiLock::new(1);
+
+            let mut x = LockStream::new(x);
+            let mut y = LockStream::new(y);
+
+            for _ in 0..1000 {
+                let x_guard = match x.poll_next(&mut waker) {
+                    Ok(Poll::Ready(Some(guard))) => guard,
+                    _ => panic!(),
+                };
+
+                // Try poll second lock while first lock still holds the lock
+                match y.poll_next(&mut waker) {
+                    Ok(Poll::Pending) => (),
+                    _ => panic!(),
+                };
+
+                x.release_lock(x_guard);
+
+                let y_guard = match y.poll_next(&mut waker) {
+                    Ok(Poll::Ready(Some(guard))) => guard,
+                    _ => panic!(),
+                };
+
+                y.release_lock(y_guard);
+            }
+            (x, y)
+        });
+    }
 
-            y.release_lock(y_guard);
-        }
-        (x, y)
-    })
-}
+    #[bench]
+    fn lock_unlock(b: &mut Bencher) {
+        let pool = LocalPool::new();
+        let mut exec = pool.executor();
+        let waker = notify_noop();
+        let mut map = task::LocalMap::new();
+        let mut waker = task::Context::new(&mut map, &waker, &mut exec);
+
+        b.iter(|| {
+            let (x, y) = BiLock::new(1);
+
+            let mut x = LockStream::new(x);
+            let mut y = LockStream::new(y);
+
+            for _ in 0..1000 {
+                let x_guard = match x.poll_next(&mut waker) {
+                    Ok(Poll::Ready(Some(guard))) => guard,
+                    _ => panic!(),
+                };
+
+                x.release_lock(x_guard);
+
+                let y_guard = match y.poll_next(&mut waker) {
+                    Ok(Poll::Ready(Some(guard))) => guard,
+                    _ => panic!(),
+                };
+
+                y.release_lock(y_guard);
+            }
+            (x, y)
+        })
+    }
 }
diff --git a/third_party/rust/futures-util/build.rs b/third_party/rust/futures-util/build.rs
new file mode 100644
index 0000000000000000000000000000000000000000..ffe971141482633d8837522ba41a11d8589a8e27
--- /dev/null
+++ b/third_party/rust/futures-util/build.rs
@@ -0,0 +1,61 @@
+#![warn(rust_2018_idioms, single_use_lifetimes)]
+
+use autocfg::AutoCfg;
+use std::env;
+
+include!("no_atomic_cas.rs");
+
+// The rustc-cfg listed below are considered public API, but it is *unstable*
+// and outside of the normal semver guarantees:
+//
+// - `futures_no_atomic_cas`
+//      Assume the target does not have atomic CAS (compare-and-swap).
+//      This is usually detected automatically by the build script, but you may
+//      need to enable it manually when building for custom targets or using
+//      non-cargo build systems that don't run the build script.
+//
+// With the exceptions mentioned above, the rustc-cfg strings below are
+// *not* public API. Please let us know by opening a GitHub issue if your build
+// environment requires some way to enable these cfgs other than by executing
+// our build script.
+fn main() {
+    let target = match env::var("TARGET") {
+        Ok(target) => target,
+        Err(e) => {
+            println!(
+                "cargo:warning={}: unable to get TARGET environment variable: {}",
+                env!("CARGO_PKG_NAME"),
+                e
+            );
+            return;
+        }
+    };
+
+    // Note that this is `no_*`, not `has_*`. This allows treating
+    // `cfg(target_has_atomic = "ptr")` as true when the build script doesn't
+    // run. This is needed for compatibility with non-cargo build systems that
+    // don't run the build script.
+    if NO_ATOMIC_CAS_TARGETS.contains(&&*target) {
+        println!("cargo:rustc-cfg=futures_no_atomic_cas");
+    }
+
+    let cfg = match AutoCfg::new() {
+        Ok(cfg) => cfg,
+        Err(e) => {
+            println!(
+                "cargo:warning={}: unable to determine rustc version: {}",
+                env!("CARGO_PKG_NAME"),
+                e
+            );
+            return;
+        }
+    };
+
+    // Function like procedural macros in expressions patterns statements stabilized in Rust 1.45:
+    // https://blog.rust-lang.org/2020/07/16/Rust-1.45.0.html#stabilizing-function-like-procedural-macros-in-expressions-patterns-and-statements
+    if cfg.probe_rustc_version(1, 45) {
+        println!("cargo:rustc-cfg=fn_like_proc_macro");
+    }
+
+    println!("cargo:rerun-if-changed=no_atomic_cas.rs");
+}
diff --git a/third_party/rust/futures-util/no_atomic_cas.rs b/third_party/rust/futures-util/no_atomic_cas.rs
new file mode 100644
index 0000000000000000000000000000000000000000..0819af1a45093532034d0042a15a3d460f208d7c
--- /dev/null
+++ b/third_party/rust/futures-util/no_atomic_cas.rs
@@ -0,0 +1,11 @@
+// This file is @generated by no_atomic_cas.sh.
+// It is not intended for manual editing.
+
+const NO_ATOMIC_CAS_TARGETS: &[&str] = &[
+    "avr-unknown-gnu-atmega328",
+    "msp430-none-elf",
+    "riscv32i-unknown-none-elf",
+    "riscv32imc-unknown-none-elf",
+    "thumbv4t-none-eabi",
+    "thumbv6m-none-eabi",
+];
diff --git a/third_party/rust/futures-util/src/abortable.rs b/third_party/rust/futures-util/src/abortable.rs
new file mode 100644
index 0000000000000000000000000000000000000000..bb82dd0db83f26c9a3d20eba0a0882bb9bf1dfb1
--- /dev/null
+++ b/third_party/rust/futures-util/src/abortable.rs
@@ -0,0 +1,185 @@
+use crate::task::AtomicWaker;
+use alloc::sync::Arc;
+use core::fmt;
+use core::pin::Pin;
+use core::sync::atomic::{AtomicBool, Ordering};
+use futures_core::future::Future;
+use futures_core::task::{Context, Poll};
+use futures_core::Stream;
+use pin_project_lite::pin_project;
+
+pin_project! {
+    /// A future/stream which can be remotely short-circuited using an `AbortHandle`.
+    #[derive(Debug, Clone)]
+    #[must_use = "futures/streams do nothing unless you poll them"]
+    pub struct Abortable<T> {
+        #[pin]
+        task: T,
+        inner: Arc<AbortInner>,
+    }
+}
+
+impl<T> Abortable<T> {
+    /// Creates a new `Abortable` future/stream using an existing `AbortRegistration`.
+    /// `AbortRegistration`s can be acquired through `AbortHandle::new`.
+    ///
+    /// When `abort` is called on the handle tied to `reg` or if `abort` has
+    /// already been called, the future/stream will complete immediately without making
+    /// any further progress.
+    ///
+    /// # Examples:
+    ///
+    /// Usage with futures:
+    ///
+    /// ```
+    /// # futures::executor::block_on(async {
+    /// use futures::future::{Abortable, AbortHandle, Aborted};
+    ///
+    /// let (abort_handle, abort_registration) = AbortHandle::new_pair();
+    /// let future = Abortable::new(async { 2 }, abort_registration);
+    /// abort_handle.abort();
+    /// assert_eq!(future.await, Err(Aborted));
+    /// # });
+    /// ```
+    ///
+    /// Usage with streams:
+    ///
+    /// ```
+    /// # futures::executor::block_on(async {
+    /// # use futures::future::{Abortable, AbortHandle};
+    /// # use futures::stream::{self, StreamExt};
+    ///
+    /// let (abort_handle, abort_registration) = AbortHandle::new_pair();
+    /// let mut stream = Abortable::new(stream::iter(vec![1, 2, 3]), abort_registration);
+    /// abort_handle.abort();
+    /// assert_eq!(stream.next().await, None);
+    /// # });
+    /// ```
+    pub fn new(task: T, reg: AbortRegistration) -> Self {
+        Self { task, inner: reg.inner }
+    }
+
+    /// Checks whether the task has been aborted. Note that all this
+    /// method indicates is whether [`AbortHandle::abort`] was *called*.
+    /// This means that it will return `true` even if:
+    /// * `abort` was called after the task had completed.
+    /// * `abort` was called while the task was being polled - the task may still be running and
+    /// will not be stopped until `poll` returns.
+    pub fn is_aborted(&self) -> bool {
+        self.inner.aborted.load(Ordering::Relaxed)
+    }
+}
+
+/// A registration handle for an `Abortable` task.
+/// Values of this type can be acquired from `AbortHandle::new` and are used
+/// in calls to `Abortable::new`.
+#[derive(Debug)]
+pub struct AbortRegistration {
+    inner: Arc<AbortInner>,
+}
+
+/// A handle to an `Abortable` task.
+#[derive(Debug, Clone)]
+pub struct AbortHandle {
+    inner: Arc<AbortInner>,
+}
+
+impl AbortHandle {
+    /// Creates an (`AbortHandle`, `AbortRegistration`) pair which can be used
+    /// to abort a running future or stream.
+    ///
+    /// This function is usually paired with a call to [`Abortable::new`].
+    pub fn new_pair() -> (Self, AbortRegistration) {
+        let inner =
+            Arc::new(AbortInner { waker: AtomicWaker::new(), aborted: AtomicBool::new(false) });
+
+        (Self { inner: inner.clone() }, AbortRegistration { inner })
+    }
+}
+
+// Inner type storing the waker to awaken and a bool indicating that it
+// should be aborted.
+#[derive(Debug)]
+struct AbortInner {
+    waker: AtomicWaker,
+    aborted: AtomicBool,
+}
+
+/// Indicator that the `Abortable` task was aborted.
+#[derive(Copy, Clone, Debug, Eq, PartialEq)]
+pub struct Aborted;
+
+impl fmt::Display for Aborted {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        write!(f, "`Abortable` future has been aborted")
+    }
+}
+
+#[cfg(feature = "std")]
+impl std::error::Error for Aborted {}
+
+impl<T> Abortable<T> {
+    fn try_poll<I>(
+        mut self: Pin<&mut Self>,
+        cx: &mut Context<'_>,
+        poll: impl Fn(Pin<&mut T>, &mut Context<'_>) -> Poll<I>,
+    ) -> Poll<Result<I, Aborted>> {
+        // Check if the task has been aborted
+        if self.is_aborted() {
+            return Poll::Ready(Err(Aborted));
+        }
+
+        // attempt to complete the task
+        if let Poll::Ready(x) = poll(self.as_mut().project().task, cx) {
+            return Poll::Ready(Ok(x));
+        }
+
+        // Register to receive a wakeup if the task is aborted in the future
+        self.inner.waker.register(cx.waker());
+
+        // Check to see if the task was aborted between the first check and
+        // registration.
+        // Checking with `is_aborted` which uses `Relaxed` is sufficient because
+        // `register` introduces an `AcqRel` barrier.
+        if self.is_aborted() {
+            return Poll::Ready(Err(Aborted));
+        }
+
+        Poll::Pending
+    }
+}
+
+impl<Fut> Future for Abortable<Fut>
+where
+    Fut: Future,
+{
+    type Output = Result<Fut::Output, Aborted>;
+
+    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
+        self.try_poll(cx, |fut, cx| fut.poll(cx))
+    }
+}
+
+impl<St> Stream for Abortable<St>
+where
+    St: Stream,
+{
+    type Item = St::Item;
+
+    fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
+        self.try_poll(cx, |stream, cx| stream.poll_next(cx)).map(Result::ok).map(Option::flatten)
+    }
+}
+
+impl AbortHandle {
+    /// Abort the `Abortable` stream/future associated with this handle.
+    ///
+    /// Notifies the Abortable task associated with this handle that it
+    /// should abort. Note that if the task is currently being polled on
+    /// another thread, it will not immediately stop running. Instead, it will
+    /// continue to run until its poll method returns.
+    pub fn abort(&self) {
+        self.inner.aborted.store(true, Ordering::Relaxed);
+        self.inner.waker.wake();
+    }
+}
diff --git a/third_party/rust/futures-util/src/async_await/join_mod.rs b/third_party/rust/futures-util/src/async_await/join_mod.rs
index d6ddb6d8a71849b242dd97245e9ce555c92e1a7c..c5cdd9babc2aa358c5b90c5de4e6aa213bfa91ba 100644
--- a/third_party/rust/futures-util/src/async_await/join_mod.rs
+++ b/third_party/rust/futures-util/src/async_await/join_mod.rs
@@ -1,14 +1,12 @@
 //! The `join` macro.
 
-use proc_macro_hack::proc_macro_hack;
-
 macro_rules! document_join_macro {
     ($join:item $try_join:item) => {
         /// Polls multiple futures simultaneously, returning a tuple
         /// of all results once complete.
         ///
         /// While `join!(a, b)` is similar to `(a.await, b.await)`,
-        /// `join!` polls both futures concurrently and therefore is more efficent.
+        /// `join!` polls both futures concurrently and therefore is more efficient.
         ///
         /// This macro is only usable inside of async functions, closures, and blocks.
         /// It is also gated behind the `async-await` feature of this library, which is
@@ -81,12 +79,14 @@ macro_rules! document_join_macro {
     }
 }
 
+#[allow(unreachable_pub)]
 #[doc(hidden)]
-#[proc_macro_hack(support_nested, only_hack_old_rustc)]
+#[cfg_attr(not(fn_like_proc_macro), proc_macro_hack::proc_macro_hack(support_nested))]
 pub use futures_macro::join_internal;
 
+#[allow(unreachable_pub)]
 #[doc(hidden)]
-#[proc_macro_hack(support_nested, only_hack_old_rustc)]
+#[cfg_attr(not(fn_like_proc_macro), proc_macro_hack::proc_macro_hack(support_nested))]
 pub use futures_macro::try_join_internal;
 
 document_join_macro! {
diff --git a/third_party/rust/futures-util/src/async_await/mod.rs b/third_party/rust/futures-util/src/async_await/mod.rs
index bdaed95b0cc82b5f203220faf14edfc8c4480292..5f5d4aca3f74502afb4f82987e4b29ff8d495bfb 100644
--- a/third_party/rust/futures-util/src/async_await/mod.rs
+++ b/third_party/rust/futures-util/src/async_await/mod.rs
@@ -3,8 +3,8 @@
 //! This module contains a number of functions and combinators for working
 //! with `async`/`await` code.
 
-use futures_core::future::{Future, FusedFuture};
-use futures_core::stream::{Stream, FusedStream};
+use futures_core::future::{FusedFuture, Future};
+use futures_core::stream::{FusedStream, Stream};
 
 #[macro_use]
 mod poll;
diff --git a/third_party/rust/futures-util/src/async_await/pending.rs b/third_party/rust/futures-util/src/async_await/pending.rs
index e0cf341a8bc48b78e71d9b86fce40f0a7afa7745..5d7a431811feff8bc257c22e26c8989c68f4eb81 100644
--- a/third_party/rust/futures-util/src/async_await/pending.rs
+++ b/third_party/rust/futures-util/src/async_await/pending.rs
@@ -16,7 +16,7 @@ use futures_core::task::{Context, Poll};
 macro_rules! pending {
     () => {
         $crate::__private::async_await::pending_once().await
-    }
+    };
 }
 
 #[doc(hidden)]
diff --git a/third_party/rust/futures-util/src/async_await/poll.rs b/third_party/rust/futures-util/src/async_await/poll.rs
index ac70a53a17bc506d4829f75997591f5f02212ce4..b62f45a943cc892dd73193caba136af07e90790a 100644
--- a/third_party/rust/futures-util/src/async_await/poll.rs
+++ b/third_party/rust/futures-util/src/async_await/poll.rs
@@ -9,11 +9,15 @@ use futures_core::task::{Context, Poll};
 /// This macro is only usable inside of `async` functions, closures, and blocks.
 /// It is also gated behind the `async-await` feature of this library, which is
 /// activated by default.
+///
+/// If you need the result of polling a [`Stream`](crate::stream::Stream),
+/// you can use this macro with the [`next`](crate::stream::StreamExt::next) method:
+/// `poll!(stream.next())`.
 #[macro_export]
 macro_rules! poll {
     ($x:expr $(,)?) => {
         $crate::__private::async_await::poll($x).await
-    }
+    };
 }
 
 #[doc(hidden)]
diff --git a/third_party/rust/futures-util/src/async_await/select_mod.rs b/third_party/rust/futures-util/src/async_await/select_mod.rs
index 59bca0840ae82c045f3564250dc88e705bd966b0..37e938da5578658d391d97f5aa6dfc60fc25ca64 100644
--- a/third_party/rust/futures-util/src/async_await/select_mod.rs
+++ b/third_party/rust/futures-util/src/async_await/select_mod.rs
@@ -1,7 +1,5 @@
 //! The `select` macro.
 
-use proc_macro_hack::proc_macro_hack;
-
 macro_rules! document_select_macro {
     // This branch is required for `futures 0.3.1`, from before select_biased was introduced
     ($select:item) => {
@@ -309,12 +307,14 @@ macro_rules! document_select_macro {
 }
 
 #[cfg(feature = "std")]
+#[allow(unreachable_pub)]
 #[doc(hidden)]
-#[proc_macro_hack(support_nested, only_hack_old_rustc)]
+#[cfg_attr(not(fn_like_proc_macro), proc_macro_hack::proc_macro_hack(support_nested))]
 pub use futures_macro::select_internal;
 
+#[allow(unreachable_pub)]
 #[doc(hidden)]
-#[proc_macro_hack(support_nested, only_hack_old_rustc)]
+#[cfg_attr(not(fn_like_proc_macro), proc_macro_hack::proc_macro_hack(support_nested))]
 pub use futures_macro::select_biased_internal;
 
 document_select_macro! {
diff --git a/third_party/rust/futures-util/src/compat/compat01as03.rs b/third_party/rust/futures-util/src/compat/compat01as03.rs
index bc3aee3c0ac057cf0346500b752ea3e62110fdb9..17239a4e57d164299594789b0157ffda5ccd8b82 100644
--- a/third_party/rust/futures-util/src/compat/compat01as03.rs
+++ b/third_party/rust/futures-util/src/compat/compat01as03.rs
@@ -1,18 +1,15 @@
 use futures_01::executor::{
-    spawn as spawn01, Notify as Notify01, NotifyHandle as NotifyHandle01,
-    Spawn as Spawn01, UnsafeNotify as UnsafeNotify01,
-};
-use futures_01::{
-    Async as Async01, Future as Future01,
-    Stream as Stream01,
+    spawn as spawn01, Notify as Notify01, NotifyHandle as NotifyHandle01, Spawn as Spawn01,
+    UnsafeNotify as UnsafeNotify01,
 };
+use futures_01::{Async as Async01, Future as Future01, Stream as Stream01};
 #[cfg(feature = "sink")]
 use futures_01::{AsyncSink as AsyncSink01, Sink as Sink01};
-use futures_core::{task as task03, future::Future as Future03, stream::Stream as Stream03};
-use std::pin::Pin;
-use std::task::Context;
+use futures_core::{future::Future as Future03, stream::Stream as Stream03, task as task03};
 #[cfg(feature = "sink")]
 use futures_sink::Sink as Sink03;
+use std::pin::Pin;
+use std::task::Context;
 
 #[cfg(feature = "io-compat")]
 #[cfg_attr(docsrs, doc(cfg(feature = "io-compat")))]
@@ -33,9 +30,7 @@ impl<T> Compat01As03<T> {
     /// Wraps a futures 0.1 Future, Stream, AsyncRead, or AsyncWrite
     /// object in a futures 0.3-compatible wrapper.
     pub fn new(object: T) -> Self {
-        Self {
-            inner: spawn01(object),
-        }
+        Self { inner: spawn01(object) }
     }
 
     fn in_notify<R>(&mut self, cx: &mut Context<'_>, f: impl FnOnce(&mut T) -> R) -> R {
@@ -157,10 +152,7 @@ fn poll_01_to_03<T, E>(x: Result<Async01<T>, E>) -> task03::Poll<Result<T, E>> {
 impl<Fut: Future01> Future03 for Compat01As03<Fut> {
     type Output = Result<Fut::Item, Fut::Error>;
 
-    fn poll(
-        mut self: Pin<&mut Self>,
-        cx: &mut Context<'_>,
-    ) -> task03::Poll<Self::Output> {
+    fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> task03::Poll<Self::Output> {
         poll_01_to_03(self.in_notify(cx, Future01::poll))
     }
 }
@@ -198,18 +190,10 @@ impl<S, SinkItem> Unpin for Compat01As03Sink<S, SinkItem> {}
 impl<S, SinkItem> Compat01As03Sink<S, SinkItem> {
     /// Wraps a futures 0.1 Sink object in a futures 0.3-compatible wrapper.
     pub fn new(inner: S) -> Self {
-        Self {
-            inner: spawn01(inner),
-            buffer: None,
-            close_started: false
-        }
+        Self { inner: spawn01(inner), buffer: None, close_started: false }
     }
 
-    fn in_notify<R>(
-        &mut self,
-        cx: &mut Context<'_>,
-        f: impl FnOnce(&mut S) -> R,
-    ) -> R {
+    fn in_notify<R>(&mut self, cx: &mut Context<'_>, f: impl FnOnce(&mut S) -> R) -> R {
         let notify = &WakerToHandle(cx.waker());
         self.inner.poll_fn_notify(notify, 0, f)
     }
@@ -256,10 +240,7 @@ where
 {
     type Error = S::SinkError;
 
-    fn start_send(
-        mut self: Pin<&mut Self>,
-        item: SinkItem,
-    ) -> Result<(), Self::Error> {
+    fn start_send(mut self: Pin<&mut Self>, item: SinkItem) -> Result<(), Self::Error> {
         debug_assert!(self.buffer.is_none());
         self.buffer = Some(item);
         Ok(())
@@ -289,9 +270,7 @@ where
         match self.in_notify(cx, |f| match item {
             Some(i) => match f.start_send(i)? {
                 AsyncSink01::Ready => f.poll_complete().map(|i| (i, None)),
-                AsyncSink01::NotReady(t) => {
-                    Ok((Async01::NotReady, Some(t)))
-                }
+                AsyncSink01::NotReady(t) => Ok((Async01::NotReady, Some(t))),
             },
             None => f.poll_complete().map(|i| (i, None)),
         })? {
@@ -447,29 +426,35 @@ mod io {
             }
         }
 
-        fn poll_read(mut self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &mut [u8])
-            -> task03::Poll<Result<usize, Error>>
-        {
+        fn poll_read(
+            mut self: Pin<&mut Self>,
+            cx: &mut Context<'_>,
+            buf: &mut [u8],
+        ) -> task03::Poll<Result<usize, Error>> {
             poll_01_to_03(self.in_notify(cx, |x| x.poll_read(buf)))
         }
     }
 
     impl<W: AsyncWrite01> AsyncWrite03 for Compat01As03<W> {
-        fn poll_write(mut self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &[u8])
-            -> task03::Poll<Result<usize, Error>>
-        {
+        fn poll_write(
+            mut self: Pin<&mut Self>,
+            cx: &mut Context<'_>,
+            buf: &[u8],
+        ) -> task03::Poll<Result<usize, Error>> {
             poll_01_to_03(self.in_notify(cx, |x| x.poll_write(buf)))
         }
 
-        fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>)
-            -> task03::Poll<Result<(), Error>>
-        {
+        fn poll_flush(
+            mut self: Pin<&mut Self>,
+            cx: &mut Context<'_>,
+        ) -> task03::Poll<Result<(), Error>> {
             poll_01_to_03(self.in_notify(cx, AsyncWrite01::poll_flush))
         }
 
-        fn poll_close(mut self: Pin<&mut Self>, cx: &mut Context<'_>)
-            -> task03::Poll<Result<(), Error>>
-        {
+        fn poll_close(
+            mut self: Pin<&mut Self>,
+            cx: &mut Context<'_>,
+        ) -> task03::Poll<Result<(), Error>> {
             poll_01_to_03(self.in_notify(cx, AsyncWrite01::shutdown))
         }
     }
diff --git a/third_party/rust/futures-util/src/compat/compat03as01.rs b/third_party/rust/futures-util/src/compat/compat03as01.rs
index 3f1eebbf1dd19cc7b627e7750588e5cec229c31b..2573fe7a7434c583ba7b6480288bafaf8e38b73a 100644
--- a/third_party/rust/futures-util/src/compat/compat03as01.rs
+++ b/third_party/rust/futures-util/src/compat/compat03as01.rs
@@ -1,31 +1,19 @@
+use crate::task::{self as task03, ArcWake as ArcWake03, WakerRef};
 use futures_01::{
-    task as task01, Async as Async01, Future as Future01, Poll as Poll01,
-    Stream as Stream01,
+    task as task01, Async as Async01, Future as Future01, Poll as Poll01, Stream as Stream01,
 };
 #[cfg(feature = "sink")]
-use futures_01::{
-    AsyncSink as AsyncSink01, Sink as Sink01, StartSend as StartSend01,
-};
+use futures_01::{AsyncSink as AsyncSink01, Sink as Sink01, StartSend as StartSend01};
 use futures_core::{
-    task::{RawWaker, RawWakerVTable},
     future::TryFuture as TryFuture03,
     stream::TryStream as TryStream03,
+    task::{RawWaker, RawWakerVTable},
 };
 #[cfg(feature = "sink")]
 use futures_sink::Sink as Sink03;
-use crate::task::{
-    self as task03,
-    ArcWake as ArcWake03,
-    WakerRef,
-};
 #[cfg(feature = "sink")]
 use std::marker::PhantomData;
-use std::{
-    mem,
-    pin::Pin,
-    sync::Arc,
-    task::Context,
-};
+use std::{mem, pin::Pin, sync::Arc, task::Context};
 
 /// Converts a futures 0.3 [`TryFuture`](futures_core::future::TryFuture) or
 /// [`TryStream`](futures_core::stream::TryStream) into a futures 0.1
@@ -80,10 +68,7 @@ impl<T> Compat<T> {
 impl<T, Item> CompatSink<T, Item> {
     /// Creates a new [`CompatSink`].
     pub fn new(inner: T) -> Self {
-        Self {
-            inner,
-            _phantom: PhantomData,
-        }
+        Self { inner, _phantom: PhantomData }
     }
 
     /// Get a reference to 0.3 Sink contained within.
@@ -102,9 +87,7 @@ impl<T, Item> CompatSink<T, Item> {
     }
 }
 
-fn poll_03_to_01<T, E>(x: task03::Poll<Result<T, E>>)
-    -> Result<Async01<T>, E>
-{
+fn poll_03_to_01<T, E>(x: task03::Poll<Result<T, E>>) -> Result<Async01<T>, E> {
     match x? {
         task03::Poll::Ready(t) => Ok(Async01::Ready(t)),
         task03::Poll::Pending => Ok(Async01::NotReady),
@@ -147,17 +130,10 @@ where
     type SinkItem = Item;
     type SinkError = T::Error;
 
-    fn start_send(
-        &mut self,
-        item: Self::SinkItem,
-    ) -> StartSend01<Self::SinkItem, Self::SinkError> {
-        with_sink_context(self, |mut inner, cx| {
-            match inner.as_mut().poll_ready(cx)? {
-                task03::Poll::Ready(()) => {
-                    inner.start_send(item).map(|()| AsyncSink01::Ready)
-                }
-                task03::Poll::Pending => Ok(AsyncSink01::NotReady(item)),
-            }
+    fn start_send(&mut self, item: Self::SinkItem) -> StartSend01<Self::SinkItem, Self::SinkError> {
+        with_sink_context(self, |mut inner, cx| match inner.as_mut().poll_ready(cx)? {
+            task03::Poll::Ready(()) => inner.start_send(item).map(|()| AsyncSink01::Ready),
+            task03::Poll::Pending => Ok(AsyncSink01::NotReady(item)),
         })
     }
 
@@ -190,9 +166,9 @@ impl Current {
             // Lazily create the `Arc` only when the waker is actually cloned.
             // FIXME: remove `transmute` when a `Waker` -> `RawWaker` conversion
             // function is landed in `core`.
-            mem::transmute::<task03::Waker, RawWaker>(
-                task03::waker(Arc::new(ptr_to_current(ptr).clone()))
-            )
+            mem::transmute::<task03::Waker, RawWaker>(task03::waker(Arc::new(
+                ptr_to_current(ptr).clone(),
+            )))
         }
         unsafe fn drop(_: *const ()) {}
         unsafe fn wake(ptr: *const ()) {
@@ -243,9 +219,7 @@ mod io {
     use futures_io::{AsyncRead as AsyncRead03, AsyncWrite as AsyncWrite03};
     use tokio_io::{AsyncRead as AsyncRead01, AsyncWrite as AsyncWrite01};
 
-    fn poll_03_to_io<T>(x: task03::Poll<Result<T, std::io::Error>>)
-        -> Result<T, std::io::Error>
-    {
+    fn poll_03_to_io<T>(x: task03::Poll<Result<T, std::io::Error>>) -> Result<T, std::io::Error> {
         match x {
             task03::Poll::Ready(Ok(t)) => Ok(t),
             task03::Poll::Pending => Err(std::io::ErrorKind::WouldBlock.into()),
diff --git a/third_party/rust/futures-util/src/compat/executor.rs b/third_party/rust/futures-util/src/compat/executor.rs
index 82cb496a700e1058786fe9c126d33e825ac0aabc..e25705be16b0cfc27554a2b0233a9b66501609fb 100644
--- a/third_party/rust/futures-util/src/compat/executor.rs
+++ b/third_party/rust/futures-util/src/compat/executor.rs
@@ -66,9 +66,7 @@ where
     fn spawn_obj(&self, future: FutureObj<'static, ()>) -> Result<(), SpawnError03> {
         let future = future.unit_error().compat();
 
-        self.executor01
-            .execute(future)
-            .map_err(|_| SpawnError03::shutdown())
+        self.executor01.execute(future).map_err(|_| SpawnError03::shutdown())
     }
 }
 
diff --git a/third_party/rust/futures-util/src/compat/mod.rs b/third_party/rust/futures-util/src/compat/mod.rs
index c5edcc580ce02210b359f7651067b09f81e8b1f0..4812803eb6d306ef759b018ca9c767f0f1df0d4f 100644
--- a/third_party/rust/futures-util/src/compat/mod.rs
+++ b/third_party/rust/futures-util/src/compat/mod.rs
@@ -4,16 +4,16 @@
 //! library is activated.
 
 mod executor;
-pub use self::executor::{Executor01CompatExt, Executor01Future, Executor01As03};
+pub use self::executor::{Executor01As03, Executor01CompatExt, Executor01Future};
 
 mod compat01as03;
+#[cfg(feature = "io-compat")]
+#[cfg_attr(docsrs, doc(cfg(feature = "io-compat")))]
+pub use self::compat01as03::{AsyncRead01CompatExt, AsyncWrite01CompatExt};
 pub use self::compat01as03::{Compat01As03, Future01CompatExt, Stream01CompatExt};
 #[cfg(feature = "sink")]
 #[cfg_attr(docsrs, doc(cfg(feature = "sink")))]
 pub use self::compat01as03::{Compat01As03Sink, Sink01CompatExt};
-#[cfg(feature = "io-compat")]
-#[cfg_attr(docsrs, doc(cfg(feature = "io-compat")))]
-pub use self::compat01as03::{AsyncRead01CompatExt, AsyncWrite01CompatExt};
 
 mod compat03as01;
 pub use self::compat03as01::Compat;
diff --git a/third_party/rust/futures-util/src/fns.rs b/third_party/rust/futures-util/src/fns.rs
index cb623918dd2d1910320c0ad37d2461a9baddefc4..37ee03e6df0c9d5fbd4770f86ed66b16e998e14e 100644
--- a/third_party/rust/futures-util/src/fns.rs
+++ b/third_party/rust/futures-util/src/fns.rs
@@ -1,5 +1,5 @@
-use core::marker::PhantomData;
 use core::fmt::{self, Debug};
+use core::marker::PhantomData;
 
 pub trait FnOnce1<A> {
     type Output;
@@ -8,7 +8,7 @@ pub trait FnOnce1<A> {
 
 impl<T, A, R> FnOnce1<A> for T
 where
-    T: FnOnce(A) -> R
+    T: FnOnce(A) -> R,
 {
     type Output = R;
     fn call_once(self, arg: A) -> R {
@@ -22,7 +22,7 @@ pub trait FnMut1<A>: FnOnce1<A> {
 
 impl<T, A, R> FnMut1<A> for T
 where
-    T: FnMut(A) -> R
+    T: FnMut(A) -> R,
 {
     fn call_mut(&mut self, arg: A) -> R {
         self(arg)
@@ -37,7 +37,7 @@ pub trait Fn1<A>: FnMut1<A> {
 
 impl<T, A, R> Fn1<A> for T
 where
-    T: Fn(A) -> R
+    T: Fn(A) -> R,
 {
     fn call(&self, arg: A) -> R {
         self(arg)
@@ -143,7 +143,7 @@ pub struct InspectFn<F>(F);
 #[allow(single_use_lifetimes)] // https://github.com/rust-lang/rust/issues/55058
 impl<F, A> FnOnce1<A> for InspectFn<F>
 where
-    F: for<'a> FnOnce1<&'a A, Output=()>,
+    F: for<'a> FnOnce1<&'a A, Output = ()>,
 {
     type Output = A;
     fn call_once(self, arg: A) -> Self::Output {
@@ -154,7 +154,7 @@ where
 #[allow(single_use_lifetimes)] // https://github.com/rust-lang/rust/issues/55058
 impl<F, A> FnMut1<A> for InspectFn<F>
 where
-    F: for<'a> FnMut1<&'a A, Output=()>,
+    F: for<'a> FnMut1<&'a A, Output = ()>,
 {
     fn call_mut(&mut self, arg: A) -> Self::Output {
         self.0.call_mut(&arg);
@@ -164,7 +164,7 @@ where
 #[allow(single_use_lifetimes)] // https://github.com/rust-lang/rust/issues/55058
 impl<F, A> Fn1<A> for InspectFn<F>
 where
-    F: for<'a> Fn1<&'a A, Output=()>,
+    F: for<'a> Fn1<&'a A, Output = ()>,
 {
     fn call(&self, arg: A) -> Self::Output {
         self.0.call(&arg);
@@ -244,27 +244,33 @@ pub struct InspectOkFn<F>(F);
 
 impl<'a, F, T, E> FnOnce1<&'a Result<T, E>> for InspectOkFn<F>
 where
-    F: FnOnce1<&'a T, Output=()>
+    F: FnOnce1<&'a T, Output = ()>,
 {
     type Output = ();
     fn call_once(self, arg: &'a Result<T, E>) -> Self::Output {
-        if let Ok(x) = arg { self.0.call_once(x) }
+        if let Ok(x) = arg {
+            self.0.call_once(x)
+        }
     }
 }
 impl<'a, F, T, E> FnMut1<&'a Result<T, E>> for InspectOkFn<F>
 where
-    F: FnMut1<&'a T, Output=()>,
+    F: FnMut1<&'a T, Output = ()>,
 {
     fn call_mut(&mut self, arg: &'a Result<T, E>) -> Self::Output {
-        if let Ok(x) = arg { self.0.call_mut(x) }
+        if let Ok(x) = arg {
+            self.0.call_mut(x)
+        }
     }
 }
 impl<'a, F, T, E> Fn1<&'a Result<T, E>> for InspectOkFn<F>
 where
-    F: Fn1<&'a T, Output=()>,
+    F: Fn1<&'a T, Output = ()>,
 {
     fn call(&self, arg: &'a Result<T, E>) -> Self::Output {
-        if let Ok(x) = arg { self.0.call(x) }
+        if let Ok(x) = arg {
+            self.0.call(x)
+        }
     }
 }
 pub(crate) fn inspect_ok_fn<F>(f: F) -> InspectOkFn<F> {
@@ -276,27 +282,33 @@ pub struct InspectErrFn<F>(F);
 
 impl<'a, F, T, E> FnOnce1<&'a Result<T, E>> for InspectErrFn<F>
 where
-    F: FnOnce1<&'a E, Output=()>
+    F: FnOnce1<&'a E, Output = ()>,
 {
     type Output = ();
     fn call_once(self, arg: &'a Result<T, E>) -> Self::Output {
-        if let Err(x) = arg { self.0.call_once(x) }
+        if let Err(x) = arg {
+            self.0.call_once(x)
+        }
     }
 }
 impl<'a, F, T, E> FnMut1<&'a Result<T, E>> for InspectErrFn<F>
 where
-    F: FnMut1<&'a E, Output=()>,
+    F: FnMut1<&'a E, Output = ()>,
 {
     fn call_mut(&mut self, arg: &'a Result<T, E>) -> Self::Output {
-        if let Err(x) = arg { self.0.call_mut(x) }
+        if let Err(x) = arg {
+            self.0.call_mut(x)
+        }
     }
 }
 impl<'a, F, T, E> Fn1<&'a Result<T, E>> for InspectErrFn<F>
 where
-    F: Fn1<&'a E, Output=()>,
+    F: Fn1<&'a E, Output = ()>,
 {
     fn call(&self, arg: &'a Result<T, E>) -> Self::Output {
-        if let Err(x) = arg { self.0.call(x) }
+        if let Err(x) = arg {
+            self.0.call(x)
+        }
     }
 }
 pub(crate) fn inspect_err_fn<F>(f: F) -> InspectErrFn<F> {
@@ -313,7 +325,7 @@ pub struct UnwrapOrElseFn<F>(F);
 
 impl<F, T, E> FnOnce1<Result<T, E>> for UnwrapOrElseFn<F>
 where
-    F: FnOnce1<E, Output=T>,
+    F: FnOnce1<E, Output = T>,
 {
     type Output = T;
     fn call_once(self, arg: Result<T, E>) -> Self::Output {
@@ -322,7 +334,7 @@ where
 }
 impl<F, T, E> FnMut1<Result<T, E>> for UnwrapOrElseFn<F>
 where
-    F: FnMut1<E, Output=T>,
+    F: FnMut1<E, Output = T>,
 {
     fn call_mut(&mut self, arg: Result<T, E>) -> Self::Output {
         arg.unwrap_or_else(|x| self.0.call_mut(x))
@@ -330,7 +342,7 @@ where
 }
 impl<F, T, E> Fn1<Result<T, E>> for UnwrapOrElseFn<F>
 where
-    F: Fn1<E, Output=T>,
+    F: Fn1<E, Output = T>,
 {
     fn call(&self, arg: Result<T, E>) -> Self::Output {
         arg.unwrap_or_else(|x| self.0.call(x))
@@ -347,7 +359,10 @@ impl<T> Default for IntoFn<T> {
         Self(PhantomData)
     }
 }
-impl<A, T> FnOnce1<A> for IntoFn<T> where A: Into<T> {
+impl<A, T> FnOnce1<A> for IntoFn<T>
+where
+    A: Into<T>,
+{
     type Output = T;
     fn call_once(self, arg: A) -> Self::Output {
         arg.into()
diff --git a/third_party/rust/futures-util/src/future/abortable.rs b/third_party/rust/futures-util/src/future/abortable.rs
index 1fc75b08fc201a1636c0feaf9cac458337ff1ba2..d017ab7340c1d395fb7d1540092e2d0736a062e8 100644
--- a/third_party/rust/futures-util/src/future/abortable.rs
+++ b/third_party/rust/futures-util/src/future/abortable.rs
@@ -1,109 +1,8 @@
-use crate::task::AtomicWaker;
+use super::assert_future;
+use crate::future::{AbortHandle, Abortable, Aborted};
 use futures_core::future::Future;
-use futures_core::task::{Context, Poll};
-use core::fmt;
-use core::pin::Pin;
-use core::sync::atomic::{AtomicBool, Ordering};
-use alloc::sync::Arc;
-use pin_project_lite::pin_project;
 
-pin_project! {
-    /// A future which can be remotely short-circuited using an `AbortHandle`.
-    #[derive(Debug, Clone)]
-    #[must_use = "futures do nothing unless you `.await` or poll them"]
-    pub struct Abortable<Fut> {
-        #[pin]
-        future: Fut,
-        inner: Arc<AbortInner>,
-    }
-}
-
-impl<Fut> Abortable<Fut> where Fut: Future {
-    /// Creates a new `Abortable` future using an existing `AbortRegistration`.
-    /// `AbortRegistration`s can be acquired through `AbortHandle::new`.
-    ///
-    /// When `abort` is called on the handle tied to `reg` or if `abort` has
-    /// already been called, the future will complete immediately without making
-    /// any further progress.
-    ///
-    /// Example:
-    ///
-    /// ```
-    /// # futures::executor::block_on(async {
-    /// use futures::future::{Abortable, AbortHandle, Aborted};
-    ///
-    /// let (abort_handle, abort_registration) = AbortHandle::new_pair();
-    /// let future = Abortable::new(async { 2 }, abort_registration);
-    /// abort_handle.abort();
-    /// assert_eq!(future.await, Err(Aborted));
-    /// # });
-    /// ```
-    pub fn new(future: Fut, reg: AbortRegistration) -> Self {
-        Self {
-            future,
-            inner: reg.inner,
-        }
-    }
-}
-
-/// A registration handle for a `Abortable` future.
-/// Values of this type can be acquired from `AbortHandle::new` and are used
-/// in calls to `Abortable::new`.
-#[derive(Debug)]
-pub struct AbortRegistration {
-    inner: Arc<AbortInner>,
-}
-
-/// A handle to a `Abortable` future.
-#[derive(Debug, Clone)]
-pub struct AbortHandle {
-    inner: Arc<AbortInner>,
-}
-
-impl AbortHandle {
-    /// Creates an (`AbortHandle`, `AbortRegistration`) pair which can be used
-    /// to abort a running future.
-    ///
-    /// This function is usually paired with a call to `Abortable::new`.
-    ///
-    /// Example:
-    ///
-    /// ```
-    /// # futures::executor::block_on(async {
-    /// use futures::future::{Abortable, AbortHandle, Aborted};
-    ///
-    /// let (abort_handle, abort_registration) = AbortHandle::new_pair();
-    /// let future = Abortable::new(async { 2 }, abort_registration);
-    /// abort_handle.abort();
-    /// assert_eq!(future.await, Err(Aborted));
-    /// # });
-    /// ```
-    pub fn new_pair() -> (Self, AbortRegistration) {
-        let inner = Arc::new(AbortInner {
-            waker: AtomicWaker::new(),
-            cancel: AtomicBool::new(false),
-        });
-
-        (
-            Self {
-                inner: inner.clone(),
-            },
-            AbortRegistration {
-                inner,
-            },
-        )
-    }
-}
-
-// Inner type storing the waker to awaken and a bool indicating that it
-// should be cancelled.
-#[derive(Debug)]
-struct AbortInner {
-    waker: AtomicWaker,
-    cancel: AtomicBool,
-}
-
-/// Creates a new `Abortable` future and a `AbortHandle` which can be used to stop it.
+/// Creates a new `Abortable` future and an `AbortHandle` which can be used to stop it.
 ///
 /// This function is a convenient (but less flexible) alternative to calling
 /// `AbortHandle::new` and `Abortable::new` manually.
@@ -111,66 +10,10 @@ struct AbortInner {
 /// This function is only available when the `std` or `alloc` feature of this
 /// library is activated, and it is activated by default.
 pub fn abortable<Fut>(future: Fut) -> (Abortable<Fut>, AbortHandle)
-    where Fut: Future
+where
+    Fut: Future,
 {
     let (handle, reg) = AbortHandle::new_pair();
-    (
-        Abortable::new(future, reg),
-        handle,
-    )
-}
-
-/// Indicator that the `Abortable` future was aborted.
-#[derive(Copy, Clone, Debug, Eq, PartialEq)]
-pub struct Aborted;
-
-impl fmt::Display for Aborted {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        write!(f, "`Abortable` future has been aborted")
-    }
-}
-
-#[cfg(feature = "std")]
-impl std::error::Error for Aborted {}
-
-impl<Fut> Future for Abortable<Fut> where Fut: Future {
-    type Output = Result<Fut::Output, Aborted>;
-
-    fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
-        // Check if the future has been aborted
-        if self.inner.cancel.load(Ordering::Relaxed) {
-            return Poll::Ready(Err(Aborted))
-        }
-
-        // attempt to complete the future
-        if let Poll::Ready(x) = self.as_mut().project().future.poll(cx) {
-            return Poll::Ready(Ok(x))
-        }
-
-        // Register to receive a wakeup if the future is aborted in the... future
-        self.inner.waker.register(cx.waker());
-
-        // Check to see if the future was aborted between the first check and
-        // registration.
-        // Checking with `Relaxed` is sufficient because `register` introduces an
-        // `AcqRel` barrier.
-        if self.inner.cancel.load(Ordering::Relaxed) {
-            return Poll::Ready(Err(Aborted))
-        }
-
-        Poll::Pending
-    }
-}
-
-impl AbortHandle {
-    /// Abort the `Abortable` future associated with this handle.
-    ///
-    /// Notifies the Abortable future associated with this handle that it
-    /// should abort. Note that if the future is currently being polled on
-    /// another thread, it will not immediately stop running. Instead, it will
-    /// continue to run until its poll method returns.
-    pub fn abort(&self) {
-        self.inner.cancel.store(true, Ordering::Relaxed);
-        self.inner.waker.wake();
-    }
+    let abortable = assert_future::<Result<Fut::Output, Aborted>, _>(Abortable::new(future, reg));
+    (abortable, handle)
 }
diff --git a/third_party/rust/futures-util/src/future/either.rs b/third_party/rust/futures-util/src/future/either.rs
index a1b9f0a9b32eaf373332cca146c544fc3e510538..35650daa998630a41b9835654d5eeb216e010be7 100644
--- a/third_party/rust/futures-util/src/future/either.rs
+++ b/third_party/rust/futures-util/src/future/either.rs
@@ -5,8 +5,25 @@ use futures_core::stream::{FusedStream, Stream};
 #[cfg(feature = "sink")]
 use futures_sink::Sink;
 
-/// Combines two different futures, streams, or sinks having the same associated types into a single
-/// type.
+/// Combines two different futures, streams, or sinks having the same associated types into a single type.
+///
+/// This is useful when conditionally choosing between two distinct future types:
+///
+/// ```rust
+/// use futures::future::Either;
+///
+/// # futures::executor::block_on(async {
+/// let cond = true;
+///
+/// let fut = if cond {
+///     Either::Left(async move { 12 })
+/// } else {
+///     Either::Right(async move { 44 })
+/// };
+///
+/// assert_eq!(fut.await, 12);
+/// # })
+/// ```
 #[derive(Debug, Clone)]
 pub enum Either<A, B> {
     /// First branch of the type
@@ -101,6 +118,13 @@ where
             Either::Right(x) => x.poll_next(cx),
         }
     }
+
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        match self {
+            Either::Left(x) => x.size_hint(),
+            Either::Right(x) => x.size_hint(),
+        }
+    }
 }
 
 impl<A, B> FusedStream for Either<A, B>
diff --git a/third_party/rust/futures-util/src/future/future/catch_unwind.rs b/third_party/rust/futures-util/src/future/future/catch_unwind.rs
index 3f16577788d4e67f288347e6f0e907500adc7f9c..0e09d6eeb0f57fe1edd087ce2a3a380fad2381cb 100644
--- a/third_party/rust/futures-util/src/future/future/catch_unwind.rs
+++ b/third_party/rust/futures-util/src/future/future/catch_unwind.rs
@@ -1,6 +1,6 @@
 use core::any::Any;
 use core::pin::Pin;
-use std::panic::{catch_unwind, UnwindSafe, AssertUnwindSafe};
+use std::panic::{catch_unwind, AssertUnwindSafe, UnwindSafe};
 
 use futures_core::future::Future;
 use futures_core::task::{Context, Poll};
@@ -16,14 +16,18 @@ pin_project! {
     }
 }
 
-impl<Fut> CatchUnwind<Fut> where Fut: Future + UnwindSafe {
+impl<Fut> CatchUnwind<Fut>
+where
+    Fut: Future + UnwindSafe,
+{
     pub(super) fn new(future: Fut) -> Self {
         Self { future }
     }
 }
 
 impl<Fut> Future for CatchUnwind<Fut>
-    where Fut: Future + UnwindSafe,
+where
+    Fut: Future + UnwindSafe,
 {
     type Output = Result<Fut::Output, Box<dyn Any + Send>>;
 
diff --git a/third_party/rust/futures-util/src/future/future/flatten.rs b/third_party/rust/futures-util/src/future/future/flatten.rs
index 0c48a4f1d40b5135f42ccaea1f0c7fe8467c6d7f..bd767af344b4e3a313424b96f51cb1bf1acabead 100644
--- a/third_party/rust/futures-util/src/future/future/flatten.rs
+++ b/third_party/rust/futures-util/src/future/future/flatten.rs
@@ -2,9 +2,9 @@ use core::pin::Pin;
 use futures_core::future::{FusedFuture, Future};
 use futures_core::ready;
 use futures_core::stream::{FusedStream, Stream};
+use futures_core::task::{Context, Poll};
 #[cfg(feature = "sink")]
 use futures_sink::Sink;
-use futures_core::task::{Context, Poll};
 use pin_project_lite::pin_project;
 
 pin_project! {
@@ -24,8 +24,9 @@ impl<Fut1, Fut2> Flatten<Fut1, Fut2> {
 }
 
 impl<Fut> FusedFuture for Flatten<Fut, Fut::Output>
-    where Fut: Future,
-          Fut::Output: Future,
+where
+    Fut: Future,
+    Fut::Output: Future,
 {
     fn is_terminated(&self) -> bool {
         match self {
@@ -36,8 +37,9 @@ impl<Fut> FusedFuture for Flatten<Fut, Fut::Output>
 }
 
 impl<Fut> Future for Flatten<Fut, Fut::Output>
-    where Fut: Future,
-          Fut::Output: Future,
+where
+    Fut: Future,
+    Fut::Output: Future,
 {
     type Output = <Fut::Output as Future>::Output;
 
@@ -47,12 +49,12 @@ impl<Fut> Future for Flatten<Fut, Fut::Output>
                 FlattenProj::First { f } => {
                     let f = ready!(f.poll(cx));
                     self.set(Self::Second { f });
-                },
+                }
                 FlattenProj::Second { f } => {
                     let output = ready!(f.poll(cx));
                     self.set(Self::Empty);
                     break output;
-                },
+                }
                 FlattenProj::Empty => panic!("Flatten polled after completion"),
             }
         })
@@ -60,8 +62,9 @@ impl<Fut> Future for Flatten<Fut, Fut::Output>
 }
 
 impl<Fut> FusedStream for Flatten<Fut, Fut::Output>
-    where Fut: Future,
-          Fut::Output: Stream,
+where
+    Fut: Future,
+    Fut::Output: Stream,
 {
     fn is_terminated(&self) -> bool {
         match self {
@@ -72,32 +75,32 @@ impl<Fut> FusedStream for Flatten<Fut, Fut::Output>
 }
 
 impl<Fut> Stream for Flatten<Fut, Fut::Output>
-    where Fut: Future,
-          Fut::Output: Stream,
+where
+    Fut: Future,
+    Fut::Output: Stream,
 {
     type Item = <Fut::Output as Stream>::Item;
 
     fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
         Poll::Ready(loop {
             match self.as_mut().project() {
-                FlattenProj::First { f }  => {
+                FlattenProj::First { f } => {
                     let f = ready!(f.poll(cx));
                     self.set(Self::Second { f });
-                },
+                }
                 FlattenProj::Second { f } => {
                     let output = ready!(f.poll_next(cx));
                     if output.is_none() {
                         self.set(Self::Empty);
                     }
                     break output;
-                },
+                }
                 FlattenProj::Empty => break None,
             }
         })
     }
 }
 
-
 #[cfg(feature = "sink")]
 impl<Fut, Item> Sink<Item> for Flatten<Fut, Fut::Output>
 where
@@ -106,19 +109,16 @@ where
 {
     type Error = <Fut::Output as Sink<Item>>::Error;
 
-    fn poll_ready(
-        mut self: Pin<&mut Self>,
-        cx: &mut Context<'_>,
-    ) -> Poll<Result<(), Self::Error>> {
+    fn poll_ready(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
         Poll::Ready(loop {
             match self.as_mut().project() {
                 FlattenProj::First { f } => {
                     let f = ready!(f.poll(cx));
                     self.set(Self::Second { f });
-                },
+                }
                 FlattenProj::Second { f } => {
                     break ready!(f.poll_ready(cx));
-                },
+                }
                 FlattenProj::Empty => panic!("poll_ready called after eof"),
             }
         })
@@ -140,10 +140,7 @@ where
         }
     }
 
-    fn poll_close(
-        mut self: Pin<&mut Self>,
-        cx: &mut Context<'_>,
-    ) -> Poll<Result<(), Self::Error>> {
+    fn poll_close(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
         let res = match self.as_mut().project() {
             FlattenProj::Second { f } => f.poll_close(cx),
             _ => Poll::Ready(Ok(())),
diff --git a/third_party/rust/futures-util/src/future/future/fuse.rs b/third_party/rust/futures-util/src/future/future/fuse.rs
index f4284ba373e08173bddef7eccff67415fecaa332..597aec1a4011b08afcf7c8472992cdcb3214a6ad 100644
--- a/third_party/rust/futures-util/src/future/future/fuse.rs
+++ b/third_party/rust/futures-util/src/future/future/fuse.rs
@@ -1,5 +1,5 @@
 use core::pin::Pin;
-use futures_core::future::{Future, FusedFuture};
+use futures_core::future::{FusedFuture, Future};
 use futures_core::ready;
 use futures_core::task::{Context, Poll};
 use pin_project_lite::pin_project;
@@ -86,7 +86,7 @@ impl<Fut: Future> Future for Fuse<Fut> {
                 let output = ready!(fut.poll(cx));
                 self.project().inner.set(None);
                 output
-            },
+            }
             None => return Poll::Pending,
         })
     }
diff --git a/third_party/rust/futures-util/src/future/future/mod.rs b/third_party/rust/futures-util/src/future/future/mod.rs
index f01d3462f7569b4b9cc52fc95b0013dc0d122156..c11d108207ea32bdc57662aaae2f6f1dacf754d4 100644
--- a/third_party/rust/futures-util/src/future/future/mod.rs
+++ b/third_party/rust/futures-util/src/future/future/mod.rs
@@ -7,10 +7,10 @@
 use alloc::boxed::Box;
 use core::pin::Pin;
 
-use crate::future::{assert_future, Either};
-use crate::stream::assert_stream;
 use crate::fns::{inspect_fn, into_fn, ok_fn, InspectFn, IntoFn, OkFn};
+use crate::future::{assert_future, Either};
 use crate::never::Never;
+use crate::stream::assert_stream;
 #[cfg(feature = "alloc")]
 use futures_core::future::{BoxFuture, LocalBoxFuture};
 use futures_core::{
@@ -506,7 +506,8 @@ pub trait FutureExt: Future {
     where
         Self: Sized,
     {
-        remote_handle::remote_handle(self)
+        let (wrapped, handle) = remote_handle::remote_handle(self);
+        (assert_future::<(), _>(wrapped), handle)
     }
 
     /// Wrap the future in a Box, pinning it.
diff --git a/third_party/rust/futures-util/src/future/future/remote_handle.rs b/third_party/rust/futures-util/src/future/future/remote_handle.rs
index 0d33ea5189f1422f2934c951c5ffa0300c1c3ad9..1358902cabf4523e6cd59d51cf97fb94264102a8 100644
--- a/third_party/rust/futures-util/src/future/future/remote_handle.rs
+++ b/third_party/rust/futures-util/src/future/future/remote_handle.rs
@@ -1,23 +1,23 @@
 use {
     crate::future::{CatchUnwind, FutureExt},
-    futures_channel::oneshot::{self, Sender, Receiver},
+    futures_channel::oneshot::{self, Receiver, Sender},
     futures_core::{
         future::Future,
-        task::{Context, Poll},
         ready,
+        task::{Context, Poll},
     },
+    pin_project_lite::pin_project,
     std::{
         any::Any,
         fmt,
         panic::{self, AssertUnwindSafe},
         pin::Pin,
         sync::{
-            Arc,
             atomic::{AtomicBool, Ordering},
+            Arc,
         },
         thread,
     },
-    pin_project_lite::pin_project,
 };
 
 /// The handle to a remote future returned by
@@ -36,7 +36,7 @@ use {
 /// must be careful with regard to unwind safety because the thread in which the future
 /// is polled will keep running after the panic and the thread running the [RemoteHandle]
 /// will unwind.
-#[must_use = "futures do nothing unless you `.await` or poll them"]
+#[must_use = "dropping a remote handle cancels the underlying future"]
 #[derive(Debug)]
 #[cfg_attr(docsrs, doc(cfg(feature = "channel")))]
 pub struct RemoteHandle<T> {
@@ -85,9 +85,7 @@ pin_project! {
 
 impl<Fut: Future + fmt::Debug> fmt::Debug for Remote<Fut> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.debug_tuple("Remote")
-            .field(&self.future)
-            .finish()
+        f.debug_tuple("Remote").field(&self.future).finish()
     }
 }
 
diff --git a/third_party/rust/futures-util/src/future/future/shared.rs b/third_party/rust/futures-util/src/future/future/shared.rs
index 53635b5582d1772ea6a45869eedcad13ee93f343..9b31932fe3ee90854601549728e266cff64ded7d 100644
--- a/third_party/rust/futures-util/src/future/future/shared.rs
+++ b/third_party/rust/futures-util/src/future/future/shared.rs
@@ -29,6 +29,12 @@ struct Notifier {
 /// A weak reference to a [`Shared`] that can be upgraded much like an `Arc`.
 pub struct WeakShared<Fut: Future>(Weak<Inner<Fut>>);
 
+impl<Fut: Future> Clone for WeakShared<Fut> {
+    fn clone(&self) -> Self {
+        Self(self.0.clone())
+    }
+}
+
 // The future itself is polled behind the `Arc`, so it won't be moved
 // when `Shared` is moved.
 impl<Fut: Future> Unpin for Shared<Fut> {}
@@ -90,10 +96,7 @@ impl<Fut: Future> Shared<Fut> {
             }),
         };
 
-        Self {
-            inner: Some(Arc::new(inner)),
-            waker_key: NULL_WAKER_KEY,
-        }
+        Self { inner: Some(Arc::new(inner)), waker_key: NULL_WAKER_KEY }
     }
 }
 
@@ -126,6 +129,32 @@ where
         }
         None
     }
+
+    /// Gets the number of strong pointers to this allocation.
+    ///
+    /// Returns [`None`] if it has already been polled to completion.
+    ///
+    /// # Safety
+    ///
+    /// This method by itself is safe, but using it correctly requires extra care. Another thread
+    /// can change the strong count at any time, including potentially between calling this method
+    /// and acting on the result.
+    pub fn strong_count(&self) -> Option<usize> {
+        self.inner.as_ref().map(|arc| Arc::strong_count(arc))
+    }
+
+    /// Gets the number of weak pointers to this allocation.
+    ///
+    /// Returns [`None`] if it has already been polled to completion.
+    ///
+    /// # Safety
+    ///
+    /// This method by itself is safe, but using it correctly requires extra care. Another thread
+    /// can change the weak count at any time, including potentially between calling this method
+    /// and acting on the result.
+    pub fn weak_count(&self) -> Option<usize> {
+        self.inner.as_ref().map(|arc| Arc::weak_count(arc))
+    }
 }
 
 impl<Fut> Inner<Fut>
@@ -197,10 +226,7 @@ where
     fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
         let this = &mut *self;
 
-        let inner = this
-            .inner
-            .take()
-            .expect("Shared future polled again after completion");
+        let inner = this.inner.take().expect("Shared future polled again after completion");
 
         // Fast path for when the wrapped future has already completed
         if inner.notifier.state.load(Acquire) == COMPLETE {
@@ -260,11 +286,7 @@ where
 
             match future.poll(&mut cx) {
                 Poll::Pending => {
-                    if inner
-                        .notifier
-                        .state
-                        .compare_exchange(POLLING, IDLE, SeqCst, SeqCst)
-                        .is_ok()
+                    if inner.notifier.state.compare_exchange(POLLING, IDLE, SeqCst, SeqCst).is_ok()
                     {
                         // Success
                         drop(_reset);
@@ -287,10 +309,8 @@ where
         // Wake all tasks and drop the slab
         let mut wakers_guard = inner.notifier.wakers.lock().unwrap();
         let mut wakers = wakers_guard.take().unwrap();
-        for opt_waker in wakers.drain() {
-            if let Some(waker) = opt_waker {
-                waker.wake();
-            }
+        for waker in wakers.drain().flatten() {
+            waker.wake();
         }
 
         drop(_reset); // Make borrow checker happy
@@ -306,10 +326,7 @@ where
     Fut: Future,
 {
     fn clone(&self) -> Self {
-        Self {
-            inner: self.inner.clone(),
-            waker_key: NULL_WAKER_KEY,
-        }
+        Self { inner: self.inner.clone(), waker_key: NULL_WAKER_KEY }
     }
 }
 
@@ -343,16 +360,12 @@ impl ArcWake for Notifier {
     }
 }
 
-impl<Fut: Future> WeakShared<Fut>
-{
+impl<Fut: Future> WeakShared<Fut> {
     /// Attempts to upgrade this [`WeakShared`] into a [`Shared`].
     ///
     /// Returns [`None`] if all clones of the [`Shared`] have been dropped or polled
     /// to completion.
     pub fn upgrade(&self) -> Option<Shared<Fut>> {
-        Some(Shared {
-            inner: Some(self.0.upgrade()?),
-            waker_key: NULL_WAKER_KEY,
-        })
+        Some(Shared { inner: Some(self.0.upgrade()?), waker_key: NULL_WAKER_KEY })
     }
 }
diff --git a/third_party/rust/futures-util/src/future/join.rs b/third_party/rust/futures-util/src/future/join.rs
index cfe53a72c8e78e892ebe0de52f8f94008945462e..740ffbc98802b09dec0b50d0755f991a85bae824 100644
--- a/third_party/rust/futures-util/src/future/join.rs
+++ b/third_party/rust/futures-util/src/future/join.rs
@@ -1,14 +1,13 @@
 #![allow(non_snake_case)]
 
-use crate::future::{MaybeDone, maybe_done};
+use super::assert_future;
+use crate::future::{maybe_done, MaybeDone};
 use core::fmt;
 use core::pin::Pin;
-use futures_core::future::{Future, FusedFuture};
+use futures_core::future::{FusedFuture, Future};
 use futures_core::task::{Context, Poll};
 use pin_project_lite::pin_project;
 
-use super::assert_future;
-
 macro_rules! generate {
     ($(
         $(#[$doc:meta])*
@@ -144,7 +143,8 @@ where
     Fut2: Future,
     Fut3: Future,
 {
-    Join3::new(future1, future2, future3)
+    let f = Join3::new(future1, future2, future3);
+    assert_future::<(Fut1::Output, Fut2::Output, Fut3::Output), _>(f)
 }
 
 /// Same as [`join`](join()), but with more futures.
@@ -176,7 +176,8 @@ where
     Fut3: Future,
     Fut4: Future,
 {
-    Join4::new(future1, future2, future3, future4)
+    let f = Join4::new(future1, future2, future3, future4);
+    assert_future::<(Fut1::Output, Fut2::Output, Fut3::Output, Fut4::Output), _>(f)
 }
 
 /// Same as [`join`](join()), but with more futures.
@@ -211,5 +212,6 @@ where
     Fut4: Future,
     Fut5: Future,
 {
-    Join5::new(future1, future2, future3, future4, future5)
+    let f = Join5::new(future1, future2, future3, future4, future5);
+    assert_future::<(Fut1::Output, Fut2::Output, Fut3::Output, Fut4::Output, Fut5::Output), _>(f)
 }
diff --git a/third_party/rust/futures-util/src/future/join_all.rs b/third_party/rust/futures-util/src/future/join_all.rs
index 0c8357ca68a49903fe4ef0735661bf6e48815d85..427e71ce04915d30fe531b7bbee8174eb09c113a 100644
--- a/third_party/rust/futures-util/src/future/join_all.rs
+++ b/third_party/rust/futures-util/src/future/join_all.rs
@@ -1,24 +1,22 @@
 //! Definition of the `JoinAll` combinator, waiting for all of a list of futures
 //! to finish.
 
+use alloc::boxed::Box;
+use alloc::vec::Vec;
 use core::fmt;
 use core::future::Future;
 use core::iter::FromIterator;
 use core::mem;
 use core::pin::Pin;
 use core::task::{Context, Poll};
-use alloc::boxed::Box;
-use alloc::vec::Vec;
 
-use super::MaybeDone;
+use super::{assert_future, MaybeDone};
 
 fn iter_pin_mut<T>(slice: Pin<&mut [T]>) -> impl Iterator<Item = Pin<&mut T>> {
     // Safety: `std` _could_ make this unsound if it were to decide Pin's
     // invariants aren't required to transmit through slices. Otherwise this has
     // the same safety as a normal field pin projection.
-    unsafe { slice.get_unchecked_mut() }
-        .iter_mut()
-        .map(|t| unsafe { Pin::new_unchecked(t) })
+    unsafe { slice.get_unchecked_mut() }.iter_mut().map(|t| unsafe { Pin::new_unchecked(t) })
 }
 
 /// Future for the [`join_all`] function.
@@ -36,9 +34,7 @@ where
     F::Output: fmt::Debug,
 {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.debug_struct("JoinAll")
-            .field("elems", &self.elems)
-            .finish()
+        f.debug_struct("JoinAll").field("elems", &self.elems).finish()
     }
 }
 
@@ -85,7 +81,7 @@ where
     I::Item: Future,
 {
     let elems: Box<[_]> = i.into_iter().map(MaybeDone::Future).collect();
-    JoinAll { elems: elems.into() }
+    assert_future::<Vec<<I::Item as Future>::Output>, _>(JoinAll { elems: elems.into() })
 }
 
 impl<F> Future for JoinAll<F>
@@ -105,9 +101,7 @@ where
 
         if all_done {
             let mut elems = mem::replace(&mut self.elems, Box::pin([]));
-            let result = iter_pin_mut(elems.as_mut())
-                .map(|e| e.take_output().unwrap())
-                .collect();
+            let result = iter_pin_mut(elems.as_mut()).map(|e| e.take_output().unwrap()).collect();
             Poll::Ready(result)
         } else {
             Poll::Pending
diff --git a/third_party/rust/futures-util/src/future/lazy.rs b/third_party/rust/futures-util/src/future/lazy.rs
index 409717a2ab4abf0e3007ca473f3c640ba1e844ce..e9a8cf2fa9ca3d322a2fa65ab40ae2fb93dc0978 100644
--- a/third_party/rust/futures-util/src/future/lazy.rs
+++ b/third_party/rust/futures-util/src/future/lazy.rs
@@ -1,3 +1,4 @@
+use super::assert_future;
 use core::pin::Pin;
 use futures_core::future::{FusedFuture, Future};
 use futures_core::task::{Context, Poll};
@@ -6,7 +7,7 @@ use futures_core::task::{Context, Poll};
 #[derive(Debug)]
 #[must_use = "futures do nothing unless you `.await` or poll them"]
 pub struct Lazy<F> {
-    f: Option<F>
+    f: Option<F>,
 }
 
 // safe because we never generate `Pin<&mut F>`
@@ -32,19 +33,24 @@ impl<F> Unpin for Lazy<F> {}
 /// # });
 /// ```
 pub fn lazy<F, R>(f: F) -> Lazy<F>
-    where F: FnOnce(&mut Context<'_>) -> R,
+where
+    F: FnOnce(&mut Context<'_>) -> R,
 {
-    Lazy { f: Some(f) }
+    assert_future::<R, _>(Lazy { f: Some(f) })
 }
 
 impl<F, R> FusedFuture for Lazy<F>
-    where F: FnOnce(&mut Context<'_>) -> R,
+where
+    F: FnOnce(&mut Context<'_>) -> R,
 {
-    fn is_terminated(&self) -> bool { self.f.is_none() }
+    fn is_terminated(&self) -> bool {
+        self.f.is_none()
+    }
 }
 
 impl<F, R> Future for Lazy<F>
-    where F: FnOnce(&mut Context<'_>) -> R,
+where
+    F: FnOnce(&mut Context<'_>) -> R,
 {
     type Output = R;
 
diff --git a/third_party/rust/futures-util/src/future/maybe_done.rs b/third_party/rust/futures-util/src/future/maybe_done.rs
index bb5579e8599ad483559983b34f1cdce910f84009..26e6c2758810fc20b97a77372e1eb6f988e198b1 100644
--- a/third_party/rust/futures-util/src/future/maybe_done.rs
+++ b/third_party/rust/futures-util/src/future/maybe_done.rs
@@ -1,5 +1,6 @@
 //! Definition of the MaybeDone combinator
 
+use super::assert_future;
 use core::mem;
 use core::pin::Pin;
 use futures_core::future::{FusedFuture, Future};
@@ -40,7 +41,7 @@ impl<Fut: Future + Unpin> Unpin for MaybeDone<Fut> {}
 /// # });
 /// ```
 pub fn maybe_done<Fut: Future>(future: Fut) -> MaybeDone<Fut> {
-    MaybeDone::Future(future)
+    assert_future::<(), _>(MaybeDone::Future(future))
 }
 
 impl<Fut: Future> MaybeDone<Fut> {
diff --git a/third_party/rust/futures-util/src/future/mod.rs b/third_party/rust/futures-util/src/future/mod.rs
index ab29823a26eb426cf1bdb222aba3ae3c15ef59d3..7a63e5ff8586db239b600e0495f9b2db7c3f4086 100644
--- a/third_party/rust/futures-util/src/future/mod.rs
+++ b/third_party/rust/futures-util/src/future/mod.rs
@@ -9,16 +9,19 @@
 //!   from a closure that defines its return value, and [`ready`](ready()),
 //!   which constructs a future with an immediate defined value.
 
+#[doc(no_inline)]
+pub use core::future::Future;
+
 #[cfg(feature = "alloc")]
 pub use futures_core::future::{BoxFuture, LocalBoxFuture};
-pub use futures_core::future::{FusedFuture, Future, TryFuture};
+pub use futures_core::future::{FusedFuture, TryFuture};
 pub use futures_task::{FutureObj, LocalFutureObj, UnsafeFutureObj};
 
 // Extension traits and combinators
 #[allow(clippy::module_inception)]
 mod future;
 pub use self::future::{
-    Flatten, Fuse, FutureExt, Inspect, IntoStream, Map, NeverError, Then, UnitError, MapInto,
+    Flatten, Fuse, FutureExt, Inspect, IntoStream, Map, MapInto, NeverError, Then, UnitError,
 };
 
 #[deprecated(note = "This is now an alias for [Flatten](Flatten)")]
@@ -37,8 +40,8 @@ pub use self::future::{Shared, WeakShared};
 
 mod try_future;
 pub use self::try_future::{
-    AndThen, ErrInto, OkInto, InspectErr, InspectOk, IntoFuture, MapErr, MapOk, OrElse, TryFlattenStream,
-    TryFutureExt, UnwrapOrElse, MapOkOrElse, TryFlatten,
+    AndThen, ErrInto, InspectErr, InspectOk, IntoFuture, MapErr, MapOk, MapOkOrElse, OkInto,
+    OrElse, TryFlatten, TryFlattenStream, TryFutureExt, UnwrapOrElse,
 };
 
 #[cfg(feature = "sink")]
@@ -109,7 +112,9 @@ cfg_target_has_atomic! {
     #[cfg(feature = "alloc")]
     mod abortable;
     #[cfg(feature = "alloc")]
-    pub use self::abortable::{abortable, Abortable, AbortHandle, AbortRegistration, Aborted};
+    pub use crate::abortable::{Abortable, AbortHandle, AbortRegistration, Aborted};
+    #[cfg(feature = "alloc")]
+    pub use abortable::abortable;
 }
 
 // Just a helper function to ensure the futures we're returning all have the
diff --git a/third_party/rust/futures-util/src/future/option.rs b/third_party/rust/futures-util/src/future/option.rs
index 85939d6b1a6bbdbd8b5e7f8cf855fd0196957cbe..426fe50feaa02433ad40f45cb32e27a4b182731a 100644
--- a/third_party/rust/futures-util/src/future/option.rs
+++ b/third_party/rust/futures-util/src/future/option.rs
@@ -1,7 +1,7 @@
 //! Definition of the `Option` (optional step) combinator
 
 use core::pin::Pin;
-use futures_core::future::{Future, FusedFuture};
+use futures_core::future::{FusedFuture, Future};
 use futures_core::task::{Context, Poll};
 use pin_project_lite::pin_project;
 
@@ -34,10 +34,7 @@ pin_project! {
 impl<F: Future> Future for OptionFuture<F> {
     type Output = Option<F::Output>;
 
-    fn poll(
-        self: Pin<&mut Self>,
-        cx: &mut Context<'_>,
-    ) -> Poll<Self::Output> {
+    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
         match self.project().inner.as_pin_mut() {
             Some(x) => x.poll(cx).map(Some),
             None => Poll::Ready(None),
diff --git a/third_party/rust/futures-util/src/future/pending.rs b/third_party/rust/futures-util/src/future/pending.rs
index 5a7bbb8d59683303fadfc3160b82afc85c95053f..92c78d52b800553f31510e19d507b6e43dd3f8da 100644
--- a/third_party/rust/futures-util/src/future/pending.rs
+++ b/third_party/rust/futures-util/src/future/pending.rs
@@ -1,3 +1,4 @@
+use super::assert_future;
 use core::marker;
 use core::pin::Pin;
 use futures_core::future::{FusedFuture, Future};
@@ -33,9 +34,7 @@ impl<T> FusedFuture for Pending<T> {
 /// # });
 /// ```
 pub fn pending<T>() -> Pending<T> {
-    Pending {
-        _data: marker::PhantomData,
-    }
+    assert_future::<T, _>(Pending { _data: marker::PhantomData })
 }
 
 impl<T> Future for Pending<T> {
@@ -46,8 +45,7 @@ impl<T> Future for Pending<T> {
     }
 }
 
-impl<T> Unpin for Pending<T> {
-}
+impl<T> Unpin for Pending<T> {}
 
 impl<T> Clone for Pending<T> {
     fn clone(&self) -> Self {
diff --git a/third_party/rust/futures-util/src/future/poll_fn.rs b/third_party/rust/futures-util/src/future/poll_fn.rs
index b7b10be85d8b4c71bce8b276b93d4c4615e7647a..19311570b5fc9356f65bb16ffd2f73f696c3a008 100644
--- a/third_party/rust/futures-util/src/future/poll_fn.rs
+++ b/third_party/rust/futures-util/src/future/poll_fn.rs
@@ -1,5 +1,6 @@
 //! Definition of the `PollFn` adapter combinator
 
+use super::assert_future;
 use core::fmt;
 use core::pin::Pin;
 use futures_core::future::Future;
@@ -34,9 +35,9 @@ impl<F> Unpin for PollFn<F> {}
 /// ```
 pub fn poll_fn<T, F>(f: F) -> PollFn<F>
 where
-    F: FnMut(&mut Context<'_>) -> Poll<T>
+    F: FnMut(&mut Context<'_>) -> Poll<T>,
 {
-    PollFn { f }
+    assert_future::<T, _>(PollFn { f })
 }
 
 impl<F> fmt::Debug for PollFn<F> {
@@ -46,7 +47,8 @@ impl<F> fmt::Debug for PollFn<F> {
 }
 
 impl<T, F> Future for PollFn<F>
-    where F: FnMut(&mut Context<'_>) -> Poll<T>,
+where
+    F: FnMut(&mut Context<'_>) -> Poll<T>,
 {
     type Output = T;
 
diff --git a/third_party/rust/futures-util/src/future/ready.rs b/third_party/rust/futures-util/src/future/ready.rs
index 35f01c9b163e6b7f58466cb818f54c9a5b251a76..e3d791b3cf25c16131d12169fb34655cb7b5b46d 100644
--- a/third_party/rust/futures-util/src/future/ready.rs
+++ b/third_party/rust/futures-util/src/future/ready.rs
@@ -1,3 +1,4 @@
+use super::assert_future;
 use core::pin::Pin;
 use futures_core::future::{FusedFuture, Future};
 use futures_core::task::{Context, Poll};
@@ -45,7 +46,7 @@ impl<T> Future for Ready<T> {
 /// # });
 /// ```
 pub fn ready<T>(t: T) -> Ready<T> {
-    Ready(Some(t))
+    assert_future::<T, _>(Ready(Some(t)))
 }
 
 /// Create a future that is immediately ready with a success value.
diff --git a/third_party/rust/futures-util/src/future/select.rs b/third_party/rust/futures-util/src/future/select.rs
index bc247796dd7c0d733ec067155927d4f54ae346d0..bd44f20f778ffd92cef0c4e34c121b37bee96481 100644
--- a/third_party/rust/futures-util/src/future/select.rs
+++ b/third_party/rust/futures-util/src/future/select.rs
@@ -1,7 +1,8 @@
+use super::assert_future;
+use crate::future::{Either, FutureExt};
 use core::pin::Pin;
-use futures_core::future::{Future, FusedFuture};
+use futures_core::future::{FusedFuture, Future};
 use futures_core::task::{Context, Poll};
-use crate::future::{Either, FutureExt};
 
 /// Future for the [`select()`] function.
 #[must_use = "futures do nothing unless you `.await` or poll them"]
@@ -31,25 +32,33 @@ impl<A: Unpin, B: Unpin> Unpin for Select<A, B> {}
 ///
 /// ```
 /// # futures::executor::block_on(async {
-/// use futures::future::{self, Either};
-/// use futures::pin_mut;
+/// use futures::{
+///     pin_mut,
+///     future::Either,
+///     future::self,
+/// };
 ///
-/// // These two futures have different types even though their outputs have the same type
-/// let future1 = async { 1 };
-/// let future2 = async { 2 };
+/// // These two futures have different types even though their outputs have the same type.
+/// let future1 = async {
+///     future::pending::<()>().await; // will never finish
+///     1
+/// };
+/// let future2 = async {
+///     future::ready(2).await
+/// };
 ///
 /// // 'select' requires Future + Unpin bounds
 /// pin_mut!(future1);
 /// pin_mut!(future2);
 ///
 /// let value = match future::select(future1, future2).await {
-///     Either::Left((value1, _)) => value1, // `value1` is resolved from `future1`
-///                                          // `_` represents `future2`
+///     Either::Left((value1, _)) => value1,  // `value1` is resolved from `future1`
+///                                           // `_` represents `future2`
 ///     Either::Right((value2, _)) => value2, // `value2` is resolved from `future2`
 ///                                           // `_` represents `future1`
 /// };
 ///
-/// assert!(value == 1 || value == 2);
+/// assert!(value == 2);
 /// # });
 /// ```
 ///
@@ -73,9 +82,13 @@ impl<A: Unpin, B: Unpin> Unpin for Select<A, B> {}
 /// }
 /// ```
 pub fn select<A, B>(future1: A, future2: B) -> Select<A, B>
-    where A: Future + Unpin, B: Future + Unpin
+where
+    A: Future + Unpin,
+    B: Future + Unpin,
 {
-    Select { inner: Some((future1, future2)) }
+    assert_future::<Either<(A::Output, B), (B::Output, A)>, _>(Select {
+        inner: Some((future1, future2)),
+    })
 }
 
 impl<A, B> Future for Select<A, B>
@@ -95,7 +108,7 @@ where
                     self.inner = Some((a, b));
                     Poll::Pending
                 }
-            }
+            },
         }
     }
 }
diff --git a/third_party/rust/futures-util/src/future/select_all.rs b/third_party/rust/futures-util/src/future/select_all.rs
index 9f7fb245bf03cffbb139150a702b5248db91ffe5..106e50844cfe56e57cb92185df1de0a6b038aa3b 100644
--- a/third_party/rust/futures-util/src/future/select_all.rs
+++ b/third_party/rust/futures-util/src/future/select_all.rs
@@ -1,8 +1,9 @@
+use super::assert_future;
 use crate::future::FutureExt;
+use alloc::vec::Vec;
 use core::iter::FromIterator;
 use core::mem;
 use core::pin::Pin;
-use alloc::vec::Vec;
 use futures_core::future::Future;
 use futures_core::task::{Context, Poll};
 
@@ -31,25 +32,29 @@ impl<Fut: Unpin> Unpin for SelectAll<Fut> {}
 ///
 /// This function will panic if the iterator specified contains no items.
 pub fn select_all<I>(iter: I) -> SelectAll<I::Item>
-    where I: IntoIterator,
-          I::Item: Future + Unpin,
+where
+    I: IntoIterator,
+    I::Item: Future + Unpin,
 {
-    let ret = SelectAll {
-        inner: iter.into_iter().collect()
-    };
+    let ret = SelectAll { inner: iter.into_iter().collect() };
     assert!(!ret.inner.is_empty());
-    ret
+    assert_future::<(<I::Item as Future>::Output, usize, Vec<I::Item>), _>(ret)
+}
+
+impl<Fut> SelectAll<Fut> {
+    /// Consumes this combinator, returning the underlying futures.
+    pub fn into_inner(self) -> Vec<Fut> {
+        self.inner
+    }
 }
 
 impl<Fut: Future + Unpin> Future for SelectAll<Fut> {
     type Output = (Fut::Output, usize, Vec<Fut>);
 
     fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
-        let item = self.inner.iter_mut().enumerate().find_map(|(i, f)| {
-            match f.poll_unpin(cx) {
-                Poll::Pending => None,
-                Poll::Ready(e) => Some((i, e)),
-            }
+        let item = self.inner.iter_mut().enumerate().find_map(|(i, f)| match f.poll_unpin(cx) {
+            Poll::Pending => None,
+            Poll::Ready(e) => Some((i, e)),
         });
         match item {
             Some((idx, res)) => {
diff --git a/third_party/rust/futures-util/src/future/select_ok.rs b/third_party/rust/futures-util/src/future/select_ok.rs
index 7f4f4d65f44b895379d27454209c0e25227d35dd..0ad83c6db6b26ea21a610b79e69b8546be67ceb7 100644
--- a/third_party/rust/futures-util/src/future/select_ok.rs
+++ b/third_party/rust/futures-util/src/future/select_ok.rs
@@ -1,8 +1,9 @@
+use super::assert_future;
 use crate::future::TryFutureExt;
+use alloc::vec::Vec;
 use core::iter::FromIterator;
 use core::mem;
 use core::pin::Pin;
-use alloc::vec::Vec;
 use futures_core::future::{Future, TryFuture};
 use futures_core::task::{Context, Poll};
 
@@ -29,14 +30,16 @@ impl<Fut: Unpin> Unpin for SelectOk<Fut> {}
 ///
 /// This function will panic if the iterator specified contains no items.
 pub fn select_ok<I>(iter: I) -> SelectOk<I::Item>
-    where I: IntoIterator,
-          I::Item: TryFuture + Unpin,
+where
+    I: IntoIterator,
+    I::Item: TryFuture + Unpin,
 {
-    let ret = SelectOk {
-        inner: iter.into_iter().collect()
-    };
+    let ret = SelectOk { inner: iter.into_iter().collect() };
     assert!(!ret.inner.is_empty(), "iterator provided to select_ok was empty");
-    ret
+    assert_future::<
+        Result<(<I::Item as TryFuture>::Ok, Vec<I::Item>), <I::Item as TryFuture>::Error>,
+        _,
+    >(ret)
 }
 
 impl<Fut: TryFuture + Unpin> Future for SelectOk<Fut> {
@@ -45,12 +48,11 @@ impl<Fut: TryFuture + Unpin> Future for SelectOk<Fut> {
     fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
         // loop until we've either exhausted all errors, a success was hit, or nothing is ready
         loop {
-            let item = self.inner.iter_mut().enumerate().find_map(|(i, f)| {
-                match f.try_poll_unpin(cx) {
+            let item =
+                self.inner.iter_mut().enumerate().find_map(|(i, f)| match f.try_poll_unpin(cx) {
                     Poll::Pending => None,
                     Poll::Ready(e) => Some((i, e)),
-                }
-            });
+                });
             match item {
                 Some((idx, res)) => {
                     // always remove Ok or Err, if it's not the last Err continue looping
@@ -58,18 +60,18 @@ impl<Fut: TryFuture + Unpin> Future for SelectOk<Fut> {
                     match res {
                         Ok(e) => {
                             let rest = mem::replace(&mut self.inner, Vec::new());
-                            return Poll::Ready(Ok((e, rest)))
+                            return Poll::Ready(Ok((e, rest)));
                         }
                         Err(e) => {
                             if self.inner.is_empty() {
-                                return Poll::Ready(Err(e))
+                                return Poll::Ready(Err(e));
                             }
                         }
                     }
                 }
                 None => {
                     // based on the filter above, nothing is ready, return
-                    return Poll::Pending
+                    return Poll::Pending;
                 }
             }
         }
diff --git a/third_party/rust/futures-util/src/future/try_future/into_future.rs b/third_party/rust/futures-util/src/future/try_future/into_future.rs
index e88d603c0fb9ad1428b3da206dd0c6ca8c9f115f..9f093d0e2e1c77278b62a479dfc1971b24f36c79 100644
--- a/third_party/rust/futures-util/src/future/try_future/into_future.rs
+++ b/third_party/rust/futures-util/src/future/try_future/into_future.rs
@@ -21,17 +21,16 @@ impl<Fut> IntoFuture<Fut> {
 }
 
 impl<Fut: TryFuture + FusedFuture> FusedFuture for IntoFuture<Fut> {
-    fn is_terminated(&self) -> bool { self.future.is_terminated() }
+    fn is_terminated(&self) -> bool {
+        self.future.is_terminated()
+    }
 }
 
 impl<Fut: TryFuture> Future for IntoFuture<Fut> {
     type Output = Result<Fut::Ok, Fut::Error>;
 
     #[inline]
-    fn poll(
-        self: Pin<&mut Self>,
-        cx: &mut Context<'_>,
-    ) -> Poll<Self::Output> {
+    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
         self.project().future.try_poll(cx)
     }
 }
diff --git a/third_party/rust/futures-util/src/future/try_future/mod.rs b/third_party/rust/futures-util/src/future/try_future/mod.rs
index 1ce01d2de0bd501d39032bab7709f1d7bc182989..fb3bdd8a025a5aa4f3f997ed6f6803bdfb5ec537 100644
--- a/third_party/rust/futures-util/src/future/try_future/mod.rs
+++ b/third_party/rust/futures-util/src/future/try_future/mod.rs
@@ -173,7 +173,7 @@ pub trait TryFutureExt: TryFuture {
         Self::Ok: Sink<Item, Error = Self::Error>,
         Self: Sized,
     {
-        FlattenSink::new(self)
+        crate::sink::assert_sink::<Item, Self::Error, _>(FlattenSink::new(self))
     }
 
     /// Maps this future's success value to a different value.
@@ -501,7 +501,7 @@ pub trait TryFutureExt: TryFuture {
         Self::Ok: TryFuture<Error = Self::Error>,
         Self: Sized,
     {
-        TryFlatten::new(self)
+        assert_future::<Result<<Self::Ok as TryFuture>::Ok, Self::Error>, _>(TryFlatten::new(self))
     }
 
     /// Flatten the execution of this future when the successful result of this
@@ -539,7 +539,7 @@ pub trait TryFutureExt: TryFuture {
         ))
     }
 
-    /// Unwraps this future's ouput, producing a future with this future's
+    /// Unwraps this future's output, producing a future with this future's
     /// [`Ok`](TryFuture::Ok) type as its
     /// [`Output`](std::future::Future::Output) type.
     ///
@@ -569,8 +569,8 @@ pub trait TryFutureExt: TryFuture {
         assert_future::<Self::Ok, _>(UnwrapOrElse::new(self, f))
     }
 
-    /// Wraps a [`TryFuture`] into a future compatable with libraries using
-    /// futures 0.1 future definitons. Requires the `compat` feature to enable.
+    /// Wraps a [`TryFuture`] into a future compatible with libraries using
+    /// futures 0.1 future definitions. Requires the `compat` feature to enable.
     #[cfg(feature = "compat")]
     #[cfg_attr(docsrs, doc(cfg(feature = "compat")))]
     fn compat(self) -> Compat<Self>
diff --git a/third_party/rust/futures-util/src/future/try_future/try_flatten.rs b/third_party/rust/futures-util/src/future/try_future/try_flatten.rs
index 5241b2750dc4acba1ecf458c551a05cd3ce81424..1ce4559ac2fa31d493d6654a0df20b49962f4cc9 100644
--- a/third_party/rust/futures-util/src/future/try_future/try_flatten.rs
+++ b/third_party/rust/futures-util/src/future/try_future/try_flatten.rs
@@ -2,9 +2,9 @@ use core::pin::Pin;
 use futures_core::future::{FusedFuture, Future, TryFuture};
 use futures_core::ready;
 use futures_core::stream::{FusedStream, Stream, TryStream};
+use futures_core::task::{Context, Poll};
 #[cfg(feature = "sink")]
 use futures_sink::Sink;
-use futures_core::task::{Context, Poll};
 use pin_project_lite::pin_project;
 
 pin_project! {
@@ -24,8 +24,9 @@ impl<Fut1, Fut2> TryFlatten<Fut1, Fut2> {
 }
 
 impl<Fut> FusedFuture for TryFlatten<Fut, Fut::Ok>
-    where Fut: TryFuture,
-          Fut::Ok: TryFuture<Error=Fut::Error>,
+where
+    Fut: TryFuture,
+    Fut::Ok: TryFuture<Error = Fut::Error>,
 {
     fn is_terminated(&self) -> bool {
         match self {
@@ -36,28 +37,27 @@ impl<Fut> FusedFuture for TryFlatten<Fut, Fut::Ok>
 }
 
 impl<Fut> Future for TryFlatten<Fut, Fut::Ok>
-    where Fut: TryFuture,
-          Fut::Ok: TryFuture<Error=Fut::Error>,
+where
+    Fut: TryFuture,
+    Fut::Ok: TryFuture<Error = Fut::Error>,
 {
     type Output = Result<<Fut::Ok as TryFuture>::Ok, Fut::Error>;
 
     fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
         Poll::Ready(loop {
             match self.as_mut().project() {
-                TryFlattenProj::First { f } => {
-                    match ready!(f.try_poll(cx)) {
-                        Ok(f) => self.set(Self::Second { f }),
-                        Err(e) => {
-                            self.set(Self::Empty);
-                            break Err(e);
-                        }
+                TryFlattenProj::First { f } => match ready!(f.try_poll(cx)) {
+                    Ok(f) => self.set(Self::Second { f }),
+                    Err(e) => {
+                        self.set(Self::Empty);
+                        break Err(e);
                     }
                 },
                 TryFlattenProj::Second { f } => {
                     let output = ready!(f.try_poll(cx));
                     self.set(Self::Empty);
                     break output;
-                },
+                }
                 TryFlattenProj::Empty => panic!("TryFlatten polled after completion"),
             }
         })
@@ -65,8 +65,9 @@ impl<Fut> Future for TryFlatten<Fut, Fut::Ok>
 }
 
 impl<Fut> FusedStream for TryFlatten<Fut, Fut::Ok>
-    where Fut: TryFuture,
-          Fut::Ok: TryStream<Error=Fut::Error>,
+where
+    Fut: TryFuture,
+    Fut::Ok: TryStream<Error = Fut::Error>,
 {
     fn is_terminated(&self) -> bool {
         match self {
@@ -77,21 +78,20 @@ impl<Fut> FusedStream for TryFlatten<Fut, Fut::Ok>
 }
 
 impl<Fut> Stream for TryFlatten<Fut, Fut::Ok>
-    where Fut: TryFuture,
-          Fut::Ok: TryStream<Error=Fut::Error>,
+where
+    Fut: TryFuture,
+    Fut::Ok: TryStream<Error = Fut::Error>,
 {
     type Item = Result<<Fut::Ok as TryStream>::Ok, Fut::Error>;
 
     fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
         Poll::Ready(loop {
             match self.as_mut().project() {
-                TryFlattenProj::First { f } => {
-                    match ready!(f.try_poll(cx)) {
-                        Ok(f) => self.set(Self::Second { f }),
-                        Err(e) => {
-                            self.set(Self::Empty);
-                            break Some(Err(e));
-                        }
+                TryFlattenProj::First { f } => match ready!(f.try_poll(cx)) {
+                    Ok(f) => self.set(Self::Second { f }),
+                    Err(e) => {
+                        self.set(Self::Empty);
+                        break Some(Err(e));
                     }
                 },
                 TryFlattenProj::Second { f } => {
@@ -100,40 +100,34 @@ impl<Fut> Stream for TryFlatten<Fut, Fut::Ok>
                         self.set(Self::Empty);
                     }
                     break output;
-                },
+                }
                 TryFlattenProj::Empty => break None,
             }
         })
     }
 }
 
-
 #[cfg(feature = "sink")]
 impl<Fut, Item> Sink<Item> for TryFlatten<Fut, Fut::Ok>
 where
     Fut: TryFuture,
-    Fut::Ok: Sink<Item, Error=Fut::Error>,
+    Fut::Ok: Sink<Item, Error = Fut::Error>,
 {
     type Error = Fut::Error;
 
-    fn poll_ready(
-        mut self: Pin<&mut Self>,
-        cx: &mut Context<'_>,
-    ) -> Poll<Result<(), Self::Error>> {
+    fn poll_ready(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
         Poll::Ready(loop {
             match self.as_mut().project() {
-                TryFlattenProj::First { f } => {
-                    match ready!(f.try_poll(cx)) {
-                        Ok(f) => self.set(Self::Second { f }),
-                        Err(e) => {
-                            self.set(Self::Empty);
-                            break Err(e);
-                        }
+                TryFlattenProj::First { f } => match ready!(f.try_poll(cx)) {
+                    Ok(f) => self.set(Self::Second { f }),
+                    Err(e) => {
+                        self.set(Self::Empty);
+                        break Err(e);
                     }
                 },
                 TryFlattenProj::Second { f } => {
                     break ready!(f.poll_ready(cx));
-                },
+                }
                 TryFlattenProj::Empty => panic!("poll_ready called after eof"),
             }
         })
@@ -155,10 +149,7 @@ where
         }
     }
 
-    fn poll_close(
-        mut self: Pin<&mut Self>,
-        cx: &mut Context<'_>,
-    ) -> Poll<Result<(), Self::Error>> {
+    fn poll_close(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
         let res = match self.as_mut().project() {
             TryFlattenProj::Second { f } => f.poll_close(cx),
             _ => Poll::Ready(Ok(())),
diff --git a/third_party/rust/futures-util/src/future/try_future/try_flatten_err.rs b/third_party/rust/futures-util/src/future/try_future/try_flatten_err.rs
index 2e67f1104eb0d448d798eafa81bc959e942edf55..39b7d9f5f60c1f4ff13a47dd8e5f643c7df4587d 100644
--- a/third_party/rust/futures-util/src/future/try_future/try_flatten_err.rs
+++ b/third_party/rust/futures-util/src/future/try_future/try_flatten_err.rs
@@ -21,8 +21,9 @@ impl<Fut1, Fut2> TryFlattenErr<Fut1, Fut2> {
 }
 
 impl<Fut> FusedFuture for TryFlattenErr<Fut, Fut::Error>
-    where Fut: TryFuture,
-          Fut::Error: TryFuture<Ok=Fut::Ok>,
+where
+    Fut: TryFuture,
+    Fut::Error: TryFuture<Ok = Fut::Ok>,
 {
     fn is_terminated(&self) -> bool {
         match self {
@@ -33,28 +34,27 @@ impl<Fut> FusedFuture for TryFlattenErr<Fut, Fut::Error>
 }
 
 impl<Fut> Future for TryFlattenErr<Fut, Fut::Error>
-    where Fut: TryFuture,
-          Fut::Error: TryFuture<Ok=Fut::Ok>,
+where
+    Fut: TryFuture,
+    Fut::Error: TryFuture<Ok = Fut::Ok>,
 {
     type Output = Result<Fut::Ok, <Fut::Error as TryFuture>::Error>;
 
     fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
         Poll::Ready(loop {
             match self.as_mut().project() {
-                TryFlattenErrProj::First { f } => {
-                    match ready!(f.try_poll(cx)) {
-                        Err(f) => self.set(Self::Second { f }),
-                        Ok(e) => {
-                            self.set(Self::Empty);
-                            break Ok(e);
-                        }
+                TryFlattenErrProj::First { f } => match ready!(f.try_poll(cx)) {
+                    Err(f) => self.set(Self::Second { f }),
+                    Ok(e) => {
+                        self.set(Self::Empty);
+                        break Ok(e);
                     }
                 },
                 TryFlattenErrProj::Second { f } => {
                     let output = ready!(f.try_poll(cx));
                     self.set(Self::Empty);
                     break output;
-                },
+                }
                 TryFlattenErrProj::Empty => panic!("TryFlattenErr polled after completion"),
             }
         })
diff --git a/third_party/rust/futures-util/src/future/try_join.rs b/third_party/rust/futures-util/src/future/try_join.rs
index 25ccdde39c397668565cb449dd556617ef7ab11f..6af1f0ccbfc9907d4c03eee2b754394c15e34e66 100644
--- a/third_party/rust/futures-util/src/future/try_join.rs
+++ b/third_party/rust/futures-util/src/future/try_join.rs
@@ -1,6 +1,6 @@
 #![allow(non_snake_case)]
 
-use crate::future::{TryMaybeDone, try_maybe_done};
+use crate::future::{assert_future, try_maybe_done, TryMaybeDone};
 use core::fmt;
 use core::pin::Pin;
 use futures_core::future::{Future, TryFuture};
@@ -108,7 +108,7 @@ generate! {
 ///
 /// This function will return a new future which awaits both futures to
 /// complete. If successful, the returned future will finish with a tuple of
-/// both results. If unsuccesful, it will complete with the first error
+/// both results. If unsuccessful, it will complete with the first error
 /// encountered.
 ///
 /// Note that this function consumes the passed futures and returns a
@@ -150,7 +150,7 @@ where
     Fut1: TryFuture,
     Fut2: TryFuture<Error = Fut1::Error>,
 {
-    TryJoin::new(future1, future2)
+    assert_future::<Result<(Fut1::Ok, Fut2::Ok), Fut1::Error>, _>(TryJoin::new(future1, future2))
 }
 
 /// Same as [`try_join`](try_join()), but with more futures.
@@ -179,7 +179,9 @@ where
     Fut2: TryFuture<Error = Fut1::Error>,
     Fut3: TryFuture<Error = Fut1::Error>,
 {
-    TryJoin3::new(future1, future2, future3)
+    assert_future::<Result<(Fut1::Ok, Fut2::Ok, Fut3::Ok), Fut1::Error>, _>(TryJoin3::new(
+        future1, future2, future3,
+    ))
 }
 
 /// Same as [`try_join`](try_join()), but with more futures.
@@ -211,7 +213,9 @@ where
     Fut3: TryFuture<Error = Fut1::Error>,
     Fut4: TryFuture<Error = Fut1::Error>,
 {
-    TryJoin4::new(future1, future2, future3, future4)
+    assert_future::<Result<(Fut1::Ok, Fut2::Ok, Fut3::Ok, Fut4::Ok), Fut1::Error>, _>(
+        TryJoin4::new(future1, future2, future3, future4),
+    )
 }
 
 /// Same as [`try_join`](try_join()), but with more futures.
@@ -246,5 +250,7 @@ where
     Fut4: TryFuture<Error = Fut1::Error>,
     Fut5: TryFuture<Error = Fut1::Error>,
 {
-    TryJoin5::new(future1, future2, future3, future4, future5)
+    assert_future::<Result<(Fut1::Ok, Fut2::Ok, Fut3::Ok, Fut4::Ok, Fut5::Ok), Fut1::Error>, _>(
+        TryJoin5::new(future1, future2, future3, future4, future5),
+    )
 }
diff --git a/third_party/rust/futures-util/src/future/try_join_all.rs b/third_party/rust/futures-util/src/future/try_join_all.rs
index 4de0a79b94ee979f76b50e4ea8386cf4a2da6586..29244af8379a74d7c896ccca866162699b926fa0 100644
--- a/third_party/rust/futures-util/src/future/try_join_all.rs
+++ b/third_party/rust/futures-util/src/future/try_join_all.rs
@@ -1,30 +1,28 @@
 //! Definition of the `TryJoinAll` combinator, waiting for all of a list of
 //! futures to finish with either success or error.
 
+use alloc::boxed::Box;
+use alloc::vec::Vec;
 use core::fmt;
 use core::future::Future;
 use core::iter::FromIterator;
 use core::mem;
 use core::pin::Pin;
 use core::task::{Context, Poll};
-use alloc::boxed::Box;
-use alloc::vec::Vec;
 
-use super::{TryFuture, TryMaybeDone};
+use super::{assert_future, TryFuture, TryMaybeDone};
 
 fn iter_pin_mut<T>(slice: Pin<&mut [T]>) -> impl Iterator<Item = Pin<&mut T>> {
     // Safety: `std` _could_ make this unsound if it were to decide Pin's
     // invariants aren't required to transmit through slices. Otherwise this has
     // the same safety as a normal field pin projection.
-    unsafe { slice.get_unchecked_mut() }
-        .iter_mut()
-        .map(|t| unsafe { Pin::new_unchecked(t) })
+    unsafe { slice.get_unchecked_mut() }.iter_mut().map(|t| unsafe { Pin::new_unchecked(t) })
 }
 
 enum FinalState<E = ()> {
     Pending,
     AllDone,
-    Error(E)
+    Error(E),
 }
 
 /// Future for the [`try_join_all`] function.
@@ -43,9 +41,7 @@ where
     F::Error: fmt::Debug,
 {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.debug_struct("TryJoinAll")
-            .field("elems", &self.elems)
-            .finish()
+        f.debug_struct("TryJoinAll").field("elems", &self.elems).finish()
     }
 }
 
@@ -93,9 +89,9 @@ where
     I::Item: TryFuture,
 {
     let elems: Box<[_]> = i.into_iter().map(TryMaybeDone::Future).collect();
-    TryJoinAll {
-        elems: elems.into(),
-    }
+    assert_future::<Result<Vec<<I::Item as TryFuture>::Ok>, <I::Item as TryFuture>::Error>, _>(
+        TryJoinAll { elems: elems.into() },
+    )
 }
 
 impl<F> Future for TryJoinAll<F>
@@ -110,7 +106,7 @@ where
         for elem in iter_pin_mut(self.elems.as_mut()) {
             match elem.try_poll(cx) {
                 Poll::Pending => state = FinalState::Pending,
-                Poll::Ready(Ok(())) => {},
+                Poll::Ready(Ok(())) => {}
                 Poll::Ready(Err(e)) => {
                     state = FinalState::Error(e);
                     break;
@@ -122,15 +118,14 @@ where
             FinalState::Pending => Poll::Pending,
             FinalState::AllDone => {
                 let mut elems = mem::replace(&mut self.elems, Box::pin([]));
-                let results = iter_pin_mut(elems.as_mut())
-                    .map(|e| e.take_output().unwrap())
-                    .collect();
+                let results =
+                    iter_pin_mut(elems.as_mut()).map(|e| e.take_output().unwrap()).collect();
                 Poll::Ready(Ok(results))
-            },
+            }
             FinalState::Error(e) => {
                 let _ = mem::replace(&mut self.elems, Box::pin([]));
                 Poll::Ready(Err(e))
-            },
+            }
         }
     }
 }
diff --git a/third_party/rust/futures-util/src/future/try_maybe_done.rs b/third_party/rust/futures-util/src/future/try_maybe_done.rs
index 90067e90be105eedb9e3d78dee1db896a7bc9c02..24044d2c276384d838c3575c8240d1779b277a11 100644
--- a/third_party/rust/futures-util/src/future/try_maybe_done.rs
+++ b/third_party/rust/futures-util/src/future/try_maybe_done.rs
@@ -1,5 +1,6 @@
 //! Definition of the TryMaybeDone combinator
 
+use super::assert_future;
 use core::mem;
 use core::pin::Pin;
 use futures_core::future::{FusedFuture, Future, TryFuture};
@@ -25,7 +26,7 @@ impl<Fut: TryFuture + Unpin> Unpin for TryMaybeDone<Fut> {}
 
 /// Wraps a future into a `TryMaybeDone`
 pub fn try_maybe_done<Fut: TryFuture>(future: Fut) -> TryMaybeDone<Fut> {
-    TryMaybeDone::Future(future)
+    assert_future::<Result<(), Fut::Error>, _>(TryMaybeDone::Future(future))
 }
 
 impl<Fut: TryFuture> TryMaybeDone<Fut> {
@@ -48,13 +49,13 @@ impl<Fut: TryFuture> TryMaybeDone<Fut> {
     #[inline]
     pub fn take_output(self: Pin<&mut Self>) -> Option<Fut::Ok> {
         match &*self {
-            Self::Done(_) => {},
+            Self::Done(_) => {}
             Self::Future(_) | Self::Gone => return None,
         }
         unsafe {
             match mem::replace(self.get_unchecked_mut(), Self::Gone) {
                 TryMaybeDone::Done(output) => Some(output),
-                _ => unreachable!()
+                _ => unreachable!(),
             }
         }
     }
@@ -75,16 +76,14 @@ impl<Fut: TryFuture> Future for TryMaybeDone<Fut> {
     fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
         unsafe {
             match self.as_mut().get_unchecked_mut() {
-                TryMaybeDone::Future(f) => {
-                    match ready!(Pin::new_unchecked(f).try_poll(cx)) {
-                        Ok(res) => self.set(Self::Done(res)),
-                        Err(e) => {
-                            self.set(Self::Gone);
-                            return Poll::Ready(Err(e));
-                        }
+                TryMaybeDone::Future(f) => match ready!(Pin::new_unchecked(f).try_poll(cx)) {
+                    Ok(res) => self.set(Self::Done(res)),
+                    Err(e) => {
+                        self.set(Self::Gone);
+                        return Poll::Ready(Err(e));
                     }
                 },
-                TryMaybeDone::Done(_) => {},
+                TryMaybeDone::Done(_) => {}
                 TryMaybeDone::Gone => panic!("TryMaybeDone polled after value taken"),
             }
         }
diff --git a/third_party/rust/futures-util/src/future/try_select.rs b/third_party/rust/futures-util/src/future/try_select.rs
index 56564f5b5c85951d6060f101275c66ebbdf344f7..4d0b7ff1358a5b6f865fa8ac9dda3223cd883a05 100644
--- a/third_party/rust/futures-util/src/future/try_select.rs
+++ b/third_party/rust/futures-util/src/future/try_select.rs
@@ -1,7 +1,7 @@
+use crate::future::{Either, TryFutureExt};
 use core::pin::Pin;
 use futures_core::future::{Future, TryFuture};
 use futures_core::task::{Context, Poll};
-use crate::future::{Either, TryFutureExt};
 
 /// Future for the [`try_select()`] function.
 #[must_use = "futures do nothing unless you `.await` or poll them"]
@@ -48,19 +48,23 @@ impl<A: Unpin, B: Unpin> Unpin for TrySelect<A, B> {}
 /// }
 /// ```
 pub fn try_select<A, B>(future1: A, future2: B) -> TrySelect<A, B>
-    where A: TryFuture + Unpin, B: TryFuture + Unpin
+where
+    A: TryFuture + Unpin,
+    B: TryFuture + Unpin,
 {
-    TrySelect { inner: Some((future1, future2)) }
+    super::assert_future::<
+        Result<Either<(A::Ok, B), (B::Ok, A)>, Either<(A::Error, B), (B::Error, A)>>,
+        _,
+    >(TrySelect { inner: Some((future1, future2)) })
 }
 
 impl<A: Unpin, B: Unpin> Future for TrySelect<A, B>
-    where A: TryFuture, B: TryFuture
+where
+    A: TryFuture,
+    B: TryFuture,
 {
     #[allow(clippy::type_complexity)]
-    type Output = Result<
-        Either<(A::Ok, B), (B::Ok, A)>,
-        Either<(A::Error, B), (B::Error, A)>,
-    >;
+    type Output = Result<Either<(A::Ok, B), (B::Ok, A)>, Either<(A::Error, B), (B::Error, A)>>;
 
     fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
         let (mut a, mut b) = self.inner.take().expect("cannot poll Select twice");
@@ -74,7 +78,7 @@ impl<A: Unpin, B: Unpin> Future for TrySelect<A, B>
                     self.inner = Some((a, b));
                     Poll::Pending
                 }
-            }
+            },
         }
     }
 }
diff --git a/third_party/rust/futures-util/src/io/allow_std.rs b/third_party/rust/futures-util/src/io/allow_std.rs
index 9aa8eb4e71c103bc6350803f1ad7cbf5b2e32336..1d13e0c177acf7aab18f0d6a54a1c8f139870b7a 100644
--- a/third_party/rust/futures-util/src/io/allow_std.rs
+++ b/third_party/rust/futures-util/src/io/allow_std.rs
@@ -1,9 +1,9 @@
 use futures_core::task::{Context, Poll};
 #[cfg(feature = "read-initializer")]
 use futures_io::Initializer;
-use futures_io::{AsyncRead, AsyncWrite, AsyncSeek, AsyncBufRead, IoSlice, IoSliceMut, SeekFrom};
-use std::{fmt, io};
+use futures_io::{AsyncBufRead, AsyncRead, AsyncSeek, AsyncWrite, IoSlice, IoSliceMut, SeekFrom};
 use std::pin::Pin;
+use std::{fmt, io};
 
 /// A simple wrapper type which allows types which implement only
 /// implement `std::io::Read` or `std::io::Write`
@@ -35,7 +35,7 @@ macro_rules! try_with_interrupt {
                 }
             }
         }
-    }
+    };
 }
 
 impl<T> AllowStdIo<T> {
@@ -60,7 +60,10 @@ impl<T> AllowStdIo<T> {
     }
 }
 
-impl<T> io::Write for AllowStdIo<T> where T: io::Write {
+impl<T> io::Write for AllowStdIo<T>
+where
+    T: io::Write,
+{
     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
         self.0.write(buf)
     }
@@ -78,16 +81,23 @@ impl<T> io::Write for AllowStdIo<T> where T: io::Write {
     }
 }
 
-impl<T> AsyncWrite for AllowStdIo<T> where T: io::Write {
-    fn poll_write(mut self: Pin<&mut Self>, _: &mut Context<'_>, buf: &[u8])
-        -> Poll<io::Result<usize>>
-    {
+impl<T> AsyncWrite for AllowStdIo<T>
+where
+    T: io::Write,
+{
+    fn poll_write(
+        mut self: Pin<&mut Self>,
+        _: &mut Context<'_>,
+        buf: &[u8],
+    ) -> Poll<io::Result<usize>> {
         Poll::Ready(Ok(try_with_interrupt!(self.0.write(buf))))
     }
 
-    fn poll_write_vectored(mut self: Pin<&mut Self>, _: &mut Context<'_>, bufs: &[IoSlice<'_>])
-        -> Poll<io::Result<usize>>
-    {
+    fn poll_write_vectored(
+        mut self: Pin<&mut Self>,
+        _: &mut Context<'_>,
+        bufs: &[IoSlice<'_>],
+    ) -> Poll<io::Result<usize>> {
         Poll::Ready(Ok(try_with_interrupt!(self.0.write_vectored(bufs))))
     }
 
@@ -101,7 +111,10 @@ impl<T> AsyncWrite for AllowStdIo<T> where T: io::Write {
     }
 }
 
-impl<T> io::Read for AllowStdIo<T> where T: io::Read {
+impl<T> io::Read for AllowStdIo<T>
+where
+    T: io::Read,
+{
     fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
         self.0.read(buf)
     }
@@ -123,16 +136,23 @@ impl<T> io::Read for AllowStdIo<T> where T: io::Read {
     }
 }
 
-impl<T> AsyncRead for AllowStdIo<T> where T: io::Read {
-    fn poll_read(mut self: Pin<&mut Self>, _: &mut Context<'_>, buf: &mut [u8])
-        -> Poll<io::Result<usize>>
-    {
+impl<T> AsyncRead for AllowStdIo<T>
+where
+    T: io::Read,
+{
+    fn poll_read(
+        mut self: Pin<&mut Self>,
+        _: &mut Context<'_>,
+        buf: &mut [u8],
+    ) -> Poll<io::Result<usize>> {
         Poll::Ready(Ok(try_with_interrupt!(self.0.read(buf))))
     }
 
-    fn poll_read_vectored(mut self: Pin<&mut Self>, _: &mut Context<'_>, bufs: &mut [IoSliceMut<'_>])
-        -> Poll<io::Result<usize>>
-    {
+    fn poll_read_vectored(
+        mut self: Pin<&mut Self>,
+        _: &mut Context<'_>,
+        bufs: &mut [IoSliceMut<'_>],
+    ) -> Poll<io::Result<usize>> {
         Poll::Ready(Ok(try_with_interrupt!(self.0.read_vectored(bufs))))
     }
 
@@ -142,21 +162,32 @@ impl<T> AsyncRead for AllowStdIo<T> where T: io::Read {
     }
 }
 
-impl<T> io::Seek for AllowStdIo<T> where T: io::Seek {
+impl<T> io::Seek for AllowStdIo<T>
+where
+    T: io::Seek,
+{
     fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> {
         self.0.seek(pos)
     }
 }
 
-impl<T> AsyncSeek for AllowStdIo<T> where T: io::Seek {
-    fn poll_seek(mut self: Pin<&mut Self>, _: &mut Context<'_>, pos: SeekFrom)
-        -> Poll<io::Result<u64>>
-    {
+impl<T> AsyncSeek for AllowStdIo<T>
+where
+    T: io::Seek,
+{
+    fn poll_seek(
+        mut self: Pin<&mut Self>,
+        _: &mut Context<'_>,
+        pos: SeekFrom,
+    ) -> Poll<io::Result<u64>> {
         Poll::Ready(Ok(try_with_interrupt!(self.0.seek(pos))))
     }
 }
 
-impl<T> io::BufRead for AllowStdIo<T> where T: io::BufRead {
+impl<T> io::BufRead for AllowStdIo<T>
+where
+    T: io::BufRead,
+{
     fn fill_buf(&mut self) -> io::Result<&[u8]> {
         self.0.fill_buf()
     }
@@ -165,10 +196,11 @@ impl<T> io::BufRead for AllowStdIo<T> where T: io::BufRead {
     }
 }
 
-impl<T> AsyncBufRead for AllowStdIo<T> where T: io::BufRead {
-    fn poll_fill_buf(mut self: Pin<&mut Self>, _: &mut Context<'_>)
-        -> Poll<io::Result<&[u8]>>
-    {
+impl<T> AsyncBufRead for AllowStdIo<T>
+where
+    T: io::BufRead,
+{
+    fn poll_fill_buf(mut self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<io::Result<&[u8]>> {
         let this: *mut Self = &mut *self as *mut _;
         Poll::Ready(Ok(try_with_interrupt!(unsafe { &mut *this }.0.fill_buf())))
     }
diff --git a/third_party/rust/futures-util/src/io/buf_reader.rs b/third_party/rust/futures-util/src/io/buf_reader.rs
index 270a086cf89e269fd98de5ce3bde2f756f780a84..5931edc1b24260f13290d0f11b553f46e51e8d4c 100644
--- a/third_party/rust/futures-util/src/io/buf_reader.rs
+++ b/third_party/rust/futures-util/src/io/buf_reader.rs
@@ -1,3 +1,4 @@
+use super::DEFAULT_BUF_SIZE;
 use futures_core::ready;
 use futures_core::task::{Context, Poll};
 #[cfg(feature = "read-initializer")]
@@ -7,7 +8,6 @@ use pin_project_lite::pin_project;
 use std::io::{self, Read};
 use std::pin::Pin;
 use std::{cmp, fmt};
-use super::DEFAULT_BUF_SIZE;
 
 pin_project! {
     /// The `BufReader` struct adds buffering to any reader.
@@ -51,12 +51,7 @@ impl<R: AsyncRead> BufReader<R> {
             let mut buffer = Vec::with_capacity(capacity);
             buffer.set_len(capacity);
             super::initialize(&inner, &mut buffer);
-            Self {
-                inner,
-                buffer: buffer.into_boxed_slice(),
-                pos: 0,
-                cap: 0,
-            }
+            Self { inner, buffer: buffer.into_boxed_slice(), pos: 0, cap: 0 }
         }
     }
 
@@ -123,10 +118,7 @@ impl<R: AsyncRead> AsyncRead for BufReader<R> {
 }
 
 impl<R: AsyncRead> AsyncBufRead for BufReader<R> {
-    fn poll_fill_buf(
-        self: Pin<&mut Self>,
-        cx: &mut Context<'_>,
-    ) -> Poll<io::Result<&[u8]>> {
+    fn poll_fill_buf(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<&[u8]>> {
         let this = self.project();
 
         // If we've reached the end of our internal buffer then we need to fetch
@@ -192,7 +184,8 @@ impl<R: AsyncRead + AsyncSeek> AsyncSeek for BufReader<R> {
             // support seeking by i64::min_value() so we need to handle underflow when subtracting
             // remainder.
             if let Some(offset) = n.checked_sub(remainder) {
-                result = ready!(self.as_mut().project().inner.poll_seek(cx, SeekFrom::Current(offset)))?;
+                result =
+                    ready!(self.as_mut().project().inner.poll_seek(cx, SeekFrom::Current(offset)))?;
             } else {
                 // seek backwards by our remainder, and then by the offset
                 ready!(self.as_mut().project().inner.poll_seek(cx, SeekFrom::Current(-remainder)))?;
diff --git a/third_party/rust/futures-util/src/io/buf_writer.rs b/third_party/rust/futures-util/src/io/buf_writer.rs
index 991a365a1c010cce05038716053a8c74ab231cde..f292b871f1e13191ae20de41c3a7a24df2e9b440 100644
--- a/third_party/rust/futures-util/src/io/buf_writer.rs
+++ b/third_party/rust/futures-util/src/io/buf_writer.rs
@@ -1,3 +1,4 @@
+use super::DEFAULT_BUF_SIZE;
 use futures_core::ready;
 use futures_core::task::{Context, Poll};
 use futures_io::{AsyncBufRead, AsyncRead, AsyncSeek, AsyncWrite, IoSlice, SeekFrom};
@@ -5,7 +6,6 @@ use pin_project_lite::pin_project;
 use std::fmt;
 use std::io::{self, Write};
 use std::pin::Pin;
-use super::DEFAULT_BUF_SIZE;
 
 pin_project! {
     /// Wraps a writer and buffers its output.
@@ -46,11 +46,7 @@ impl<W: AsyncWrite> BufWriter<W> {
 
     /// Creates a new `BufWriter` with the specified buffer capacity.
     pub fn with_capacity(cap: usize, inner: W) -> Self {
-        Self {
-            inner,
-            buf: Vec::with_capacity(cap),
-            written: 0,
-        }
+        Self { inner, buf: Vec::with_capacity(cap), written: 0 }
     }
 
     fn flush_buf(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
diff --git a/third_party/rust/futures-util/src/io/chain.rs b/third_party/rust/futures-util/src/io/chain.rs
index 1b6a3355693905f17605c0b1affc8004a06f139b..a35c50de358d6d0c4926dca83c285c3262a52cfb 100644
--- a/third_party/rust/futures-util/src/io/chain.rs
+++ b/third_party/rust/futures-util/src/io/chain.rs
@@ -26,11 +26,7 @@ where
     U: AsyncRead,
 {
     pub(super) fn new(first: T, second: U) -> Self {
-        Self {
-            first,
-            second,
-            done_first: false,
-        }
+        Self { first, second, done_first: false }
     }
 
     /// Gets references to the underlying readers in this `Chain`.
diff --git a/third_party/rust/futures-util/src/io/copy.rs b/third_party/rust/futures-util/src/io/copy.rs
index bc592552e9aca4bbfc418c7d9053a1ec368ba796..c80add271b07932df45a28df7833604f8d55b104 100644
--- a/third_party/rust/futures-util/src/io/copy.rs
+++ b/third_party/rust/futures-util/src/io/copy.rs
@@ -1,10 +1,10 @@
+use super::{copy_buf, BufReader, CopyBuf};
 use futures_core::future::Future;
 use futures_core::task::{Context, Poll};
 use futures_io::{AsyncRead, AsyncWrite};
+use pin_project_lite::pin_project;
 use std::io;
 use std::pin::Pin;
-use super::{BufReader, copy_buf, CopyBuf};
-use pin_project_lite::pin_project;
 
 /// Creates a future which copies all the bytes from one object to another.
 ///
@@ -36,9 +36,7 @@ where
     R: AsyncRead,
     W: AsyncWrite + Unpin + ?Sized,
 {
-    Copy {
-        inner: copy_buf(BufReader::new(reader), writer),
-    }
+    Copy { inner: copy_buf(BufReader::new(reader), writer) }
 }
 
 pin_project! {
diff --git a/third_party/rust/futures-util/src/io/copy_buf.rs b/third_party/rust/futures-util/src/io/copy_buf.rs
index 6adf594d5473f468557d6c27148e3c9980a8ae3d..50f7abdca9def6de519e1e5ae2962198e92af3e9 100644
--- a/third_party/rust/futures-util/src/io/copy_buf.rs
+++ b/third_party/rust/futures-util/src/io/copy_buf.rs
@@ -2,9 +2,9 @@ use futures_core::future::Future;
 use futures_core::ready;
 use futures_core::task::{Context, Poll};
 use futures_io::{AsyncBufRead, AsyncWrite};
+use pin_project_lite::pin_project;
 use std::io;
 use std::pin::Pin;
-use pin_project_lite::pin_project;
 
 /// Creates a future which copies all the bytes from one object to another.
 ///
@@ -36,11 +36,7 @@ where
     R: AsyncBufRead,
     W: AsyncWrite + Unpin + ?Sized,
 {
-    CopyBuf {
-        reader,
-        writer,
-        amt: 0,
-    }
+    CopyBuf { reader, writer, amt: 0 }
 }
 
 pin_project! {
@@ -56,8 +52,9 @@ pin_project! {
 }
 
 impl<R, W> Future for CopyBuf<'_, R, W>
-    where R: AsyncBufRead,
-          W: AsyncWrite + Unpin + ?Sized,
+where
+    R: AsyncBufRead,
+    W: AsyncWrite + Unpin + ?Sized,
 {
     type Output = io::Result<u64>;
 
@@ -72,7 +69,7 @@ impl<R, W> Future for CopyBuf<'_, R, W>
 
             let i = ready!(Pin::new(&mut this.writer).poll_write(cx, buffer))?;
             if i == 0 {
-                return Poll::Ready(Err(io::ErrorKind::WriteZero.into()))
+                return Poll::Ready(Err(io::ErrorKind::WriteZero.into()));
             }
             *this.amt += i as u64;
             this.reader.as_mut().consume(i);
diff --git a/third_party/rust/futures-util/src/io/cursor.rs b/third_party/rust/futures-util/src/io/cursor.rs
index b11dbf54f4898c480e127054a2092e7e8fdf7450..b6fb3724c72fbca0abb6c85fbd56234e0f24baef 100644
--- a/third_party/rust/futures-util/src/io/cursor.rs
+++ b/third_party/rust/futures-util/src/io/cursor.rs
@@ -13,7 +13,7 @@ use std::pin::Pin;
 /// allowing these buffers to be used anywhere you might use a reader or writer
 /// that does actual I/O.
 ///
-/// The standard library implements some I/O traits on various types which
+/// This library implements some I/O traits on various types which
 /// are commonly used as a buffer, like `Cursor<`[`Vec`]`<u8>>` and
 /// `Cursor<`[`&[u8]`][bytes]`>`.
 ///
@@ -43,9 +43,7 @@ impl<T> Cursor<T> {
     /// # force_inference(&buff);
     /// ```
     pub fn new(inner: T) -> Self {
-        Self {
-            inner: io::Cursor::new(inner),
-        }
+        Self { inner: io::Cursor::new(inner) }
     }
 
     /// Consumes this cursor, returning the underlying value.
@@ -199,15 +197,19 @@ where
 
 macro_rules! delegate_async_write_to_stdio {
     () => {
-        fn poll_write(mut self: Pin<&mut Self>, _: &mut Context<'_>, buf: &[u8])
-            -> Poll<io::Result<usize>>
-        {
+        fn poll_write(
+            mut self: Pin<&mut Self>,
+            _: &mut Context<'_>,
+            buf: &[u8],
+        ) -> Poll<io::Result<usize>> {
             Poll::Ready(io::Write::write(&mut self.inner, buf))
         }
 
-        fn poll_write_vectored(mut self: Pin<&mut Self>, _: &mut Context<'_>, bufs: &[IoSlice<'_>])
-            -> Poll<io::Result<usize>>
-        {
+        fn poll_write_vectored(
+            mut self: Pin<&mut Self>,
+            _: &mut Context<'_>,
+            bufs: &[IoSlice<'_>],
+        ) -> Poll<io::Result<usize>> {
             Poll::Ready(io::Write::write_vectored(&mut self.inner, bufs))
         }
 
@@ -218,7 +220,7 @@ macro_rules! delegate_async_write_to_stdio {
         fn poll_close(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
             self.poll_flush(cx)
         }
-    }
+    };
 }
 
 impl AsyncWrite for Cursor<&mut [u8]> {
diff --git a/third_party/rust/futures-util/src/io/fill_buf.rs b/third_party/rust/futures-util/src/io/fill_buf.rs
index 6fb3ec73aa17be5aed1f77ef909e9900f74c135f..19b0d2044c7a11e17262f4288abf531712884b7c 100644
--- a/third_party/rust/futures-util/src/io/fill_buf.rs
+++ b/third_party/rust/futures-util/src/io/fill_buf.rs
@@ -20,7 +20,8 @@ impl<'a, R: AsyncBufRead + ?Sized + Unpin> FillBuf<'a, R> {
 }
 
 impl<'a, R> Future for FillBuf<'a, R>
-    where R: AsyncBufRead + ?Sized + Unpin,
+where
+    R: AsyncBufRead + ?Sized + Unpin,
 {
     type Output = io::Result<&'a [u8]>;
 
diff --git a/third_party/rust/futures-util/src/io/flush.rs b/third_party/rust/futures-util/src/io/flush.rs
index ece0a7cdc009ab104404cc2d7d798ac08d88a2f6..b75d14c5d3c447d889d8c02bffc09a818f71043d 100644
--- a/third_party/rust/futures-util/src/io/flush.rs
+++ b/third_party/rust/futures-util/src/io/flush.rs
@@ -20,7 +20,8 @@ impl<'a, W: AsyncWrite + ?Sized + Unpin> Flush<'a, W> {
 }
 
 impl<W> Future for Flush<'_, W>
-    where W: AsyncWrite + ?Sized + Unpin,
+where
+    W: AsyncWrite + ?Sized + Unpin,
 {
     type Output = io::Result<()>;
 
diff --git a/third_party/rust/futures-util/src/io/into_sink.rs b/third_party/rust/futures-util/src/io/into_sink.rs
index 885ba2fb8deafc273f065dd7101a5435dc3cc5e5..384b8e3b922ed21b2410baab1b2c30161941daae 100644
--- a/third_party/rust/futures-util/src/io/into_sink.rs
+++ b/third_party/rust/futures-util/src/io/into_sink.rs
@@ -2,9 +2,9 @@ use futures_core::ready;
 use futures_core::task::{Context, Poll};
 use futures_io::AsyncWrite;
 use futures_sink::Sink;
+use pin_project_lite::pin_project;
 use std::io;
 use std::pin::Pin;
-use pin_project_lite::pin_project;
 
 #[derive(Debug)]
 struct Block<Item> {
@@ -36,8 +36,7 @@ impl<W: AsyncWrite, Item: AsRef<[u8]>> IntoSink<W, Item> {
     fn poll_flush_buffer(
         self: Pin<&mut Self>,
         cx: &mut Context<'_>,
-    ) -> Poll<Result<(), io::Error>>
-    {
+    ) -> Poll<Result<(), io::Error>> {
         let mut this = self.project();
 
         if let Some(buffer) = this.buffer {
@@ -53,47 +52,30 @@ impl<W: AsyncWrite, Item: AsRef<[u8]>> IntoSink<W, Item> {
         *this.buffer = None;
         Poll::Ready(Ok(()))
     }
-
 }
 
 impl<W: AsyncWrite, Item: AsRef<[u8]>> Sink<Item> for IntoSink<W, Item> {
     type Error = io::Error;
 
-    fn poll_ready(
-        self: Pin<&mut Self>,
-        cx: &mut Context<'_>,
-    ) -> Poll<Result<(), Self::Error>>
-    {
+    fn poll_ready(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
         ready!(self.poll_flush_buffer(cx))?;
         Poll::Ready(Ok(()))
     }
 
     #[allow(clippy::debug_assert_with_mut_call)]
-    fn start_send(
-        self: Pin<&mut Self>,
-        item: Item,
-    ) -> Result<(), Self::Error>
-    {
+    fn start_send(self: Pin<&mut Self>, item: Item) -> Result<(), Self::Error> {
         debug_assert!(self.buffer.is_none());
         *self.project().buffer = Some(Block { offset: 0, bytes: item });
         Ok(())
     }
 
-    fn poll_flush(
-        mut self: Pin<&mut Self>,
-        cx: &mut Context<'_>,
-    ) -> Poll<Result<(), Self::Error>>
-    {
+    fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
         ready!(self.as_mut().poll_flush_buffer(cx))?;
         ready!(self.project().writer.poll_flush(cx))?;
         Poll::Ready(Ok(()))
     }
 
-    fn poll_close(
-        mut self: Pin<&mut Self>,
-        cx: &mut Context<'_>,
-    ) -> Poll<Result<(), Self::Error>>
-    {
+    fn poll_close(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
         ready!(self.as_mut().poll_flush_buffer(cx))?;
         ready!(self.project().writer.poll_close(cx))?;
         Poll::Ready(Ok(()))
diff --git a/third_party/rust/futures-util/src/io/lines.rs b/third_party/rust/futures-util/src/io/lines.rs
index 6ae7392245f9b5ce62ded2bf2f9f8f78c1801d65..13e70df238561cb19396ea34c028aed1e83af5ff 100644
--- a/third_party/rust/futures-util/src/io/lines.rs
+++ b/third_party/rust/futures-util/src/io/lines.rs
@@ -1,12 +1,12 @@
+use super::read_line::read_line_internal;
 use futures_core::ready;
 use futures_core::stream::Stream;
 use futures_core::task::{Context, Poll};
 use futures_io::AsyncBufRead;
+use pin_project_lite::pin_project;
 use std::io;
 use std::mem;
 use std::pin::Pin;
-use super::read_line::read_line_internal;
-use pin_project_lite::pin_project;
 
 pin_project! {
     /// Stream for the [`lines`](super::AsyncBufReadExt::lines) method.
@@ -23,12 +23,7 @@ pin_project! {
 
 impl<R: AsyncBufRead> Lines<R> {
     pub(super) fn new(reader: R) -> Self {
-        Self {
-            reader,
-            buf: String::new(),
-            bytes: Vec::new(),
-            read: 0,
-        }
+        Self { reader, buf: String::new(), bytes: Vec::new(), read: 0 }
     }
 }
 
@@ -39,7 +34,7 @@ impl<R: AsyncBufRead> Stream for Lines<R> {
         let this = self.project();
         let n = ready!(read_line_internal(this.reader, cx, this.buf, this.bytes, this.read))?;
         if n == 0 && this.buf.is_empty() {
-            return Poll::Ready(None)
+            return Poll::Ready(None);
         }
         if this.buf.ends_with('\n') {
             this.buf.pop();
diff --git a/third_party/rust/futures-util/src/io/mod.rs b/third_party/rust/futures-util/src/io/mod.rs
index a7e2add34d05a70cba91ac6ef0c8b23c8fb2e563..b96223d1c110dd697e17780b17a2a98b838001d2 100644
--- a/third_party/rust/futures-util/src/io/mod.rs
+++ b/third_party/rust/futures-util/src/io/mod.rs
@@ -19,15 +19,20 @@
 #[cfg(feature = "io-compat")]
 #[cfg_attr(docsrs, doc(cfg(feature = "io-compat")))]
 use crate::compat::Compat;
-use std::{ptr, pin::Pin};
+use crate::future::assert_future;
+use crate::stream::assert_stream;
+use std::{pin::Pin, ptr};
 
-pub use futures_io::{
-    AsyncRead, AsyncWrite, AsyncSeek, AsyncBufRead, Error, ErrorKind,
-    IoSlice, IoSliceMut, Result, SeekFrom,
-};
+// Re-export some types from `std::io` so that users don't have to deal
+// with conflicts when `use`ing `futures::io` and `std::io`.
+#[doc(no_inline)]
 #[cfg(feature = "read-initializer")]
 #[cfg_attr(docsrs, doc(cfg(feature = "read-initializer")))]
-pub use futures_io::Initializer;
+pub use std::io::Initializer;
+#[doc(no_inline)]
+pub use std::io::{Error, ErrorKind, IoSlice, IoSliceMut, Result, SeekFrom};
+
+pub use futures_io::{AsyncBufRead, AsyncRead, AsyncSeek, AsyncWrite};
 
 // used by `BufReader` and `BufWriter`
 // https://github.com/rust-lang/rust/blob/master/src/libstd/sys_common/io.rs#L1
@@ -121,7 +126,7 @@ mod sink;
 pub use self::sink::{sink, Sink};
 
 mod split;
-pub use self::split::{ReadHalf, WriteHalf, ReuniteError};
+pub use self::split::{ReadHalf, ReuniteError, WriteHalf};
 
 mod take;
 pub use self::take::Take;
@@ -173,7 +178,7 @@ pub trait AsyncReadExt: AsyncRead {
         Self: Sized,
         R: AsyncRead,
     {
-        Chain::new(self, next)
+        assert_read(Chain::new(self, next))
     }
 
     /// Tries to read some bytes directly into the given `buf` in asynchronous
@@ -201,9 +206,10 @@ pub trait AsyncReadExt: AsyncRead {
     /// # Ok::<(), Box<dyn std::error::Error>>(()) }).unwrap();
     /// ```
     fn read<'a>(&'a mut self, buf: &'a mut [u8]) -> Read<'a, Self>
-        where Self: Unpin,
+    where
+        Self: Unpin,
     {
-        Read::new(self, buf)
+        assert_future::<Result<usize>, _>(Read::new(self, buf))
     }
 
     /// Creates a future which will read from the `AsyncRead` into `bufs` using vectored
@@ -212,9 +218,10 @@ pub trait AsyncReadExt: AsyncRead {
     /// The returned future will resolve to the number of bytes read once the read
     /// operation is completed.
     fn read_vectored<'a>(&'a mut self, bufs: &'a mut [IoSliceMut<'a>]) -> ReadVectored<'a, Self>
-        where Self: Unpin,
+    where
+        Self: Unpin,
     {
-        ReadVectored::new(self, bufs)
+        assert_future::<Result<usize>, _>(ReadVectored::new(self, bufs))
     }
 
     /// Creates a future which will read exactly enough bytes to fill `buf`,
@@ -254,13 +261,11 @@ pub trait AsyncReadExt: AsyncRead {
     /// assert_eq!(result.unwrap_err().kind(), io::ErrorKind::UnexpectedEof);
     /// # });
     /// ```
-    fn read_exact<'a>(
-        &'a mut self,
-        buf: &'a mut [u8],
-    ) -> ReadExact<'a, Self>
-        where Self: Unpin,
+    fn read_exact<'a>(&'a mut self, buf: &'a mut [u8]) -> ReadExact<'a, Self>
+    where
+        Self: Unpin,
     {
-        ReadExact::new(self, buf)
+        assert_future::<Result<()>, _>(ReadExact::new(self, buf))
     }
 
     /// Creates a future which will read all the bytes from this `AsyncRead`.
@@ -282,13 +287,11 @@ pub trait AsyncReadExt: AsyncRead {
     /// assert_eq!(output, vec![1, 2, 3, 4]);
     /// # Ok::<(), Box<dyn std::error::Error>>(()) }).unwrap();
     /// ```
-    fn read_to_end<'a>(
-        &'a mut self,
-        buf: &'a mut Vec<u8>,
-    ) -> ReadToEnd<'a, Self>
-        where Self: Unpin,
+    fn read_to_end<'a>(&'a mut self, buf: &'a mut Vec<u8>) -> ReadToEnd<'a, Self>
+    where
+        Self: Unpin,
     {
-        ReadToEnd::new(self, buf)
+        assert_future::<Result<usize>, _>(ReadToEnd::new(self, buf))
     }
 
     /// Creates a future which will read all the bytes from this `AsyncRead`.
@@ -310,13 +313,11 @@ pub trait AsyncReadExt: AsyncRead {
     /// assert_eq!(buffer, String::from("1234"));
     /// # Ok::<(), Box<dyn std::error::Error>>(()) }).unwrap();
     /// ```
-    fn read_to_string<'a>(
-        &'a mut self,
-        buf: &'a mut String,
-    ) -> ReadToString<'a, Self>
-        where Self: Unpin,
+    fn read_to_string<'a>(&'a mut self, buf: &'a mut String) -> ReadToString<'a, Self>
+    where
+        Self: Unpin,
     {
-        ReadToString::new(self, buf)
+        assert_future::<Result<usize>, _>(ReadToString::new(self, buf))
     }
 
     /// Helper method for splitting this read/write object into two halves.
@@ -349,9 +350,11 @@ pub trait AsyncReadExt: AsyncRead {
     /// # Ok::<(), Box<dyn std::error::Error>>(()) }).unwrap();
     /// ```
     fn split(self) -> (ReadHalf<Self>, WriteHalf<Self>)
-        where Self: AsyncWrite + Sized,
+    where
+        Self: AsyncWrite + Sized,
     {
-        split::split(self)
+        let (r, w) = split::split(self);
+        (assert_read(r), assert_write(w))
     }
 
     /// Creates an AsyncRead adapter which will read at most `limit` bytes
@@ -374,9 +377,10 @@ pub trait AsyncReadExt: AsyncRead {
     /// # Ok::<(), Box<dyn std::error::Error>>(()) }).unwrap();
     /// ```
     fn take(self, limit: u64) -> Take<Self>
-        where Self: Sized
+    where
+        Self: Sized,
     {
-        Take::new(self, limit)
+        assert_read(Take::new(self, limit))
     }
 
     /// Wraps an [`AsyncRead`] in a compatibility wrapper that allows it to be
@@ -388,7 +392,8 @@ pub trait AsyncReadExt: AsyncRead {
     #[cfg(feature = "io-compat")]
     #[cfg_attr(docsrs, doc(cfg(feature = "io-compat")))]
     fn compat(self) -> Compat<Self>
-        where Self: Sized + Unpin,
+    where
+        Self: Sized + Unpin,
     {
         Compat::new(self)
     }
@@ -421,16 +426,18 @@ pub trait AsyncWriteExt: AsyncWrite {
     /// # Ok::<(), Box<dyn std::error::Error>>(()) }).unwrap();
     /// ```
     fn flush(&mut self) -> Flush<'_, Self>
-        where Self: Unpin,
+    where
+        Self: Unpin,
     {
-        Flush::new(self)
+        assert_future::<Result<()>, _>(Flush::new(self))
     }
 
     /// Creates a future which will entirely close this `AsyncWrite`.
     fn close(&mut self) -> Close<'_, Self>
-        where Self: Unpin,
+    where
+        Self: Unpin,
     {
-        Close::new(self)
+        assert_future::<Result<()>, _>(Close::new(self))
     }
 
     /// Creates a future which will write bytes from `buf` into the object.
@@ -438,9 +445,10 @@ pub trait AsyncWriteExt: AsyncWrite {
     /// The returned future will resolve to the number of bytes written once the write
     /// operation is completed.
     fn write<'a>(&'a mut self, buf: &'a [u8]) -> Write<'a, Self>
-        where Self: Unpin,
+    where
+        Self: Unpin,
     {
-        Write::new(self, buf)
+        assert_future::<Result<usize>, _>(Write::new(self, buf))
     }
 
     /// Creates a future which will write bytes from `bufs` into the object using vectored
@@ -449,9 +457,10 @@ pub trait AsyncWriteExt: AsyncWrite {
     /// The returned future will resolve to the number of bytes written once the write
     /// operation is completed.
     fn write_vectored<'a>(&'a mut self, bufs: &'a [IoSlice<'a>]) -> WriteVectored<'a, Self>
-        where Self: Unpin,
+    where
+        Self: Unpin,
     {
-        WriteVectored::new(self, bufs)
+        assert_future::<Result<usize>, _>(WriteVectored::new(self, bufs))
     }
 
     /// Write data into this object.
@@ -475,9 +484,10 @@ pub trait AsyncWriteExt: AsyncWrite {
     /// # Ok::<(), Box<dyn std::error::Error>>(()) }).unwrap();
     /// ```
     fn write_all<'a>(&'a mut self, buf: &'a [u8]) -> WriteAll<'a, Self>
-        where Self: Unpin,
+    where
+        Self: Unpin,
     {
-        WriteAll::new(self, buf)
+        assert_future::<Result<()>, _>(WriteAll::new(self, buf))
     }
 
     /// Attempts to write multiple buffers into this writer.
@@ -532,7 +542,7 @@ pub trait AsyncWriteExt: AsyncWrite {
     where
         Self: Unpin,
     {
-        WriteAllVectored::new(self, bufs)
+        assert_future::<Result<()>, _>(WriteAllVectored::new(self, bufs))
     }
 
     /// Wraps an [`AsyncWrite`] in a compatibility wrapper that allows it to be
@@ -541,7 +551,8 @@ pub trait AsyncWriteExt: AsyncWrite {
     #[cfg(feature = "io-compat")]
     #[cfg_attr(docsrs, doc(cfg(feature = "io-compat")))]
     fn compat_write(self) -> Compat<Self>
-        where Self: Sized + Unpin,
+    where
+        Self: Sized + Unpin,
     {
         Compat::new(self)
     }
@@ -575,9 +586,10 @@ pub trait AsyncWriteExt: AsyncWrite {
     #[cfg(feature = "sink")]
     #[cfg_attr(docsrs, doc(cfg(feature = "sink")))]
     fn into_sink<Item: AsRef<[u8]>>(self) -> IntoSink<Self, Item>
-        where Self: Sized,
+    where
+        Self: Sized,
     {
-        IntoSink::new(self)
+        crate::sink::assert_sink::<Item, Error, _>(IntoSink::new(self))
     }
 }
 
@@ -591,9 +603,21 @@ pub trait AsyncSeekExt: AsyncSeek {
     /// In the case of an error the buffer and the object will be discarded, with
     /// the error yielded.
     fn seek(&mut self, pos: SeekFrom) -> Seek<'_, Self>
-        where Self: Unpin,
+    where
+        Self: Unpin,
     {
-        Seek::new(self, pos)
+        assert_future::<Result<u64>, _>(Seek::new(self, pos))
+    }
+
+    /// Creates a future which will return the current seek position from the
+    /// start of the stream.
+    ///
+    /// This is equivalent to `self.seek(SeekFrom::Current(0))`.
+    fn stream_position(&mut self) -> Seek<'_, Self>
+    where
+        Self: Unpin,
+    {
+        self.seek(SeekFrom::Current(0))
     }
 }
 
@@ -625,9 +649,10 @@ pub trait AsyncBufReadExt: AsyncBufRead {
     /// # Ok::<(), Box<dyn std::error::Error>>(()) }).unwrap();
     /// ```
     fn fill_buf(&mut self) -> FillBuf<'_, Self>
-        where Self: Unpin,
+    where
+        Self: Unpin,
     {
-        FillBuf::new(self)
+        assert_future::<Result<&[u8]>, _>(FillBuf::new(self))
     }
 
     /// A convenience for calling [`AsyncBufRead::consume`] on [`Unpin`] IO types.
@@ -648,7 +673,8 @@ pub trait AsyncBufReadExt: AsyncBufRead {
     /// # Ok::<(), Box<dyn std::error::Error>>(()) }).unwrap();
     /// ```
     fn consume_unpin(&mut self, amt: usize)
-        where Self: Unpin,
+    where
+        Self: Unpin,
     {
         Pin::new(self).consume(amt)
     }
@@ -694,14 +720,11 @@ pub trait AsyncBufReadExt: AsyncBufRead {
     /// assert_eq!(buf, b"");
     /// # Ok::<(), Box<dyn std::error::Error>>(()) }).unwrap();
     /// ```
-    fn read_until<'a>(
-        &'a mut self,
-        byte: u8,
-        buf: &'a mut Vec<u8>,
-    ) -> ReadUntil<'a, Self>
-        where Self: Unpin,
+    fn read_until<'a>(&'a mut self, byte: u8, buf: &'a mut Vec<u8>) -> ReadUntil<'a, Self>
+    where
+        Self: Unpin,
     {
-        ReadUntil::new(self, byte, buf)
+        assert_future::<Result<usize>, _>(ReadUntil::new(self, byte, buf))
     }
 
     /// Creates a future which will read all the bytes associated with this I/O
@@ -756,9 +779,10 @@ pub trait AsyncBufReadExt: AsyncBufRead {
     /// # Ok::<(), Box<dyn std::error::Error>>(()) }).unwrap();
     /// ```
     fn read_line<'a>(&'a mut self, buf: &'a mut String) -> ReadLine<'a, Self>
-        where Self: Unpin,
+    where
+        Self: Unpin,
     {
-        ReadLine::new(self, buf)
+        assert_future::<Result<usize>, _>(ReadLine::new(self, buf))
     }
 
     /// Returns a stream over the lines of this reader.
@@ -794,10 +818,28 @@ pub trait AsyncBufReadExt: AsyncBufRead {
     /// # Ok::<(), Box<dyn std::error::Error>>(()) }).unwrap();
     /// ```
     fn lines(self) -> Lines<Self>
-        where Self: Sized,
+    where
+        Self: Sized,
     {
-        Lines::new(self)
+        assert_stream::<Result<String>, _>(Lines::new(self))
     }
 }
 
 impl<R: AsyncBufRead + ?Sized> AsyncBufReadExt for R {}
+
+// Just a helper function to ensure the reader we're returning all have the
+// right implementations.
+pub(crate) fn assert_read<R>(reader: R) -> R
+where
+    R: AsyncRead,
+{
+    reader
+}
+// Just a helper function to ensure the writer we're returning all have the
+// right implementations.
+pub(crate) fn assert_write<W>(writer: W) -> W
+where
+    W: AsyncWrite,
+{
+    writer
+}
diff --git a/third_party/rust/futures-util/src/io/read_exact.rs b/third_party/rust/futures-util/src/io/read_exact.rs
index f2e0440890ba2ef63618bd77e4b7e9ef78b30565..02e38c35be07c87fd0b7938485420289a03ec35a 100644
--- a/third_party/rust/futures-util/src/io/read_exact.rs
+++ b/third_party/rust/futures-util/src/io/read_exact.rs
@@ -1,6 +1,6 @@
 use crate::io::AsyncRead;
-use futures_core::ready;
 use futures_core::future::Future;
+use futures_core::ready;
 use futures_core::task::{Context, Poll};
 use std::io;
 use std::mem;
@@ -34,7 +34,7 @@ impl<R: AsyncRead + ?Sized + Unpin> Future for ReadExact<'_, R> {
                 this.buf = rest;
             }
             if n == 0 {
-                return Poll::Ready(Err(io::ErrorKind::UnexpectedEof.into()))
+                return Poll::Ready(Err(io::ErrorKind::UnexpectedEof.into()));
             }
         }
         Poll::Ready(Ok(()))
diff --git a/third_party/rust/futures-util/src/io/read_line.rs b/third_party/rust/futures-util/src/io/read_line.rs
index d402c966056bb4f5e7b724eb0ee49f2aeb9f14a1..c75af9471f8453c1a783745d816194225524e4ef 100644
--- a/third_party/rust/futures-util/src/io/read_line.rs
+++ b/third_party/rust/futures-util/src/io/read_line.rs
@@ -1,12 +1,12 @@
-use futures_core::ready;
+use super::read_until::read_until_internal;
 use futures_core::future::Future;
+use futures_core::ready;
 use futures_core::task::{Context, Poll};
 use futures_io::AsyncBufRead;
 use std::io;
 use std::mem;
 use std::pin::Pin;
 use std::str;
-use super::read_until::read_until_internal;
 
 /// Future for the [`read_line`](super::AsyncBufReadExt::read_line) method.
 #[derive(Debug)]
@@ -22,12 +22,7 @@ impl<R: ?Sized + Unpin> Unpin for ReadLine<'_, R> {}
 
 impl<'a, R: AsyncBufRead + ?Sized + Unpin> ReadLine<'a, R> {
     pub(super) fn new(reader: &'a mut R, buf: &'a mut String) -> Self {
-        Self {
-            reader,
-            bytes: mem::replace(buf, String::new()).into_bytes(),
-            buf,
-            read: 0,
-        }
+        Self { reader, bytes: mem::replace(buf, String::new()).into_bytes(), buf, read: 0 }
     }
 }
 
diff --git a/third_party/rust/futures-util/src/io/read_to_end.rs b/third_party/rust/futures-util/src/io/read_to_end.rs
index 7bd2c899143175ec7f532ce01e0caa819f30b87d..919d7d13c7e73d70710d19b46fd9bd5b7de0859c 100644
--- a/third_party/rust/futures-util/src/io/read_to_end.rs
+++ b/third_party/rust/futures-util/src/io/read_to_end.rs
@@ -20,11 +20,7 @@ impl<R: ?Sized + Unpin> Unpin for ReadToEnd<'_, R> {}
 impl<'a, R: AsyncRead + ?Sized + Unpin> ReadToEnd<'a, R> {
     pub(super) fn new(reader: &'a mut R, buf: &'a mut Vec<u8>) -> Self {
         let start_len = buf.len();
-        Self {
-            reader,
-            buf,
-            start_len,
-        }
+        Self { reader, buf, start_len }
     }
 }
 
@@ -56,10 +52,7 @@ pub(super) fn read_to_end_internal<R: AsyncRead + ?Sized>(
     buf: &mut Vec<u8>,
     start_len: usize,
 ) -> Poll<io::Result<usize>> {
-    let mut g = Guard {
-        len: buf.len(),
-        buf,
-    };
+    let mut g = Guard { len: buf.len(), buf };
     loop {
         if g.len == g.buf.len() {
             unsafe {
diff --git a/third_party/rust/futures-util/src/io/read_to_string.rs b/third_party/rust/futures-util/src/io/read_to_string.rs
index 9242654ff13839e21ff2905fa86ec4b6384f3296..457af59e4fc7573d19ebbda90b06ea5a932ef8f1 100644
--- a/third_party/rust/futures-util/src/io/read_to_string.rs
+++ b/third_party/rust/futures-util/src/io/read_to_string.rs
@@ -1,6 +1,6 @@
 use super::read_to_end::read_to_end_internal;
-use futures_core::ready;
 use futures_core::future::Future;
+use futures_core::ready;
 use futures_core::task::{Context, Poll};
 use futures_io::AsyncRead;
 use std::pin::Pin;
@@ -22,12 +22,7 @@ impl<R: ?Sized + Unpin> Unpin for ReadToString<'_, R> {}
 impl<'a, R: AsyncRead + ?Sized + Unpin> ReadToString<'a, R> {
     pub(super) fn new(reader: &'a mut R, buf: &'a mut String) -> Self {
         let start_len = buf.len();
-        Self {
-            reader,
-            bytes: mem::replace(buf, String::new()).into_bytes(),
-            buf,
-            start_len,
-        }
+        Self { reader, bytes: mem::replace(buf, String::new()).into_bytes(), buf, start_len }
     }
 }
 
@@ -41,10 +36,7 @@ fn read_to_string_internal<R: AsyncRead + ?Sized>(
     let ret = ready!(read_to_end_internal(reader, cx, bytes, start_len));
     if str::from_utf8(bytes).is_err() {
         Poll::Ready(ret.and_then(|_| {
-            Err(io::Error::new(
-                io::ErrorKind::InvalidData,
-                "stream did not contain valid UTF-8",
-            ))
+            Err(io::Error::new(io::ErrorKind::InvalidData, "stream did not contain valid UTF-8"))
         }))
     } else {
         debug_assert!(buf.is_empty());
diff --git a/third_party/rust/futures-util/src/io/split.rs b/third_party/rust/futures-util/src/io/split.rs
index 185c21c7d43e87ae29d433a697c25588769f9db3..3f1b9af4568510c5b8ca4b320396332dfddacadb 100644
--- a/third_party/rust/futures-util/src/io/split.rs
+++ b/third_party/rust/futures-util/src/io/split.rs
@@ -1,8 +1,8 @@
 use crate::lock::BiLock;
+use core::fmt;
 use futures_core::ready;
 use futures_core::task::{Context, Poll};
 use futures_io::{AsyncRead, AsyncWrite, IoSlice, IoSliceMut};
-use core::fmt;
 use std::io;
 use std::pin::Pin;
 
@@ -18,12 +18,9 @@ pub struct WriteHalf<T> {
     handle: BiLock<T>,
 }
 
-fn lock_and_then<T, U, E, F>(
-    lock: &BiLock<T>,
-    cx: &mut Context<'_>,
-    f: F
-) -> Poll<Result<U, E>>
-    where F: FnOnce(Pin<&mut T>, &mut Context<'_>) -> Poll<Result<U, E>>
+fn lock_and_then<T, U, E, F>(lock: &BiLock<T>, cx: &mut Context<'_>, f: F) -> Poll<Result<U, E>>
+where
+    F: FnOnce(Pin<&mut T>, &mut Context<'_>) -> Poll<Result<U, E>>,
 {
     let mut l = ready!(lock.poll_lock(cx));
     f(l.as_pin_mut(), cx)
@@ -39,9 +36,9 @@ impl<T: Unpin> ReadHalf<T> {
     /// together. Succeeds only if the `ReadHalf<T>` and `WriteHalf<T>` are
     /// a matching pair originating from the same call to `AsyncReadExt::split`.
     pub fn reunite(self, other: WriteHalf<T>) -> Result<T, ReuniteError<T>> {
-        self.handle.reunite(other.handle).map_err(|err| {
-            ReuniteError(ReadHalf { handle: err.0 }, WriteHalf { handle: err.1 })
-        })
+        self.handle
+            .reunite(other.handle)
+            .map_err(|err| ReuniteError(ReadHalf { handle: err.0 }, WriteHalf { handle: err.1 }))
     }
 }
 
@@ -55,29 +52,37 @@ impl<T: Unpin> WriteHalf<T> {
 }
 
 impl<R: AsyncRead> AsyncRead for ReadHalf<R> {
-    fn poll_read(self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &mut [u8])
-        -> Poll<io::Result<usize>>
-    {
+    fn poll_read(
+        self: Pin<&mut Self>,
+        cx: &mut Context<'_>,
+        buf: &mut [u8],
+    ) -> Poll<io::Result<usize>> {
         lock_and_then(&self.handle, cx, |l, cx| l.poll_read(cx, buf))
     }
 
-    fn poll_read_vectored(self: Pin<&mut Self>, cx: &mut Context<'_>, bufs: &mut [IoSliceMut<'_>])
-        -> Poll<io::Result<usize>>
-    {
+    fn poll_read_vectored(
+        self: Pin<&mut Self>,
+        cx: &mut Context<'_>,
+        bufs: &mut [IoSliceMut<'_>],
+    ) -> Poll<io::Result<usize>> {
         lock_and_then(&self.handle, cx, |l, cx| l.poll_read_vectored(cx, bufs))
     }
 }
 
 impl<W: AsyncWrite> AsyncWrite for WriteHalf<W> {
-    fn poll_write(self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &[u8])
-        -> Poll<io::Result<usize>>
-    {
+    fn poll_write(
+        self: Pin<&mut Self>,
+        cx: &mut Context<'_>,
+        buf: &[u8],
+    ) -> Poll<io::Result<usize>> {
         lock_and_then(&self.handle, cx, |l, cx| l.poll_write(cx, buf))
     }
 
-    fn poll_write_vectored(self: Pin<&mut Self>, cx: &mut Context<'_>, bufs: &[IoSlice<'_>])
-        -> Poll<io::Result<usize>>
-    {
+    fn poll_write_vectored(
+        self: Pin<&mut Self>,
+        cx: &mut Context<'_>,
+        bufs: &[IoSlice<'_>],
+    ) -> Poll<io::Result<usize>> {
         lock_and_then(&self.handle, cx, |l, cx| l.poll_write_vectored(cx, bufs))
     }
 
@@ -96,9 +101,7 @@ pub struct ReuniteError<T>(pub ReadHalf<T>, pub WriteHalf<T>);
 
 impl<T> fmt::Debug for ReuniteError<T> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.debug_tuple("ReuniteError")
-            .field(&"...")
-            .finish()
+        f.debug_tuple("ReuniteError").field(&"...").finish()
     }
 }
 
diff --git a/third_party/rust/futures-util/src/io/take.rs b/third_party/rust/futures-util/src/io/take.rs
index 687a69744f237a577279c6078aeeff3d9702eb58..05830203d0d82f2905985100d6d331e409d2c911 100644
--- a/third_party/rust/futures-util/src/io/take.rs
+++ b/third_party/rust/futures-util/src/io/take.rs
@@ -2,10 +2,10 @@ use futures_core::ready;
 use futures_core::task::{Context, Poll};
 #[cfg(feature = "read-initializer")]
 use futures_io::Initializer;
-use futures_io::{AsyncRead, AsyncBufRead};
+use futures_io::{AsyncBufRead, AsyncRead};
 use pin_project_lite::pin_project;
-use std::{cmp, io};
 use std::pin::Pin;
+use std::{cmp, io};
 
 pin_project! {
     /// Reader for the [`take`](super::AsyncReadExt::take) method.
@@ -14,14 +14,13 @@ pin_project! {
     pub struct Take<R> {
         #[pin]
         inner: R,
-        // Add '_' to avoid conflicts with `limit` method.
-        limit_: u64,
+        limit: u64,
     }
 }
 
 impl<R: AsyncRead> Take<R> {
     pub(super) fn new(inner: R, limit: u64) -> Self {
-        Self { inner, limit_: limit }
+        Self { inner, limit }
     }
 
     /// Returns the remaining number of bytes that can be
@@ -48,7 +47,7 @@ impl<R: AsyncRead> Take<R> {
     /// # Ok::<(), Box<dyn std::error::Error>>(()) }).unwrap();
     /// ```
     pub fn limit(&self) -> u64 {
-        self.limit_
+        self.limit
     }
 
     /// Sets the number of bytes that can be read before this instance will
@@ -78,7 +77,7 @@ impl<R: AsyncRead> Take<R> {
     /// # Ok::<(), Box<dyn std::error::Error>>(()) }).unwrap();
     /// ```
     pub fn set_limit(&mut self, limit: u64) {
-        self.limit_ = limit
+        self.limit = limit
     }
 
     delegate_access_inner!(inner, R, ());
@@ -92,13 +91,13 @@ impl<R: AsyncRead> AsyncRead for Take<R> {
     ) -> Poll<Result<usize, io::Error>> {
         let this = self.project();
 
-        if *this.limit_ == 0 {
+        if *this.limit == 0 {
             return Poll::Ready(Ok(0));
         }
 
-        let max = cmp::min(buf.len() as u64, *this.limit_) as usize;
+        let max = cmp::min(buf.len() as u64, *this.limit) as usize;
         let n = ready!(this.inner.poll_read(cx, &mut buf[..max]))?;
-        *this.limit_ -= n as u64;
+        *this.limit -= n as u64;
         Poll::Ready(Ok(n))
     }
 
@@ -113,12 +112,12 @@ impl<R: AsyncBufRead> AsyncBufRead for Take<R> {
         let this = self.project();
 
         // Don't call into inner reader at all at EOF because it may still block
-        if *this.limit_ == 0 {
+        if *this.limit == 0 {
             return Poll::Ready(Ok(&[]));
         }
 
         let buf = ready!(this.inner.poll_fill_buf(cx)?);
-        let cap = cmp::min(buf.len() as u64, *this.limit_) as usize;
+        let cap = cmp::min(buf.len() as u64, *this.limit) as usize;
         Poll::Ready(Ok(&buf[..cap]))
     }
 
@@ -126,8 +125,8 @@ impl<R: AsyncBufRead> AsyncBufRead for Take<R> {
         let this = self.project();
 
         // Don't let callers reset the limit by passing an overlarge value
-        let amt = cmp::min(amt as u64, *this.limit_) as usize;
-        *this.limit_ -= amt as u64;
+        let amt = cmp::min(amt as u64, *this.limit) as usize;
+        *this.limit -= amt as u64;
         this.inner.consume(amt);
     }
 }
diff --git a/third_party/rust/futures-util/src/io/window.rs b/third_party/rust/futures-util/src/io/window.rs
index 3424197d75a14110f50cb470f0b51743980125b3..77b7267c695e98f87ee1a9e6ef513042f10ae3a6 100644
--- a/third_party/rust/futures-util/src/io/window.rs
+++ b/third_party/rust/futures-util/src/io/window.rs
@@ -30,10 +30,7 @@ impl<T: AsRef<[u8]>> Window<T> {
     /// Further methods can be called on the returned `Window<T>` to alter the
     /// window into the data provided.
     pub fn new(t: T) -> Self {
-        Self {
-            range: 0..t.as_ref().len(),
-            inner: t,
-        }
+        Self { range: 0..t.as_ref().len(), inner: t }
     }
 
     /// Gets a shared reference to the underlying buffer inside of this
diff --git a/third_party/rust/futures-util/src/io/write_all_vectored.rs b/third_party/rust/futures-util/src/io/write_all_vectored.rs
index 380604df98a0e33b29cd45613aae6a03bdcba4ca..f465209fe2c1e0bfc20f4c6686f5549e134aeeb3 100644
--- a/third_party/rust/futures-util/src/io/write_all_vectored.rs
+++ b/third_party/rust/futures-util/src/io/write_all_vectored.rs
@@ -1,5 +1,5 @@
-use futures_core::ready;
 use futures_core::future::Future;
+use futures_core::ready;
 use futures_core::task::{Context, Poll};
 use futures_io::AsyncWrite;
 use futures_io::IoSlice;
@@ -56,11 +56,7 @@ mod tests {
     /// Create a new writer that reads from at most `n_bufs` and reads
     /// `per_call` bytes (in total) per call to write.
     fn test_writer(n_bufs: usize, per_call: usize) -> TestWriter {
-        TestWriter {
-            n_bufs,
-            per_call,
-            written: Vec::new(),
-        }
+        TestWriter { n_bufs, per_call, written: Vec::new() }
     }
 
     // TODO: maybe move this the future-test crate?
@@ -110,10 +106,9 @@ mod tests {
             let expected = $expected;
             match $e {
                 Poll::Ready(Ok(ok)) if ok == expected => {}
-                got => panic!(
-                    "unexpected result, got: {:?}, wanted: Ready(Ok({:?}))",
-                    got, expected
-                ),
+                got => {
+                    panic!("unexpected result, got: {:?}, wanted: Ready(Ok({:?}))", got, expected)
+                }
             }
         };
     }
@@ -154,11 +149,7 @@ mod tests {
         assert_poll_ok!(dst.as_mut().poll_write_vectored(&mut cx, bufs), 3);
 
         // Read at most 3 bytes from three buffers.
-        let bufs = &[
-            IoSlice::new(&[3]),
-            IoSlice::new(&[4]),
-            IoSlice::new(&[5, 5]),
-        ];
+        let bufs = &[IoSlice::new(&[3]), IoSlice::new(&[4]), IoSlice::new(&[5, 5])];
         assert_poll_ok!(dst.as_mut().poll_write_vectored(&mut cx, bufs), 3);
 
         assert_eq!(dst.written, &[1, 2, 2, 3, 4, 5]);
diff --git a/third_party/rust/futures-util/src/lib.rs b/third_party/rust/futures-util/src/lib.rs
index 44823cc7da22267eb08047143b4847b22d815e5d..16871cb4b57ec9a7405dd44923f45871f937fd1e 100644
--- a/third_party/rust/futures-util/src/lib.rs
+++ b/third_party/rust/futures-util/src/lib.rs
@@ -1,25 +1,16 @@
 //! Combinators and utilities for working with `Future`s, `Stream`s, `Sink`s,
 //! and the `AsyncRead` and `AsyncWrite` traits.
 
-#![cfg_attr(feature = "cfg-target-has-atomic", feature(cfg_target_has_atomic))]
 #![cfg_attr(feature = "read-initializer", feature(read_initializer))]
 #![cfg_attr(feature = "write-all-vectored", feature(io_slice_advance))]
 #![cfg_attr(not(feature = "std"), no_std)]
-#![warn(
-    missing_docs,
-    missing_debug_implementations,
-    rust_2018_idioms,
-    unreachable_pub
-)]
+#![warn(missing_docs, missing_debug_implementations, rust_2018_idioms, unreachable_pub)]
 // It cannot be included in the published code because this lints have false positives in the minimum required version.
 #![cfg_attr(test, warn(single_use_lifetimes))]
 #![warn(clippy::all)]
 #![doc(test(attr(deny(warnings), allow(dead_code, unused_assignments, unused_variables))))]
 #![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");
-
 #[cfg(all(feature = "bilock", not(feature = "unstable")))]
 compile_error!("The `bilock` feature requires the `unstable` feature as an explicit opt-in to unstable features");
 
@@ -58,7 +49,7 @@ pub mod __private {
 
 macro_rules! cfg_target_has_atomic {
     ($($item:item)*) => {$(
-        #[cfg_attr(feature = "cfg-target-has-atomic", cfg(target_has_atomic = "ptr"))]
+        #[cfg(not(futures_no_atomic_cas))]
         $item
     )*};
 }
@@ -309,18 +300,18 @@ macro_rules! delegate_all {
 
 pub mod future;
 #[doc(hidden)]
-pub use crate::future::{FutureExt, TryFutureExt};
+pub use crate::future::{Future, FutureExt, TryFuture, TryFutureExt};
 
 pub mod stream;
 #[doc(hidden)]
-pub use crate::stream::{StreamExt, TryStreamExt};
+pub use crate::stream::{Stream, StreamExt, TryStream, TryStreamExt};
 
 #[cfg(feature = "sink")]
 #[cfg_attr(docsrs, doc(cfg(feature = "sink")))]
 pub mod sink;
 #[cfg(feature = "sink")]
 #[doc(hidden)]
-pub use crate::sink::SinkExt;
+pub use crate::sink::{Sink, SinkExt};
 
 pub mod task;
 
@@ -337,10 +328,18 @@ pub mod io;
 #[cfg(feature = "io")]
 #[cfg(feature = "std")]
 #[doc(hidden)]
-pub use crate::io::{AsyncBufReadExt, AsyncReadExt, AsyncSeekExt, AsyncWriteExt};
+pub use crate::io::{
+    AsyncBufRead, AsyncBufReadExt, AsyncRead, AsyncReadExt, AsyncSeek, AsyncSeekExt, AsyncWrite,
+    AsyncWriteExt,
+};
 
 #[cfg(feature = "alloc")]
 pub mod lock;
 
+cfg_target_has_atomic! {
+    #[cfg(feature = "alloc")]
+    mod abortable;
+}
+
 mod fns;
 mod unfold_state;
diff --git a/third_party/rust/futures-util/src/lock/bilock.rs b/third_party/rust/futures-util/src/lock/bilock.rs
index 600e16e4215d74f62ac61883570c3ac6c621e2f1..2f51ae7c987f38a04ae2876c0ed17cd84a75c651 100644
--- a/third_party/rust/futures-util/src/lock/bilock.rs
+++ b/third_party/rust/futures-util/src/lock/bilock.rs
@@ -1,16 +1,16 @@
 //! Futures-powered synchronization primitives.
 
-#[cfg(feature = "bilock")]
-use futures_core::future::Future;
-use futures_core::task::{Context, Poll, Waker};
+use alloc::boxed::Box;
+use alloc::sync::Arc;
 use core::cell::UnsafeCell;
 use core::fmt;
 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 = "bilock")]
+use futures_core::future::Future;
+use futures_core::task::{Context, Poll, Waker};
 
 /// A type of futures-powered synchronization primitive which is a mutex between
 /// two possible owners.
@@ -61,10 +61,7 @@ impl<T> BiLock<T> {
     /// Similarly, reuniting the lock and extracting the inner value is only
     /// possible when `T` is `Unpin`.
     pub fn new(t: T) -> (Self, Self) {
-        let arc = Arc::new(Inner {
-            state: AtomicUsize::new(0),
-            value: Some(UnsafeCell::new(t)),
-        });
+        let arc = Arc::new(Inner { state: AtomicUsize::new(0), value: Some(UnsafeCell::new(t)) });
 
         (Self { arc: arc.clone() }, Self { arc })
     }
@@ -103,11 +100,11 @@ impl<T> BiLock<T> {
                     let mut prev = Box::from_raw(n as *mut Waker);
                     *prev = cx.waker().clone();
                     waker = Some(prev);
-                }
+                },
             }
 
             // type ascription for safety's sake!
-            let me: Box<Waker> = waker.take().unwrap_or_else(||Box::new(cx.waker().clone()));
+            let me: Box<Waker> = waker.take().unwrap_or_else(|| Box::new(cx.waker().clone()));
             let me = Box::into_raw(me) as usize;
 
             match self.arc.state.compare_exchange(1, me, SeqCst, SeqCst) {
@@ -145,9 +142,7 @@ impl<T> BiLock<T> {
     #[cfg(feature = "bilock")]
     #[cfg_attr(docsrs, doc(cfg(feature = "bilock")))]
     pub fn lock(&self) -> BiLockAcquire<'_, T> {
-        BiLockAcquire {
-            bilock: self,
-        }
+        BiLockAcquire { bilock: self }
     }
 
     /// Attempts to put the two "halves" of a `BiLock<T>` back together and
@@ -181,7 +176,7 @@ impl<T> BiLock<T> {
             // up as its now their turn.
             n => unsafe {
                 Box::from_raw(n as *mut Waker).wake();
-            }
+            },
         }
     }
 }
@@ -205,9 +200,7 @@ pub struct ReuniteError<T>(pub BiLock<T>, pub BiLock<T>);
 
 impl<T> fmt::Debug for ReuniteError<T> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.debug_tuple("ReuniteError")
-            .field(&"...")
-            .finish()
+        f.debug_tuple("ReuniteError").field(&"...").finish()
     }
 }
 
diff --git a/third_party/rust/futures-util/src/lock/mutex.rs b/third_party/rust/futures-util/src/lock/mutex.rs
index a78de6283cc0d0aaedc7265dfd412ded38007858..a849aeeb3883d5ceb13552938a046495f2740298 100644
--- a/third_party/rust/futures-util/src/lock/mutex.rs
+++ b/third_party/rust/futures-util/src/lock/mutex.rs
@@ -1,13 +1,13 @@
 use futures_core::future::{FusedFuture, Future};
 use futures_core::task::{Context, Poll, Waker};
 use slab::Slab;
-use std::{fmt, mem};
 use std::cell::UnsafeCell;
 use std::marker::PhantomData;
 use std::ops::{Deref, DerefMut};
 use std::pin::Pin;
-use std::sync::Mutex as StdMutex;
 use std::sync::atomic::{AtomicUsize, Ordering};
+use std::sync::Mutex as StdMutex;
+use std::{fmt, mem};
 
 /// A futures-aware mutex.
 ///
@@ -53,7 +53,7 @@ enum Waiter {
 impl Waiter {
     fn register(&mut self, waker: &Waker) {
         match self {
-            Self::Waiting(w) if waker.will_wake(w) => {},
+            Self::Waiting(w) if waker.will_wake(w) => {}
             _ => *self = Self::Waiting(waker.clone()),
         }
     }
@@ -61,7 +61,7 @@ impl Waiter {
     fn wake(&mut self) {
         match mem::replace(self, Self::Woken) {
             Self::Waiting(waker) => waker.wake(),
-            Self::Woken => {},
+            Self::Woken => {}
         }
     }
 }
@@ -113,10 +113,7 @@ impl<T: ?Sized> Mutex<T> {
     /// This method returns a future that will resolve once the lock has been
     /// successfully acquired.
     pub fn lock(&self) -> MutexLockFuture<'_, T> {
-        MutexLockFuture {
-            mutex: Some(self),
-            wait_key: WAIT_KEY_NONE,
-        }
+        MutexLockFuture { mutex: Some(self), wait_key: WAIT_KEY_NONE }
     }
 
     /// Returns a mutable reference to the underlying data.
@@ -145,7 +142,7 @@ impl<T: ?Sized> Mutex<T> {
         if wait_key != WAIT_KEY_NONE {
             let mut waiters = self.waiters.lock().unwrap();
             match waiters.remove(wait_key) {
-                Waiter::Waiting(_) => {},
+                Waiter::Waiting(_) => {}
                 Waiter::Woken => {
                     // We were awoken, but then dropped before we could
                     // wake up to acquire the lock. Wake up another
@@ -191,13 +188,10 @@ impl<T: ?Sized> fmt::Debug for MutexLockFuture<'_, T> {
         f.debug_struct("MutexLockFuture")
             .field("was_acquired", &self.mutex.is_none())
             .field("mutex", &self.mutex)
-            .field("wait_key", &(
-                    if self.wait_key == WAIT_KEY_NONE {
-                        None
-                    } else {
-                        Some(self.wait_key)
-                    }
-                ))
+            .field(
+                "wait_key",
+                &(if self.wait_key == WAIT_KEY_NONE { None } else { Some(self.wait_key) }),
+            )
             .finish()
     }
 }
@@ -295,10 +289,7 @@ impl<'a, T: ?Sized> MutexGuard<'a, T> {
 
 impl<T: ?Sized + fmt::Debug> fmt::Debug for MutexGuard<'_, T> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.debug_struct("MutexGuard")
-            .field("value", &&**self)
-            .field("mutex", &self.mutex)
-            .finish()
+        f.debug_struct("MutexGuard").field("value", &&**self).field("mutex", &self.mutex).finish()
     }
 }
 
diff --git a/third_party/rust/futures-util/src/sink/buffer.rs b/third_party/rust/futures-util/src/sink/buffer.rs
index 8c58f4f569a74c7cfd033777c63512ff76bee1c5..c6ea548d652be5e3cd232b9ff25aa84e52d9ef59 100644
--- a/third_party/rust/futures-util/src/sink/buffer.rs
+++ b/third_party/rust/futures-util/src/sink/buffer.rs
@@ -1,10 +1,10 @@
+use alloc::collections::VecDeque;
+use core::pin::Pin;
 use futures_core::ready;
-use futures_core::stream::{Stream, FusedStream};
+use futures_core::stream::{FusedStream, Stream};
 use futures_core::task::{Context, Poll};
 use futures_sink::Sink;
 use pin_project_lite::pin_project;
-use core::pin::Pin;
-use alloc::collections::VecDeque;
 
 pin_project! {
     /// Sink for the [`buffer`](super::SinkExt::buffer) method.
@@ -22,19 +22,12 @@ pin_project! {
 
 impl<Si: Sink<Item>, Item> Buffer<Si, Item> {
     pub(super) fn new(sink: Si, capacity: usize) -> Self {
-        Self {
-            sink,
-            buf: VecDeque::with_capacity(capacity),
-            capacity,
-        }
+        Self { sink, buf: VecDeque::with_capacity(capacity), capacity }
     }
 
     delegate_access_inner!(sink, Si, ());
 
-    fn try_empty_buffer(
-        self: Pin<&mut Self>,
-        cx: &mut Context<'_>,
-    ) -> Poll<Result<(), Si::Error>> {
+    fn try_empty_buffer(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Si::Error>> {
         let mut this = self.project();
         ready!(this.sink.as_mut().poll_ready(cx))?;
         while let Some(item) = this.buf.pop_front() {
@@ -48,7 +41,10 @@ impl<Si: Sink<Item>, Item> Buffer<Si, Item> {
 }
 
 // Forwarding impl of Stream from the underlying sink
-impl<S, Item> Stream for Buffer<S, Item> where S: Sink<Item> + Stream {
+impl<S, Item> Stream for Buffer<S, Item>
+where
+    S: Sink<Item> + Stream,
+{
     type Item = S::Item;
 
     fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<S::Item>> {
@@ -60,7 +56,10 @@ impl<S, Item> Stream for Buffer<S, Item> where S: Sink<Item> + Stream {
     }
 }
 
-impl<S, Item> FusedStream for Buffer<S, Item> where S: Sink<Item> + FusedStream {
+impl<S, Item> FusedStream for Buffer<S, Item>
+where
+    S: Sink<Item> + FusedStream,
+{
     fn is_terminated(&self) -> bool {
         self.sink.is_terminated()
     }
@@ -69,10 +68,7 @@ impl<S, Item> FusedStream for Buffer<S, Item> where S: Sink<Item> + FusedStream
 impl<Si: Sink<Item>, Item> Sink<Item> for Buffer<Si, Item> {
     type Error = Si::Error;
 
-    fn poll_ready(
-        mut self: Pin<&mut Self>,
-        cx: &mut Context<'_>,
-    ) -> Poll<Result<(), Self::Error>> {
+    fn poll_ready(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
         if self.capacity == 0 {
             return self.project().sink.poll_ready(cx);
         }
@@ -86,10 +82,7 @@ impl<Si: Sink<Item>, Item> Sink<Item> for Buffer<Si, Item> {
         }
     }
 
-    fn start_send(
-        self: Pin<&mut Self>,
-        item: Item,
-    ) -> Result<(), Self::Error> {
+    fn start_send(self: Pin<&mut Self>, item: Item) -> Result<(), Self::Error> {
         if self.capacity == 0 {
             self.project().sink.start_send(item)
         } else {
@@ -99,20 +92,14 @@ impl<Si: Sink<Item>, Item> Sink<Item> for Buffer<Si, Item> {
     }
 
     #[allow(clippy::debug_assert_with_mut_call)]
-    fn poll_flush(
-        mut self: Pin<&mut Self>,
-        cx: &mut Context<'_>,
-    ) -> Poll<Result<(), Self::Error>> {
+    fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
         ready!(self.as_mut().try_empty_buffer(cx))?;
         debug_assert!(self.buf.is_empty());
         self.project().sink.poll_flush(cx)
     }
 
     #[allow(clippy::debug_assert_with_mut_call)]
-    fn poll_close(
-        mut self: Pin<&mut Self>,
-        cx: &mut Context<'_>,
-    ) -> Poll<Result<(), Self::Error>> {
+    fn poll_close(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
         ready!(self.as_mut().try_empty_buffer(cx))?;
         debug_assert!(self.buf.is_empty());
         self.project().sink.poll_close(cx)
diff --git a/third_party/rust/futures-util/src/sink/close.rs b/third_party/rust/futures-util/src/sink/close.rs
index 4421d10debd9388f52d2df6c5ed34dcf7a17ab42..43eea74b0f02ba71b9ab38ff6e4942ab0b7a0ee2 100644
--- a/third_party/rust/futures-util/src/sink/close.rs
+++ b/third_party/rust/futures-util/src/sink/close.rs
@@ -16,23 +16,17 @@ impl<Si: Unpin + ?Sized, Item> Unpin for Close<'_, Si, Item> {}
 
 /// A future that completes when the sink has finished closing.
 ///
-/// The sink itself is returned after closeing is complete.
+/// The sink itself is returned after closing is complete.
 impl<'a, Si: Sink<Item> + Unpin + ?Sized, Item> Close<'a, Si, Item> {
     pub(super) fn new(sink: &'a mut Si) -> Self {
-        Self {
-            sink,
-            _phantom: PhantomData,
-        }
+        Self { sink, _phantom: PhantomData }
     }
 }
 
 impl<Si: Sink<Item> + Unpin + ?Sized, Item> Future for Close<'_, Si, Item> {
     type Output = Result<(), Si::Error>;
 
-    fn poll(
-        mut self: Pin<&mut Self>,
-        cx: &mut Context<'_>,
-    ) -> Poll<Self::Output> {
+    fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
         Pin::new(&mut self.sink).poll_close(cx)
     }
 }
diff --git a/third_party/rust/futures-util/src/sink/drain.rs b/third_party/rust/futures-util/src/sink/drain.rs
index 46de83b7c29929815e636b30c4ee2b250f1b66b0..5295115b66dee27a3b0759bbeef25643d61c0003 100644
--- a/third_party/rust/futures-util/src/sink/drain.rs
+++ b/third_party/rust/futures-util/src/sink/drain.rs
@@ -1,3 +1,4 @@
+use super::assert_sink;
 use crate::never::Never;
 use core::marker::PhantomData;
 use core::pin::Pin;
@@ -26,7 +27,7 @@ pub struct Drain<T> {
 /// # Ok::<(), futures::never::Never>(()) }).unwrap();
 /// ```
 pub fn drain<T>() -> Drain<T> {
-    Drain { marker: PhantomData }
+    assert_sink::<T, Never, _>(Drain { marker: PhantomData })
 }
 
 impl<T> Unpin for Drain<T> {}
@@ -34,31 +35,19 @@ impl<T> Unpin for Drain<T> {}
 impl<T> Sink<T> for Drain<T> {
     type Error = Never;
 
-    fn poll_ready(
-        self: Pin<&mut Self>,
-        _cx: &mut Context<'_>,
-    ) -> Poll<Result<(), Self::Error>> {
+    fn poll_ready(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
         Poll::Ready(Ok(()))
     }
 
-    fn start_send(
-        self: Pin<&mut Self>,
-        _item: T,
-    ) -> Result<(), Self::Error> {
+    fn start_send(self: Pin<&mut Self>, _item: T) -> Result<(), Self::Error> {
         Ok(())
     }
 
-    fn poll_flush(
-        self: Pin<&mut Self>,
-        _cx: &mut Context<'_>,
-    ) -> Poll<Result<(), Self::Error>> {
+    fn poll_flush(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
         Poll::Ready(Ok(()))
     }
 
-    fn poll_close(
-        self: Pin<&mut Self>,
-        _cx: &mut Context<'_>,
-    ) -> Poll<Result<(), Self::Error>> {
+    fn poll_close(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
         Poll::Ready(Ok(()))
     }
 }
diff --git a/third_party/rust/futures-util/src/sink/err_into.rs b/third_party/rust/futures-util/src/sink/err_into.rs
index 3eb994041f9767b4148efcf401b1d797750fb5d3..a64d1337baf21f3cd9ba16cd8fa251a76b5f327c 100644
--- a/third_party/rust/futures-util/src/sink/err_into.rs
+++ b/third_party/rust/futures-util/src/sink/err_into.rs
@@ -1,6 +1,6 @@
 use crate::sink::{SinkExt, SinkMapErr};
-use futures_core::stream::{Stream, FusedStream};
-use futures_sink::{Sink};
+use futures_core::stream::{FusedStream, Stream};
+use futures_sink::Sink;
 use pin_project_lite::pin_project;
 
 pin_project! {
@@ -14,21 +14,21 @@ pin_project! {
 }
 
 impl<Si, E, Item> SinkErrInto<Si, Item, E>
-    where Si: Sink<Item>,
-          Si::Error: Into<E>,
+where
+    Si: Sink<Item>,
+    Si::Error: Into<E>,
 {
     pub(super) fn new(sink: Si) -> Self {
-        Self {
-            sink: SinkExt::sink_map_err(sink, Into::into),
-        }
+        Self { sink: SinkExt::sink_map_err(sink, Into::into) }
     }
 
     delegate_access_inner!(sink, Si, (.));
 }
 
 impl<Si, Item, E> Sink<Item> for SinkErrInto<Si, Item, E>
-    where Si: Sink<Item>,
-          Si::Error: Into<E>,
+where
+    Si: Sink<Item>,
+    Si::Error: Into<E>,
 {
     type Error = E;
 
@@ -37,8 +37,9 @@ impl<Si, Item, E> Sink<Item> for SinkErrInto<Si, Item, E>
 
 // Forwarding impl of Stream from the underlying sink
 impl<S, Item, E> Stream for SinkErrInto<S, Item, E>
-    where S: Sink<Item> + Stream,
-          S::Error: Into<E>
+where
+    S: Sink<Item> + Stream,
+    S::Error: Into<E>,
 {
     type Item = S::Item;
 
@@ -46,8 +47,9 @@ impl<S, Item, E> Stream for SinkErrInto<S, Item, E>
 }
 
 impl<S, Item, E> FusedStream for SinkErrInto<S, Item, E>
-    where S: Sink<Item> + FusedStream,
-          S::Error: Into<E>
+where
+    S: Sink<Item> + FusedStream,
+    S::Error: Into<E>,
 {
     fn is_terminated(&self) -> bool {
         self.sink.is_terminated()
diff --git a/third_party/rust/futures-util/src/sink/fanout.rs b/third_party/rust/futures-util/src/sink/fanout.rs
index f351e867d44300e8bfba817ed70d506848599668..fe2038f27f5a2a3935d7ffe161e41d76450b3f63 100644
--- a/third_party/rust/futures-util/src/sink/fanout.rs
+++ b/third_party/rust/futures-util/src/sink/fanout.rs
@@ -50,36 +50,32 @@ impl<Si1, Si2> Fanout<Si1, Si2> {
 
 impl<Si1: Debug, Si2: Debug> Debug for Fanout<Si1, Si2> {
     fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
-        f.debug_struct("Fanout")
-            .field("sink1", &self.sink1)
-            .field("sink2", &self.sink2)
-            .finish()
+        f.debug_struct("Fanout").field("sink1", &self.sink1).field("sink2", &self.sink2).finish()
     }
 }
 
 impl<Si1, Si2, Item> Sink<Item> for Fanout<Si1, Si2>
-    where Si1: Sink<Item>,
-          Item: Clone,
-          Si2: Sink<Item, Error=Si1::Error>
+where
+    Si1: Sink<Item>,
+    Item: Clone,
+    Si2: Sink<Item, Error = Si1::Error>,
 {
     type Error = Si1::Error;
 
-    fn poll_ready(
-        self: Pin<&mut Self>,
-        cx: &mut Context<'_>,
-    ) -> Poll<Result<(), Self::Error>> {
+    fn poll_ready(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
         let this = self.project();
 
         let sink1_ready = this.sink1.poll_ready(cx)?.is_ready();
         let sink2_ready = this.sink2.poll_ready(cx)?.is_ready();
         let ready = sink1_ready && sink2_ready;
-        if ready { Poll::Ready(Ok(())) } else { Poll::Pending }
+        if ready {
+            Poll::Ready(Ok(()))
+        } else {
+            Poll::Pending
+        }
     }
 
-    fn start_send(
-        self: Pin<&mut Self>,
-        item: Item,
-    ) -> Result<(), Self::Error> {
+    fn start_send(self: Pin<&mut Self>, item: Item) -> Result<(), Self::Error> {
         let this = self.project();
 
         this.sink1.start_send(item.clone())?;
@@ -87,27 +83,29 @@ impl<Si1, Si2, Item> Sink<Item> for Fanout<Si1, Si2>
         Ok(())
     }
 
-    fn poll_flush(
-        self: Pin<&mut Self>,
-        cx: &mut Context<'_>,
-    ) -> Poll<Result<(), Self::Error>> {
+    fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
         let this = self.project();
 
         let sink1_ready = this.sink1.poll_flush(cx)?.is_ready();
         let sink2_ready = this.sink2.poll_flush(cx)?.is_ready();
         let ready = sink1_ready && sink2_ready;
-        if ready { Poll::Ready(Ok(())) } else { Poll::Pending }
+        if ready {
+            Poll::Ready(Ok(()))
+        } else {
+            Poll::Pending
+        }
     }
 
-    fn poll_close(
-        self: Pin<&mut Self>,
-        cx: &mut Context<'_>,
-    ) -> Poll<Result<(), Self::Error>> {
+    fn poll_close(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
         let this = self.project();
 
         let sink1_ready = this.sink1.poll_close(cx)?.is_ready();
         let sink2_ready = this.sink2.poll_close(cx)?.is_ready();
         let ready = sink1_ready && sink2_ready;
-        if ready { Poll::Ready(Ok(())) } else { Poll::Pending }
+        if ready {
+            Poll::Ready(Ok(()))
+        } else {
+            Poll::Pending
+        }
     }
 }
diff --git a/third_party/rust/futures-util/src/sink/feed.rs b/third_party/rust/futures-util/src/sink/feed.rs
index 06df9a91a8f6f2aa3ca2419c25b98f0fc60fb2e7..6701f7a1b42604987f72bac2e084ded610ae69d4 100644
--- a/third_party/rust/futures-util/src/sink/feed.rs
+++ b/third_party/rust/futures-util/src/sink/feed.rs
@@ -17,10 +17,7 @@ impl<Si: Unpin + ?Sized, Item> Unpin for Feed<'_, Si, Item> {}
 
 impl<'a, Si: Sink<Item> + Unpin + ?Sized, Item> Feed<'a, Si, Item> {
     pub(super) fn new(sink: &'a mut Si, item: Item) -> Self {
-        Feed {
-            sink,
-            item: Some(item),
-        }
+        Feed { sink, item: Some(item) }
     }
 
     pub(super) fn sink_pin_mut(&mut self) -> Pin<&mut Si> {
@@ -35,10 +32,7 @@ impl<'a, Si: Sink<Item> + Unpin + ?Sized, Item> Feed<'a, Si, Item> {
 impl<Si: Sink<Item> + Unpin + ?Sized, Item> Future for Feed<'_, Si, Item> {
     type Output = Result<(), Si::Error>;
 
-    fn poll(
-        self: Pin<&mut Self>,
-        cx: &mut Context<'_>,
-    ) -> Poll<Self::Output> {
+    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
         let this = self.get_mut();
         let mut sink = Pin::new(&mut this.sink);
         ready!(sink.as_mut().poll_ready(cx))?;
diff --git a/third_party/rust/futures-util/src/sink/flush.rs b/third_party/rust/futures-util/src/sink/flush.rs
index c06a22185ecf5a46b88164b74a93088c4dd18a7c..35a8372de79f0588a75cb04e4e696407a289dded 100644
--- a/third_party/rust/futures-util/src/sink/flush.rs
+++ b/third_party/rust/futures-util/src/sink/flush.rs
@@ -23,20 +23,14 @@ impl<Si: Unpin + ?Sized, Item> Unpin for Flush<'_, Si, Item> {}
 /// all current requests are processed.
 impl<'a, Si: Sink<Item> + Unpin + ?Sized, Item> Flush<'a, Si, Item> {
     pub(super) fn new(sink: &'a mut Si) -> Self {
-        Self {
-            sink,
-            _phantom: PhantomData,
-        }
+        Self { sink, _phantom: PhantomData }
     }
 }
 
 impl<Si: Sink<Item> + Unpin + ?Sized, Item> Future for Flush<'_, Si, Item> {
     type Output = Result<(), Si::Error>;
 
-    fn poll(
-        mut self: Pin<&mut Self>,
-        cx: &mut Context<'_>,
-    ) -> Poll<Self::Output> {
+    fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
         Pin::new(&mut self.sink).poll_flush(cx)
     }
 }
diff --git a/third_party/rust/futures-util/src/sink/map_err.rs b/third_party/rust/futures-util/src/sink/map_err.rs
index 282934465e4493987072f341e466fd6628e972b5..9d2ab7b24b81853b91025ee1f730543a244af18c 100644
--- a/third_party/rust/futures-util/src/sink/map_err.rs
+++ b/third_party/rust/futures-util/src/sink/map_err.rs
@@ -1,7 +1,7 @@
 use core::pin::Pin;
-use futures_core::stream::{Stream, FusedStream};
+use futures_core::stream::{FusedStream, Stream};
 use futures_core::task::{Context, Poll};
-use futures_sink::{Sink};
+use futures_sink::Sink;
 use pin_project_lite::pin_project;
 
 pin_project! {
@@ -28,36 +28,25 @@ impl<Si, F> SinkMapErr<Si, F> {
 }
 
 impl<Si, F, E, Item> Sink<Item> for SinkMapErr<Si, F>
-    where Si: Sink<Item>,
-          F: FnOnce(Si::Error) -> E,
+where
+    Si: Sink<Item>,
+    F: FnOnce(Si::Error) -> E,
 {
     type Error = E;
 
-    fn poll_ready(
-        mut self: Pin<&mut Self>,
-        cx: &mut Context<'_>,
-    ) -> Poll<Result<(), Self::Error>> {
+    fn poll_ready(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
         self.as_mut().project().sink.poll_ready(cx).map_err(|e| self.as_mut().take_f()(e))
     }
 
-    fn start_send(
-        mut self: Pin<&mut Self>,
-        item: Item,
-    ) -> Result<(), Self::Error> {
+    fn start_send(mut self: Pin<&mut Self>, item: Item) -> Result<(), Self::Error> {
         self.as_mut().project().sink.start_send(item).map_err(|e| self.as_mut().take_f()(e))
     }
 
-    fn poll_flush(
-        mut self: Pin<&mut Self>,
-        cx: &mut Context<'_>,
-    ) -> Poll<Result<(), Self::Error>> {
+    fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
         self.as_mut().project().sink.poll_flush(cx).map_err(|e| self.as_mut().take_f()(e))
     }
 
-    fn poll_close(
-        mut self: Pin<&mut Self>,
-        cx: &mut Context<'_>,
-    ) -> Poll<Result<(), Self::Error>> {
+    fn poll_close(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
         self.as_mut().project().sink.poll_close(cx).map_err(|e| self.as_mut().take_f()(e))
     }
 }
diff --git a/third_party/rust/futures-util/src/sink/mod.rs b/third_party/rust/futures-util/src/sink/mod.rs
index 1a062d005f5db25550782ed7694172edc9929662..147e9adc9385f9f087d45a0ddc040ee4b4683499 100644
--- a/third_party/rust/futures-util/src/sink/mod.rs
+++ b/third_party/rust/futures-util/src/sink/mod.rs
@@ -6,7 +6,7 @@
 //! - The [`SinkExt`] trait, which provides adapters for chaining and composing
 //!   sinks.
 
-use crate::future::Either;
+use crate::future::{assert_future, Either};
 use core::pin::Pin;
 use futures_core::future::Future;
 use futures_core::stream::{Stream, TryStream};
@@ -81,7 +81,7 @@ pub trait SinkExt<Item>: Sink<Item> {
         E: From<Self::Error>,
         Self: Sized,
     {
-        With::new(self, f)
+        assert_sink::<U, E, _>(With::new(self, f))
     }
 
     /// Composes a function *in front of* the sink.
@@ -122,7 +122,7 @@ pub trait SinkExt<Item>: Sink<Item> {
         St: Stream<Item = Result<Item, Self::Error>>,
         Self: Sized,
     {
-        WithFlatMap::new(self, f)
+        assert_sink::<U, Self::Error, _>(WithFlatMap::new(self, f))
     }
 
     /*
@@ -145,7 +145,7 @@ pub trait SinkExt<Item>: Sink<Item> {
         F: FnOnce(Self::Error) -> E,
         Self: Sized,
     {
-        SinkMapErr::new(self, f)
+        assert_sink::<Item, E, _>(SinkMapErr::new(self, f))
     }
 
     /// Map this sink's error to a different error type using the `Into` trait.
@@ -156,7 +156,7 @@ pub trait SinkExt<Item>: Sink<Item> {
         Self: Sized,
         Self::Error: Into<E>,
     {
-        SinkErrInto::new(self)
+        assert_sink::<Item, E, _>(SinkErrInto::new(self))
     }
 
     /// Adds a fixed-size buffer to the current sink.
@@ -176,7 +176,7 @@ pub trait SinkExt<Item>: Sink<Item> {
     where
         Self: Sized,
     {
-        Buffer::new(self, capacity)
+        assert_sink::<Item, Self::Error, _>(Buffer::new(self, capacity))
     }
 
     /// Close the sink.
@@ -184,7 +184,7 @@ pub trait SinkExt<Item>: Sink<Item> {
     where
         Self: Unpin,
     {
-        Close::new(self)
+        assert_future::<Result<(), Self::Error>, _>(Close::new(self))
     }
 
     /// Fanout items to multiple sinks.
@@ -197,7 +197,7 @@ pub trait SinkExt<Item>: Sink<Item> {
         Item: Clone,
         Si: Sink<Item, Error = Self::Error>,
     {
-        Fanout::new(self, other)
+        assert_sink::<Item, Self::Error, _>(Fanout::new(self, other))
     }
 
     /// Flush the sink, processing all pending items.
@@ -208,7 +208,7 @@ pub trait SinkExt<Item>: Sink<Item> {
     where
         Self: Unpin,
     {
-        Flush::new(self)
+        assert_future::<Result<(), Self::Error>, _>(Flush::new(self))
     }
 
     /// A future that completes after the given item has been fully processed
@@ -221,7 +221,7 @@ pub trait SinkExt<Item>: Sink<Item> {
     where
         Self: Unpin,
     {
-        Send::new(self, item)
+        assert_future::<Result<(), Self::Error>, _>(Send::new(self, item))
     }
 
     /// A future that completes after the given item has been received
@@ -231,9 +231,10 @@ pub trait SinkExt<Item>: Sink<Item> {
     /// It is the caller's responsibility to ensure all pending items
     /// are processed, which can be done via `flush` or `close`.
     fn feed(&mut self, item: Item) -> Feed<'_, Self, Item>
-        where Self: Unpin,
+    where
+        Self: Unpin,
     {
-        Feed::new(self, item)
+        assert_future::<Result<(), Self::Error>, _>(Feed::new(self, item))
     }
 
     /// A future that completes after the given stream has been fully processed
@@ -242,7 +243,8 @@ pub trait SinkExt<Item>: Sink<Item> {
     /// This future will drive the stream to keep producing items until it is
     /// exhausted, sending each item to the sink. It will complete once both the
     /// stream is exhausted, the sink has received all items, and the sink has
-    /// been flushed. Note that the sink is **not** closed.
+    /// been flushed. Note that the sink is **not** closed. If the stream produces
+    /// an error, that error will be returned by this future without flushing the sink.
     ///
     /// Doing `sink.send_all(stream)` is roughly equivalent to
     /// `stream.forward(sink)`. The returned future will exhaust all items from
@@ -250,8 +252,11 @@ pub trait SinkExt<Item>: Sink<Item> {
     fn send_all<'a, St>(&'a mut self, stream: &'a mut St) -> SendAll<'a, Self, St>
     where
         St: TryStream<Ok = Item, Error = Self::Error> + Stream + Unpin + ?Sized,
+        // St: Stream<Item = Result<Item, Self::Error>> + Unpin + ?Sized,
         Self: Unpin,
     {
+        // TODO: type mismatch resolving `<St as Stream>::Item == std::result::Result<Item, <Self as futures_sink::Sink<Item>>::Error>`
+        // assert_future::<Result<(), Self::Error>, _>(SendAll::new(self, stream))
         SendAll::new(self, stream)
     }
 
@@ -265,7 +270,7 @@ pub trait SinkExt<Item>: Sink<Item> {
         Si2: Sink<Item, Error = Self::Error>,
         Self: Sized,
     {
-        Either::Left(self)
+        assert_sink::<Item, Self::Error, _>(Either::Left(self))
     }
 
     /// Wrap this stream in an `Either` stream, making it the right-hand variant
@@ -278,7 +283,7 @@ pub trait SinkExt<Item>: Sink<Item> {
         Si1: Sink<Item, Error = Self::Error>,
         Self: Sized,
     {
-        Either::Right(self)
+        assert_sink::<Item, Self::Error, _>(Either::Right(self))
     }
 
     /// Wraps a [`Sink`] into a sink compatible with libraries using
@@ -328,3 +333,12 @@ pub trait SinkExt<Item>: Sink<Item> {
         Pin::new(self).poll_close(cx)
     }
 }
+
+// Just a helper function to ensure the sinks we're returning all have the
+// right implementations.
+pub(crate) fn assert_sink<T, E, S>(sink: S) -> S
+where
+    S: Sink<T, Error = E>,
+{
+    sink
+}
diff --git a/third_party/rust/futures-util/src/sink/send.rs b/third_party/rust/futures-util/src/sink/send.rs
index 384c22c56c6a4ee546d599b76e8b05d7c1ec04a6..6d21f33fe46d3ad0efa45ed6a1f2c65e6cbe71de 100644
--- a/third_party/rust/futures-util/src/sink/send.rs
+++ b/third_party/rust/futures-util/src/sink/send.rs
@@ -17,19 +17,14 @@ impl<Si: Unpin + ?Sized, Item> Unpin for Send<'_, Si, Item> {}
 
 impl<'a, Si: Sink<Item> + Unpin + ?Sized, Item> Send<'a, Si, Item> {
     pub(super) fn new(sink: &'a mut Si, item: Item) -> Self {
-        Self {
-            feed: Feed::new(sink, item),
-        }
+        Self { feed: Feed::new(sink, item) }
     }
 }
 
 impl<Si: Sink<Item> + Unpin + ?Sized, Item> Future for Send<'_, Si, Item> {
     type Output = Result<(), Si::Error>;
 
-    fn poll(
-        mut self: Pin<&mut Self>,
-        cx: &mut Context<'_>,
-    ) -> Poll<Self::Output> {
+    fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
         let this = &mut *self;
 
         if this.feed.is_item_pending() {
diff --git a/third_party/rust/futures-util/src/sink/send_all.rs b/third_party/rust/futures-util/src/sink/send_all.rs
index 6a33459be0653fb7f30e21332f86c2b62897d751..1302dd2148b0f13b6cc36305d08458fa4ad4a18b 100644
--- a/third_party/rust/futures-util/src/sink/send_all.rs
+++ b/third_party/rust/futures-util/src/sink/send_all.rs
@@ -1,9 +1,9 @@
-use crate::stream::{StreamExt, TryStreamExt, Fuse};
+use crate::stream::{Fuse, StreamExt, TryStreamExt};
 use core::fmt;
 use core::pin::Pin;
 use futures_core::future::Future;
 use futures_core::ready;
-use futures_core::stream::{TryStream, Stream};
+use futures_core::stream::{Stream, TryStream};
 use futures_core::task::{Context, Poll};
 use futures_sink::Sink;
 
@@ -40,22 +40,16 @@ impl<Si, St> Unpin for SendAll<'_, Si, St>
 where
     Si: Unpin + ?Sized,
     St: TryStream + Unpin + ?Sized,
-{}
+{
+}
 
 impl<'a, Si, St, Ok, Error> SendAll<'a, Si, St>
 where
     Si: Sink<Ok, Error = Error> + Unpin + ?Sized,
     St: TryStream<Ok = Ok, Error = Error> + Stream + Unpin + ?Sized,
 {
-    pub(super) fn new(
-        sink: &'a mut Si,
-        stream: &'a mut St,
-    ) -> Self {
-        Self {
-            sink,
-            stream: stream.fuse(),
-            buffered: None,
-        }
+    pub(super) fn new(sink: &'a mut Si, stream: &'a mut St) -> Self {
+        Self { sink, stream: stream.fuse(), buffered: None }
     }
 
     fn try_start_send(
@@ -65,9 +59,7 @@ where
     ) -> Poll<Result<(), Si::Error>> {
         debug_assert!(self.buffered.is_none());
         match Pin::new(&mut self.sink).poll_ready(cx)? {
-            Poll::Ready(()) => {
-                Poll::Ready(Pin::new(&mut self.sink).start_send(item))
-            }
+            Poll::Ready(()) => Poll::Ready(Pin::new(&mut self.sink).start_send(item)),
             Poll::Pending => {
                 self.buffered = Some(item);
                 Poll::Pending
@@ -83,10 +75,7 @@ where
 {
     type Output = Result<(), Error>;
 
-    fn poll(
-        mut self: Pin<&mut Self>,
-        cx: &mut Context<'_>,
-    ) -> Poll<Self::Output> {
+    fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
         let this = &mut *self;
         // If we've got an item buffered already, we need to write it to the
         // sink before we can do anything else
@@ -96,16 +85,14 @@ where
 
         loop {
             match this.stream.try_poll_next_unpin(cx)? {
-                Poll::Ready(Some(item)) => {
-                    ready!(this.try_start_send(cx, item))?
-                }
+                Poll::Ready(Some(item)) => ready!(this.try_start_send(cx, item))?,
                 Poll::Ready(None) => {
                     ready!(Pin::new(&mut this.sink).poll_flush(cx))?;
-                    return Poll::Ready(Ok(()))
+                    return Poll::Ready(Ok(()));
                 }
                 Poll::Pending => {
                     ready!(Pin::new(&mut this.sink).poll_flush(cx))?;
-                    return Poll::Pending
+                    return Poll::Pending;
                 }
             }
         }
diff --git a/third_party/rust/futures-util/src/sink/unfold.rs b/third_party/rust/futures-util/src/sink/unfold.rs
index 1aab200dfb89dde8cfc1fcacf6594bcecab219b0..330a068c31ea680d2f51f9e82ddfa55ce93b3f24 100644
--- a/third_party/rust/futures-util/src/sink/unfold.rs
+++ b/third_party/rust/futures-util/src/sink/unfold.rs
@@ -1,3 +1,4 @@
+use super::assert_sink;
 use crate::unfold_state::UnfoldState;
 use core::{future::Future, pin::Pin};
 use futures_core::ready;
@@ -40,10 +41,7 @@ where
     F: FnMut(T, Item) -> R,
     R: Future<Output = Result<T, E>>,
 {
-    Unfold {
-        function,
-        state: UnfoldState::Value { value: init },
-    }
+    assert_sink::<Item, E, _>(Unfold { function, state: UnfoldState::Value { value: init } })
 }
 
 impl<T, F, R, Item, E> Sink<Item> for Unfold<T, F, R>
diff --git a/third_party/rust/futures-util/src/sink/with.rs b/third_party/rust/futures-util/src/sink/with.rs
index 73b87b72fccfc52064f5004e512fb2bc46907f2d..86d3dcc7b8c1e6d20ef6d1ba1ef6bccf3ce20e4d 100644
--- a/third_party/rust/futures-util/src/sink/with.rs
+++ b/third_party/rust/futures-util/src/sink/with.rs
@@ -27,29 +27,22 @@ where
     Fut: fmt::Debug,
 {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.debug_struct("With")
-            .field("sink", &self.sink)
-            .field("state", &self.state)
-            .finish()
+        f.debug_struct("With").field("sink", &self.sink).field("state", &self.state).finish()
     }
 }
 
 impl<Si, Item, U, Fut, F> With<Si, Item, U, Fut, F>
-where Si: Sink<Item>,
-      F: FnMut(U) -> Fut,
-      Fut: Future,
+where
+    Si: Sink<Item>,
+    F: FnMut(U) -> Fut,
+    Fut: Future,
 {
     pub(super) fn new<E>(sink: Si, f: F) -> Self
-        where
-            Fut: Future<Output = Result<Item, E>>,
-            E: From<Si::Error>,
+    where
+        Fut: Future<Output = Result<Item, E>>,
+        E: From<Si::Error>,
     {
-        Self {
-            state: None,
-            sink,
-            f,
-            _phantom: PhantomData,
-        }
+        Self { state: None, sink, f, _phantom: PhantomData }
     }
 }
 
@@ -71,9 +64,10 @@ where
 
 // Forwarding impl of Stream from the underlying sink
 impl<S, Item, U, Fut, F> Stream for With<S, Item, U, Fut, F>
-    where S: Stream + Sink<Item>,
-          F: FnMut(U) -> Fut,
-          Fut: Future
+where
+    S: Stream + Sink<Item>,
+    F: FnMut(U) -> Fut,
+    Fut: Future,
 {
     type Item = S::Item;
 
@@ -81,18 +75,16 @@ impl<S, Item, U, Fut, F> Stream for With<S, Item, U, Fut, F>
 }
 
 impl<Si, Item, U, Fut, F, E> With<Si, Item, U, Fut, F>
-    where Si: Sink<Item>,
-          F: FnMut(U) -> Fut,
-          Fut: Future<Output = Result<Item, E>>,
-          E: From<Si::Error>,
+where
+    Si: Sink<Item>,
+    F: FnMut(U) -> Fut,
+    Fut: Future<Output = Result<Item, E>>,
+    E: From<Si::Error>,
 {
     delegate_access_inner!(sink, Si, ());
 
     /// Completes the processing of previous item if any.
-    fn poll(
-        self: Pin<&mut Self>,
-        cx: &mut Context<'_>,
-    ) -> Poll<Result<(), E>> {
+    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), E>> {
         let mut this = self.project();
 
         let item = match this.state.as_mut().as_pin_mut() {
@@ -106,26 +98,21 @@ impl<Si, Item, U, Fut, F, E> With<Si, Item, U, Fut, F>
 }
 
 impl<Si, Item, U, Fut, F, E> Sink<U> for With<Si, Item, U, Fut, F>
-    where Si: Sink<Item>,
-          F: FnMut(U) -> Fut,
-          Fut: Future<Output = Result<Item, E>>,
-          E: From<Si::Error>,
+where
+    Si: Sink<Item>,
+    F: FnMut(U) -> Fut,
+    Fut: Future<Output = Result<Item, E>>,
+    E: From<Si::Error>,
 {
     type Error = E;
 
-    fn poll_ready(
-        mut self: Pin<&mut Self>,
-        cx: &mut Context<'_>,
-    ) -> Poll<Result<(), Self::Error>> {
+    fn poll_ready(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
         ready!(self.as_mut().poll(cx))?;
         ready!(self.project().sink.poll_ready(cx)?);
         Poll::Ready(Ok(()))
     }
 
-    fn start_send(
-        self: Pin<&mut Self>,
-        item: U,
-    ) -> Result<(), Self::Error> {
+    fn start_send(self: Pin<&mut Self>, item: U) -> Result<(), Self::Error> {
         let mut this = self.project();
 
         assert!(this.state.is_none());
@@ -133,19 +120,13 @@ impl<Si, Item, U, Fut, F, E> Sink<U> for With<Si, Item, U, Fut, F>
         Ok(())
     }
 
-    fn poll_flush(
-        mut self: Pin<&mut Self>,
-        cx: &mut Context<'_>,
-    ) -> Poll<Result<(), Self::Error>> {
+    fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
         ready!(self.as_mut().poll(cx))?;
         ready!(self.project().sink.poll_flush(cx)?);
         Poll::Ready(Ok(()))
     }
 
-    fn poll_close(
-        mut self: Pin<&mut Self>,
-        cx: &mut Context<'_>,
-    ) -> Poll<Result<(), Self::Error>> {
+    fn poll_close(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
         ready!(self.as_mut().poll(cx))?;
         ready!(self.project().sink.poll_close(cx)?);
         Poll::Ready(Ok(()))
diff --git a/third_party/rust/futures-util/src/sink/with_flat_map.rs b/third_party/rust/futures-util/src/sink/with_flat_map.rs
index 4b8d3a275c5a2b3244e38633fdd53ed5d0d43809..2ae877a24b38802bbc1356ffe955f9edfe511014 100644
--- a/third_party/rust/futures-util/src/sink/with_flat_map.rs
+++ b/third_party/rust/futures-util/src/sink/with_flat_map.rs
@@ -2,7 +2,7 @@ use core::fmt;
 use core::marker::PhantomData;
 use core::pin::Pin;
 use futures_core::ready;
-use futures_core::stream::{Stream, FusedStream};
+use futures_core::stream::{FusedStream, Stream};
 use futures_core::task::{Context, Poll};
 use futures_sink::Sink;
 use pin_project_lite::pin_project;
@@ -43,21 +43,12 @@ where
     St: Stream<Item = Result<Item, Si::Error>>,
 {
     pub(super) fn new(sink: Si, f: F) -> Self {
-        Self {
-            sink,
-            f,
-            stream: None,
-            buffer: None,
-            _marker: PhantomData,
-        }
+        Self { sink, f, stream: None, buffer: None, _marker: PhantomData }
     }
 
     delegate_access_inner!(sink, Si, ());
 
-    fn try_empty_stream(
-        self: Pin<&mut Self>,
-        cx: &mut Context<'_>,
-    ) -> Poll<Result<(), Si::Error>> {
+    fn try_empty_stream(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Si::Error>> {
         let mut this = self.project();
 
         if this.buffer.is_some() {
@@ -112,17 +103,11 @@ where
 {
     type Error = Si::Error;
 
-    fn poll_ready(
-        self: Pin<&mut Self>,
-        cx: &mut Context<'_>,
-    ) -> Poll<Result<(), Self::Error>> {
+    fn poll_ready(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
         self.try_empty_stream(cx)
     }
 
-    fn start_send(
-        self: Pin<&mut Self>,
-        item: U,
-    ) -> Result<(), Self::Error> {
+    fn start_send(self: Pin<&mut Self>, item: U) -> Result<(), Self::Error> {
         let mut this = self.project();
 
         assert!(this.stream.is_none());
@@ -130,18 +115,12 @@ where
         Ok(())
     }
 
-    fn poll_flush(
-        mut self: Pin<&mut Self>,
-        cx: &mut Context<'_>,
-    ) -> Poll<Result<(), Self::Error>> {
+    fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
         ready!(self.as_mut().try_empty_stream(cx)?);
         self.project().sink.poll_flush(cx)
     }
 
-    fn poll_close(
-        mut self: Pin<&mut Self>,
-        cx: &mut Context<'_>,
-    ) -> Poll<Result<(), Self::Error>> {
+    fn poll_close(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
         ready!(self.as_mut().try_empty_stream(cx)?);
         self.project().sink.poll_close(cx)
     }
diff --git a/third_party/rust/futures-util/src/stream/abortable.rs b/third_party/rust/futures-util/src/stream/abortable.rs
new file mode 100644
index 0000000000000000000000000000000000000000..1fea89582228ec4243edebd24e57698452d18abc
--- /dev/null
+++ b/third_party/rust/futures-util/src/stream/abortable.rs
@@ -0,0 +1,19 @@
+use super::assert_stream;
+use crate::stream::{AbortHandle, Abortable};
+use crate::Stream;
+
+/// Creates a new `Abortable` stream and an `AbortHandle` which can be used to stop it.
+///
+/// This function is a convenient (but less flexible) alternative to calling
+/// `AbortHandle::new` and `Abortable::new` manually.
+///
+/// This function is only available when the `std` or `alloc` feature of this
+/// library is activated, and it is activated by default.
+pub fn abortable<St>(stream: St) -> (Abortable<St>, AbortHandle)
+where
+    St: Stream,
+{
+    let (handle, reg) = AbortHandle::new_pair();
+    let abortable = assert_stream::<St::Item, _>(Abortable::new(stream, reg));
+    (abortable, handle)
+}
diff --git a/third_party/rust/futures-util/src/stream/empty.rs b/third_party/rust/futures-util/src/stream/empty.rs
index d228b315818bd0ef81379f43c9e832ac524d4895..e4fd87326b889f6be0136eaa5b4ced03f7645729 100644
--- a/third_party/rust/futures-util/src/stream/empty.rs
+++ b/third_party/rust/futures-util/src/stream/empty.rs
@@ -1,3 +1,4 @@
+use super::assert_stream;
 use core::marker::PhantomData;
 use core::pin::Pin;
 use futures_core::stream::{FusedStream, Stream};
@@ -7,16 +8,14 @@ use futures_core::task::{Context, Poll};
 #[derive(Debug)]
 #[must_use = "streams do nothing unless polled"]
 pub struct Empty<T> {
-    _phantom: PhantomData<T>
+    _phantom: PhantomData<T>,
 }
 
 /// Creates a stream which contains no elements.
 ///
 /// The returned stream will always return `Ready(None)` when polled.
 pub fn empty<T>() -> Empty<T> {
-    Empty {
-        _phantom: PhantomData
-    }
+    assert_stream::<T, _>(Empty { _phantom: PhantomData })
 }
 
 impl<T> Unpin for Empty<T> {}
diff --git a/third_party/rust/futures-util/src/stream/futures_ordered.rs b/third_party/rust/futures-util/src/stream/futures_ordered.rs
index eda3b27038a8df8ef0bab00e9accc931b553d9db..f596b3b0e34daf076ad560aca1935ce1d3fee533 100644
--- a/third_party/rust/futures-util/src/stream/futures_ordered.rs
+++ b/third_party/rust/futures-util/src/stream/futures_ordered.rs
@@ -52,10 +52,7 @@ where
 
     fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
         let index = self.index;
-        self.project().data.poll(cx).map(|output| OrderWrapper {
-            data: output,
-            index,
-        })
+        self.project().data.poll(cx).map(|output| OrderWrapper { data: output, index })
     }
 }
 
@@ -139,10 +136,7 @@ impl<Fut: Future> FuturesOrdered<Fut> {
     /// must ensure that `FuturesOrdered::poll` is called in order to receive
     /// task notifications.
     pub fn push(&mut self, future: Fut) {
-        let wrapped = OrderWrapper {
-            data: future,
-            index: self.next_incoming_index,
-        };
+        let wrapped = OrderWrapper { data: future, index: self.next_incoming_index };
         self.next_incoming_index += 1;
         self.in_progress_queue.push(wrapped);
     }
diff --git a/third_party/rust/futures-util/src/stream/futures_unordered/iter.rs b/third_party/rust/futures-util/src/stream/futures_unordered/iter.rs
index ef7b15aed8d898030ae1c97e669fa62a4ee00236..04db5ee75350dcda37f597fcfe169d9e016208e1 100644
--- a/third_party/rust/futures-util/src/stream/futures_unordered/iter.rs
+++ b/third_party/rust/futures-util/src/stream/futures_unordered/iter.rs
@@ -1,41 +1,83 @@
-use super::FuturesUnordered;
 use super::task::Task;
+use super::FuturesUnordered;
 use core::marker::PhantomData;
 use core::pin::Pin;
 use core::sync::atomic::Ordering::Relaxed;
 
-#[derive(Debug)]
 /// Mutable iterator over all futures in the unordered set.
+#[derive(Debug)]
 pub struct IterPinMut<'a, Fut> {
     pub(super) task: *const Task<Fut>,
     pub(super) len: usize,
-    pub(super) _marker: PhantomData<&'a mut FuturesUnordered<Fut>>
+    pub(super) _marker: PhantomData<&'a mut FuturesUnordered<Fut>>,
 }
 
-#[derive(Debug)]
 /// Mutable iterator over all futures in the unordered set.
-pub struct IterMut<'a, Fut: Unpin> (pub(super) IterPinMut<'a, Fut>);
-
 #[derive(Debug)]
+pub struct IterMut<'a, Fut: Unpin>(pub(super) IterPinMut<'a, Fut>);
+
 /// Immutable iterator over all futures in the unordered set.
+#[derive(Debug)]
 pub struct IterPinRef<'a, Fut> {
     pub(super) task: *const Task<Fut>,
     pub(super) len: usize,
     pub(super) pending_next_all: *mut Task<Fut>,
-    pub(super) _marker: PhantomData<&'a FuturesUnordered<Fut>>
+    pub(super) _marker: PhantomData<&'a FuturesUnordered<Fut>>,
 }
 
-#[derive(Debug)]
 /// Immutable iterator over all the futures in the unordered set.
-pub struct Iter<'a, Fut: Unpin> (pub(super) IterPinRef<'a, Fut>);
+#[derive(Debug)]
+pub struct Iter<'a, Fut: Unpin>(pub(super) IterPinRef<'a, Fut>);
+
+/// Owned iterator over all futures in the unordered set.
+#[derive(Debug)]
+pub struct IntoIter<Fut: Unpin> {
+    pub(super) len: usize,
+    pub(super) inner: FuturesUnordered<Fut>,
+}
+
+impl<Fut: Unpin> Iterator for IntoIter<Fut> {
+    type Item = Fut;
+
+    fn next(&mut self) -> Option<Self::Item> {
+        // `head_all` can be accessed directly and we don't need to spin on
+        // `Task::next_all` since we have exclusive access to the set.
+        let task = self.inner.head_all.get_mut();
+
+        if (*task).is_null() {
+            return None;
+        }
+
+        unsafe {
+            // Moving out of the future is safe because it is `Unpin`
+            let future = (*(**task).future.get()).take().unwrap();
+
+            // Mutable access to a previously shared `FuturesUnordered` implies
+            // that the other threads already released the object before the
+            // current thread acquired it, so relaxed ordering can be used and
+            // valid `next_all` checks can be skipped.
+            let next = (**task).next_all.load(Relaxed);
+            *task = next;
+            self.len -= 1;
+            Some(future)
+        }
+    }
+
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        (self.len, Some(self.len))
+    }
+}
+
+impl<Fut: Unpin> ExactSizeIterator for IntoIter<Fut> {}
 
 impl<'a, Fut> Iterator for IterPinMut<'a, Fut> {
     type Item = Pin<&'a mut Fut>;
 
-    fn next(&mut self) -> Option<Pin<&'a mut Fut>> {
+    fn next(&mut self) -> Option<Self::Item> {
         if self.task.is_null() {
             return None;
         }
+
         unsafe {
             let future = (*(*self.task).future.get()).as_mut().unwrap();
 
@@ -60,7 +102,7 @@ impl<Fut> ExactSizeIterator for IterPinMut<'_, Fut> {}
 impl<'a, Fut: Unpin> Iterator for IterMut<'a, Fut> {
     type Item = &'a mut Fut;
 
-    fn next(&mut self) -> Option<&'a mut Fut> {
+    fn next(&mut self) -> Option<Self::Item> {
         self.0.next().map(Pin::get_mut)
     }
 
@@ -74,10 +116,11 @@ impl<Fut: Unpin> ExactSizeIterator for IterMut<'_, Fut> {}
 impl<'a, Fut> Iterator for IterPinRef<'a, Fut> {
     type Item = Pin<&'a Fut>;
 
-    fn next(&mut self) -> Option<Pin<&'a Fut>> {
+    fn next(&mut self) -> Option<Self::Item> {
         if self.task.is_null() {
             return None;
         }
+
         unsafe {
             let future = (*(*self.task).future.get()).as_ref().unwrap();
 
@@ -85,10 +128,7 @@ impl<'a, Fut> Iterator for IterPinRef<'a, Fut> {
             // `head_all` was initially read for this iterator implies acquire
             // ordering for all previously inserted nodes (and we don't need to
             // read `len_all` again for any other nodes).
-            let next = (*self.task).spin_next_all(
-                self.pending_next_all,
-                Relaxed,
-            );
+            let next = (*self.task).spin_next_all(self.pending_next_all, Relaxed);
             self.task = next;
             self.len -= 1;
             Some(Pin::new_unchecked(future))
@@ -105,7 +145,7 @@ impl<Fut> ExactSizeIterator for IterPinRef<'_, Fut> {}
 impl<'a, Fut: Unpin> Iterator for Iter<'a, Fut> {
     type Item = &'a Fut;
 
-    fn next(&mut self) -> Option<&'a Fut> {
+    fn next(&mut self) -> Option<Self::Item> {
         self.0.next().map(Pin::get_ref)
     }
 
@@ -115,3 +155,14 @@ impl<'a, Fut: Unpin> Iterator for Iter<'a, Fut> {
 }
 
 impl<Fut: Unpin> ExactSizeIterator for Iter<'_, Fut> {}
+
+// SAFETY: we do nothing thread-local and there is no interior mutability,
+// so the usual structural `Send`/`Sync` apply.
+unsafe impl<Fut: Send> Send for IterPinRef<'_, Fut> {}
+unsafe impl<Fut: Sync> Sync for IterPinRef<'_, Fut> {}
+
+unsafe impl<Fut: Send> Send for IterPinMut<'_, Fut> {}
+unsafe impl<Fut: Sync> Sync for IterPinMut<'_, Fut> {}
+
+unsafe impl<Fut: Send + Unpin> Send for IntoIter<Fut> {}
+unsafe impl<Fut: Sync + Unpin> Sync for IntoIter<Fut> {}
diff --git a/third_party/rust/futures-util/src/stream/futures_unordered/mod.rs b/third_party/rust/futures-util/src/stream/futures_unordered/mod.rs
index 37b7d7e0ec4091a58c6fc431b291e27ed6a395b9..a25fbe03ef520e15b94548914b648782b5b65202 100644
--- a/third_party/rust/futures-util/src/stream/futures_unordered/mod.rs
+++ b/third_party/rust/futures-util/src/stream/futures_unordered/mod.rs
@@ -3,11 +3,8 @@
 //! This module is only available when the `std` or `alloc` feature of this
 //! library is activated, and it is activated by default.
 
-use futures_core::future::Future;
-use futures_core::stream::{FusedStream, Stream};
-use futures_core::task::{Context, Poll};
-use futures_task::{FutureObj, LocalFutureObj, Spawn, LocalSpawn, SpawnError};
 use crate::task::AtomicWaker;
+use alloc::sync::{Arc, Weak};
 use core::cell::UnsafeCell;
 use core::fmt::{self, Debug};
 use core::iter::FromIterator;
@@ -16,36 +13,22 @@ use core::mem;
 use core::pin::Pin;
 use core::ptr;
 use core::sync::atomic::Ordering::{AcqRel, Acquire, Relaxed, Release, SeqCst};
-use core::sync::atomic::{AtomicPtr, AtomicBool};
-use alloc::sync::{Arc, Weak};
+use core::sync::atomic::{AtomicBool, AtomicPtr};
+use futures_core::future::Future;
+use futures_core::stream::{FusedStream, Stream};
+use futures_core::task::{Context, Poll};
+use futures_task::{FutureObj, LocalFutureObj, LocalSpawn, Spawn, SpawnError};
 
 mod abort;
 
 mod iter;
-pub use self::iter::{Iter, IterMut, IterPinMut, IterPinRef};
+pub use self::iter::{IntoIter, Iter, IterMut, IterPinMut, IterPinRef};
 
 mod task;
 use self::task::Task;
 
 mod ready_to_run_queue;
-use self::ready_to_run_queue::{ReadyToRunQueue, Dequeue};
-
-/// Constant used for a `FuturesUnordered` to determine how many times it is
-/// allowed to poll underlying futures without yielding.
-///
-/// A single call to `poll_next` may potentially do a lot of work before
-/// yielding. This happens in particular if the underlying futures are awoken
-/// frequently but continue to return `Pending`. This is problematic if other
-/// tasks are waiting on the executor, since they do not get to run. This value
-/// caps the number of calls to `poll` on underlying futures a single call to
-/// `poll_next` is allowed to make.
-///
-/// The value itself is chosen somewhat arbitrarily. It needs to be high enough
-/// that amortize wakeup and scheduling costs, but low enough that we do not
-/// starve other tasks for long.
-///
-/// See also https://github.com/rust-lang/futures-rs/issues/2047.
-const YIELD_EVERY: usize = 32;
+use self::ready_to_run_queue::{Dequeue, ReadyToRunQueue};
 
 /// A set of futures which may complete in any order.
 ///
@@ -79,18 +62,14 @@ unsafe impl<Fut: Sync> Sync for FuturesUnordered<Fut> {}
 impl<Fut> Unpin for FuturesUnordered<Fut> {}
 
 impl Spawn for FuturesUnordered<FutureObj<'_, ()>> {
-    fn spawn_obj(&self, future_obj: FutureObj<'static, ()>)
-        -> Result<(), SpawnError>
-    {
+    fn spawn_obj(&self, future_obj: FutureObj<'static, ()>) -> Result<(), SpawnError> {
         self.push(future_obj);
         Ok(())
     }
 }
 
 impl LocalSpawn for FuturesUnordered<LocalFutureObj<'_, ()>> {
-    fn spawn_local_obj(&self, future_obj: LocalFutureObj<'static, ()>)
-        -> Result<(), SpawnError>
-    {
+    fn spawn_local_obj(&self, future_obj: LocalFutureObj<'static, ()>) -> Result<(), SpawnError> {
         self.push(future_obj);
         Ok(())
     }
@@ -207,24 +186,26 @@ impl<Fut> FuturesUnordered<Fut> {
     }
 
     /// Returns an iterator that allows inspecting each future in the set.
-    pub fn iter(&self) -> Iter<'_, Fut> where Fut: Unpin {
+    pub fn iter(&self) -> Iter<'_, Fut>
+    where
+        Fut: Unpin,
+    {
         Iter(Pin::new(self).iter_pin_ref())
     }
 
     /// Returns an iterator that allows inspecting each future in the set.
-    fn iter_pin_ref(self: Pin<&Self>) -> IterPinRef<'_, Fut> {
+    pub fn iter_pin_ref(self: Pin<&Self>) -> IterPinRef<'_, Fut> {
         let (task, len) = self.atomic_load_head_and_len_all();
+        let pending_next_all = self.pending_next_all();
 
-        IterPinRef {
-            task,
-            len,
-            pending_next_all: self.pending_next_all(),
-            _marker: PhantomData,
-        }
+        IterPinRef { task, len, pending_next_all, _marker: PhantomData }
     }
 
     /// Returns an iterator that allows modifying each future in the set.
-    pub fn iter_mut(&mut self) -> IterMut<'_, Fut> where Fut: Unpin {
+    pub fn iter_mut(&mut self) -> IterMut<'_, Fut>
+    where
+        Fut: Unpin,
+    {
         IterMut(Pin::new(self).iter_pin_mut())
     }
 
@@ -233,19 +214,9 @@ impl<Fut> FuturesUnordered<Fut> {
         // `head_all` can be accessed directly and we don't need to spin on
         // `Task::next_all` since we have exclusive access to the set.
         let task = *self.head_all.get_mut();
-        let len = if task.is_null() {
-            0
-        } else {
-            unsafe {
-                *(*task).len_all.get()
-            }
-        };
+        let len = if task.is_null() { 0 } else { unsafe { *(*task).len_all.get() } };
 
-        IterPinMut {
-            task,
-            len,
-            _marker: PhantomData
-        }
+        IterPinMut { task, len, _marker: PhantomData }
     }
 
     /// Returns the current head node and number of futures in the list of all
@@ -265,7 +236,7 @@ impl<Fut> FuturesUnordered<Fut> {
         (task, len)
     }
 
-    /// Releases the task. It destorys the future inside and either drops
+    /// Releases the task. It destroys the future inside and either drops
     /// the `Arc<Task>` or transfers ownership to the ready to run queue.
     /// The task this method is called on must have been unlinked before.
     fn release_task(&mut self, task: Arc<Task<Fut>>) {
@@ -411,9 +382,23 @@ impl<Fut> FuturesUnordered<Fut> {
 impl<Fut: Future> Stream for FuturesUnordered<Fut> {
     type Item = Fut::Output;
 
-    fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>)
-        -> Poll<Option<Self::Item>>
-    {
+    fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
+        // Variable to determine how many times it is allowed to poll underlying
+        // futures without yielding.
+        //
+        // A single call to `poll_next` may potentially do a lot of work before
+        // yielding. This happens in particular if the underlying futures are awoken
+        // frequently but continue to return `Pending`. This is problematic if other
+        // tasks are waiting on the executor, since they do not get to run. This value
+        // caps the number of calls to `poll` on underlying futures a single call to
+        // `poll_next` is allowed to make.
+        //
+        // The value is the length of FuturesUnordered. This ensures that each
+        // future is polled only once at most per iteration.
+        //
+        // See also https://github.com/rust-lang/futures-rs/issues/2047.
+        let yield_every = self.len();
+
         // Keep track of how many child futures we have polled,
         // in case we want to forcibly yield.
         let mut polled = 0;
@@ -469,14 +454,11 @@ impl<Fut: Future> Stream for FuturesUnordered<Fut> {
 
                     // Double check that the call to `release_task` really
                     // happened. Calling it required the task to be unlinked.
-                    debug_assert_eq!(
-                        task.next_all.load(Relaxed),
-                        self.pending_next_all()
-                    );
+                    debug_assert_eq!(task.next_all.load(Relaxed), self.pending_next_all());
                     unsafe {
                         debug_assert!((*task.prev_all.get()).is_null());
                     }
-                    continue
+                    continue;
                 }
             };
 
@@ -516,10 +498,7 @@ impl<Fut: Future> Stream for FuturesUnordered<Fut> {
                 }
             }
 
-            let mut bomb = Bomb {
-                task: Some(task),
-                queue: &mut *self,
-            };
+            let mut bomb = Bomb { task: Some(task), queue: &mut *self };
 
             // Poll the underlying future with the appropriate waker
             // implementation. This is where a large bit of the unsafety
@@ -548,18 +527,16 @@ impl<Fut: Future> Stream for FuturesUnordered<Fut> {
                     let task = bomb.task.take().unwrap();
                     bomb.queue.link(task);
 
-                    if polled == YIELD_EVERY {
+                    if polled == yield_every {
                         // We have polled a large number of futures in a row without yielding.
                         // To ensure we do not starve other tasks waiting on the executor,
                         // we yield here, but immediately wake ourselves up to continue.
                         cx.waker().wake_by_ref();
                         return Poll::Pending;
                     }
-                    continue
-                }
-                Poll::Ready(output) => {
-                    return Poll::Ready(Some(output))
+                    continue;
                 }
+                Poll::Ready(output) => return Poll::Ready(Some(output)),
             }
         }
     }
@@ -576,19 +553,33 @@ impl<Fut> Debug for FuturesUnordered<Fut> {
     }
 }
 
+impl<Fut> FuturesUnordered<Fut> {
+    /// Clears the set, removing all futures.
+    pub fn clear(&mut self) {
+        self.clear_head_all();
+
+        // we just cleared all the tasks, and we have &mut self, so this is safe.
+        unsafe { self.ready_to_run_queue.clear() };
+
+        self.is_terminated.store(false, Relaxed);
+    }
+
+    fn clear_head_all(&mut self) {
+        while !self.head_all.get_mut().is_null() {
+            let head = *self.head_all.get_mut();
+            let task = unsafe { self.unlink(head) };
+            self.release_task(task);
+        }
+    }
+}
+
 impl<Fut> Drop for FuturesUnordered<Fut> {
     fn drop(&mut self) {
         // When a `FuturesUnordered` is dropped we want to drop all futures
         // associated with it. At the same time though there may be tons of
         // wakers flying around which contain `Task<Fut>` references
         // inside them. We'll let those naturally get deallocated.
-        unsafe {
-            while !self.head_all.get_mut().is_null() {
-                let head = *self.head_all.get_mut();
-                let task = self.unlink(head);
-                self.release_task(task);
-            }
-        }
+        self.clear_head_all();
 
         // Note that at this point we could still have a bunch of tasks in the
         // ready to run queue. None of those tasks, however, have futures
@@ -605,13 +596,48 @@ impl<Fut> Drop for FuturesUnordered<Fut> {
     }
 }
 
+impl<'a, Fut: Unpin> IntoIterator for &'a FuturesUnordered<Fut> {
+    type Item = &'a Fut;
+    type IntoIter = Iter<'a, Fut>;
+
+    fn into_iter(self) -> Self::IntoIter {
+        self.iter()
+    }
+}
+
+impl<'a, Fut: Unpin> IntoIterator for &'a mut FuturesUnordered<Fut> {
+    type Item = &'a mut Fut;
+    type IntoIter = IterMut<'a, Fut>;
+
+    fn into_iter(self) -> Self::IntoIter {
+        self.iter_mut()
+    }
+}
+
+impl<Fut: Unpin> IntoIterator for FuturesUnordered<Fut> {
+    type Item = Fut;
+    type IntoIter = IntoIter<Fut>;
+
+    fn into_iter(mut self) -> Self::IntoIter {
+        // `head_all` can be accessed directly and we don't need to spin on
+        // `Task::next_all` since we have exclusive access to the set.
+        let task = *self.head_all.get_mut();
+        let len = if task.is_null() { 0 } else { unsafe { *(*task).len_all.get() } };
+
+        IntoIter { len, inner: self }
+    }
+}
+
 impl<Fut> FromIterator<Fut> for FuturesUnordered<Fut> {
     fn from_iter<I>(iter: I) -> Self
     where
         I: IntoIterator<Item = Fut>,
     {
         let acc = Self::new();
-        iter.into_iter().fold(acc, |acc, item| { acc.push(item); acc })
+        iter.into_iter().fold(acc, |acc, item| {
+            acc.push(item);
+            acc
+        })
     }
 }
 
diff --git a/third_party/rust/futures-util/src/stream/futures_unordered/ready_to_run_queue.rs b/third_party/rust/futures-util/src/stream/futures_unordered/ready_to_run_queue.rs
index 210519585e3850f35f90cf3c36726a3beec1fd9c..5ef6cde83d21bf041d91c5cbd00c961fd6a2fbb7 100644
--- a/third_party/rust/futures-util/src/stream/futures_unordered/ready_to_run_queue.rs
+++ b/third_party/rust/futures-util/src/stream/futures_unordered/ready_to_run_queue.rs
@@ -1,9 +1,9 @@
 use crate::task::AtomicWaker;
+use alloc::sync::Arc;
 use core::cell::UnsafeCell;
 use core::ptr;
 use core::sync::atomic::AtomicPtr;
-use core::sync::atomic::Ordering::{Relaxed, Acquire, Release, AcqRel};
-use alloc::sync::Arc;
+use core::sync::atomic::Ordering::{AcqRel, Acquire, Relaxed, Release};
 
 use super::abort::abort;
 use super::task::Task;
@@ -85,25 +85,38 @@ impl<Fut> ReadyToRunQueue<Fut> {
     pub(super) fn stub(&self) -> *const Task<Fut> {
         &*self.stub
     }
+
+    // Clear the queue of tasks.
+    //
+    // Note that each task has a strong reference count associated with it
+    // which is owned by the ready to run queue. This method just pulls out
+    // tasks and drops their refcounts.
+    //
+    // # Safety
+    //
+    // - All tasks **must** have had their futures dropped already (by FuturesUnordered::clear)
+    // - The caller **must** guarantee unique access to `self`
+    pub(crate) unsafe fn clear(&self) {
+        loop {
+            // SAFETY: We have the guarantee of mutual exclusion required by `dequeue`.
+            match self.dequeue() {
+                Dequeue::Empty => break,
+                Dequeue::Inconsistent => abort("inconsistent in drop"),
+                Dequeue::Data(ptr) => drop(Arc::from_raw(ptr)),
+            }
+        }
+    }
 }
 
 impl<Fut> Drop for ReadyToRunQueue<Fut> {
     fn drop(&mut self) {
         // Once we're in the destructor for `Inner<Fut>` we need to clear out
         // the ready to run queue of tasks if there's anything left in there.
-        //
-        // Note that each task has a strong reference count associated with it
-        // which is owned by the ready to run queue. All tasks should have had
-        // their futures dropped already by the `FuturesUnordered` destructor
-        // above, so we're just pulling out tasks and dropping their refcounts.
+
+        // All tasks have had their futures dropped already by the `FuturesUnordered`
+        // destructor above, and we have &mut self, so this is safe.
         unsafe {
-            loop {
-                match self.dequeue() {
-                    Dequeue::Empty => break,
-                    Dequeue::Inconsistent => abort("inconsistent in drop"),
-                    Dequeue::Data(ptr) => drop(Arc::from_raw(ptr)),
-                }
-            }
+            self.clear();
         }
     }
 }
diff --git a/third_party/rust/futures-util/src/stream/futures_unordered/task.rs b/third_party/rust/futures-util/src/stream/futures_unordered/task.rs
index 261408f01cca661d74f23be55b419f1fae801bb9..da2cd67d975df56a6b4118c99f79e347d97bf8d3 100644
--- a/third_party/rust/futures-util/src/stream/futures_unordered/task.rs
+++ b/third_party/rust/futures-util/src/stream/futures_unordered/task.rs
@@ -1,11 +1,11 @@
+use alloc::sync::{Arc, Weak};
 use core::cell::UnsafeCell;
-use core::sync::atomic::{AtomicPtr, AtomicBool};
 use core::sync::atomic::Ordering::{self, SeqCst};
-use alloc::sync::{Arc, Weak};
+use core::sync::atomic::{AtomicBool, AtomicPtr};
 
-use crate::task::{ArcWake, WakerRef, waker_ref};
-use super::ReadyToRunQueue;
 use super::abort::abort;
+use super::ReadyToRunQueue;
+use crate::task::{waker_ref, ArcWake, WakerRef};
 
 pub(super) struct Task<Fut> {
     // The future
diff --git a/third_party/rust/futures-util/src/stream/iter.rs b/third_party/rust/futures-util/src/stream/iter.rs
index cab8cd81b16eb7b231deeccdc5d776cd4c01bbf7..20471c2ed0630f69ee9dae2552ee0838eea5439e 100644
--- a/third_party/rust/futures-util/src/stream/iter.rs
+++ b/third_party/rust/futures-util/src/stream/iter.rs
@@ -1,3 +1,4 @@
+use super::assert_stream;
 use core::pin::Pin;
 use futures_core::stream::Stream;
 use futures_core::task::{Context, Poll};
@@ -26,15 +27,15 @@ impl<I> Unpin for Iter<I> {}
 /// # });
 /// ```
 pub fn iter<I>(i: I) -> Iter<I::IntoIter>
-    where I: IntoIterator,
+where
+    I: IntoIterator,
 {
-    Iter {
-        iter: i.into_iter(),
-    }
+    assert_stream::<I::Item, _>(Iter { iter: i.into_iter() })
 }
 
 impl<I> Stream for Iter<I>
-    where I: Iterator,
+where
+    I: Iterator,
 {
     type Item = I::Item;
 
diff --git a/third_party/rust/futures-util/src/stream/mod.rs b/third_party/rust/futures-util/src/stream/mod.rs
index a5624badac5188d38098af35fdf6971ec3e5887d..0b2fc90532da9685546f8fa9acda886e92e25ba9 100644
--- a/third_party/rust/futures-util/src/stream/mod.rs
+++ b/third_party/rust/futures-util/src/stream/mod.rs
@@ -19,8 +19,8 @@ pub use futures_core::stream::{FusedStream, Stream, TryStream};
 mod stream;
 pub use self::stream::{
     Chain, Collect, Concat, Cycle, Enumerate, Filter, FilterMap, FlatMap, Flatten, Fold, ForEach,
-    Fuse, Inspect, Map, Next, Peek, Peekable, Scan, SelectNextSome, Skip, SkipWhile, StreamExt,
-    StreamFuture, Take, TakeUntil, TakeWhile, Then, Unzip, Zip,
+    Fuse, Inspect, Map, Next, NextIf, NextIfEq, Peek, Peekable, Scan, SelectNextSome, Skip,
+    SkipWhile, StreamExt, StreamFuture, Take, TakeUntil, TakeWhile, Then, Unzip, Zip,
 };
 
 #[cfg(feature = "std")]
@@ -36,11 +36,11 @@ pub use self::stream::ReadyChunks;
 #[cfg_attr(docsrs, doc(cfg(feature = "sink")))]
 pub use self::stream::Forward;
 
-#[cfg_attr(feature = "cfg-target-has-atomic", cfg(target_has_atomic = "ptr"))]
+#[cfg(not(futures_no_atomic_cas))]
 #[cfg(feature = "alloc")]
 pub use self::stream::{BufferUnordered, Buffered, ForEachConcurrent};
 
-#[cfg_attr(feature = "cfg-target-has-atomic", cfg(target_has_atomic = "ptr"))]
+#[cfg(not(futures_no_atomic_cas))]
 #[cfg(feature = "sink")]
 #[cfg_attr(docsrs, doc(cfg(feature = "sink")))]
 #[cfg(feature = "alloc")]
@@ -58,7 +58,7 @@ pub use self::try_stream::{
 #[cfg(feature = "std")]
 pub use self::try_stream::IntoAsyncRead;
 
-#[cfg_attr(feature = "cfg-target-has-atomic", cfg(target_has_atomic = "ptr"))]
+#[cfg(not(futures_no_atomic_cas))]
 #[cfg(feature = "alloc")]
 pub use self::try_stream::{TryBufferUnordered, TryBuffered, TryForEachConcurrent};
 
@@ -104,16 +104,23 @@ cfg_target_has_atomic! {
     pub use self::futures_unordered::FuturesUnordered;
 
     #[cfg(feature = "alloc")]
-    mod select_all;
+    pub mod select_all;
     #[cfg(feature = "alloc")]
     pub use self::select_all::{select_all, SelectAll};
+
+    #[cfg(feature = "alloc")]
+    mod abortable;
+    #[cfg(feature = "alloc")]
+    pub use crate::abortable::{Abortable, AbortHandle, AbortRegistration, Aborted};
+    #[cfg(feature = "alloc")]
+    pub use abortable::abortable;
 }
 
-// Just a helper function to ensure the futures we're returning all have the
+// Just a helper function to ensure the streams we're returning all have the
 // right implementations.
 pub(crate) fn assert_stream<T, S>(stream: S) -> S
-    where
-        S: Stream<Item = T>,
+where
+    S: Stream<Item = T>,
 {
     stream
 }
diff --git a/third_party/rust/futures-util/src/stream/once.rs b/third_party/rust/futures-util/src/stream/once.rs
index 318de076d117ca34438319334c4243f394405ef0..ee21c8b594bb27c34140153824a96aa1f4b14589 100644
--- a/third_party/rust/futures-util/src/stream/once.rs
+++ b/third_party/rust/futures-util/src/stream/once.rs
@@ -1,7 +1,8 @@
+use super::assert_stream;
 use core::pin::Pin;
 use futures_core::future::Future;
 use futures_core::ready;
-use futures_core::stream::{Stream, FusedStream};
+use futures_core::stream::{FusedStream, Stream};
 use futures_core::task::{Context, Poll};
 use pin_project_lite::pin_project;
 
@@ -17,7 +18,7 @@ use pin_project_lite::pin_project;
 /// # });
 /// ```
 pub fn once<Fut: Future>(future: Fut) -> Once<Fut> {
-    Once::new(future)
+    assert_stream::<Fut::Output, _>(Once::new(future))
 }
 
 pin_project! {
diff --git a/third_party/rust/futures-util/src/stream/pending.rs b/third_party/rust/futures-util/src/stream/pending.rs
index ca793c1e0431c5b2fe7b0362b56200045db55282..d7030ff3cc21edec4571cfa39a08c4ebfc2e1c5a 100644
--- a/third_party/rust/futures-util/src/stream/pending.rs
+++ b/third_party/rust/futures-util/src/stream/pending.rs
@@ -1,3 +1,4 @@
+use super::assert_stream;
 use core::marker;
 use core::pin::Pin;
 use futures_core::stream::{FusedStream, Stream};
@@ -14,7 +15,7 @@ pub struct Pending<T> {
 ///
 /// The returned stream will always return `Pending` when polled.
 pub fn pending<T>() -> Pending<T> {
-    Pending { _data: marker::PhantomData }
+    assert_stream::<T, _>(Pending { _data: marker::PhantomData })
 }
 
 impl<T> Unpin for Pending<T> {}
diff --git a/third_party/rust/futures-util/src/stream/poll_fn.rs b/third_party/rust/futures-util/src/stream/poll_fn.rs
index e33ca577ae6b4bd6fce1ff75912f45b083a0d091..b9bd7d1664a1ca1266c665e08bc1afe44662d709 100644
--- a/third_party/rust/futures-util/src/stream/poll_fn.rs
+++ b/third_party/rust/futures-util/src/stream/poll_fn.rs
@@ -1,5 +1,6 @@
 //! Definition of the `PollFn` combinator
 
+use super::assert_stream;
 use core::fmt;
 use core::pin::Pin;
 use futures_core::stream::Stream;
@@ -41,7 +42,7 @@ pub fn poll_fn<T, F>(f: F) -> PollFn<F>
 where
     F: FnMut(&mut Context<'_>) -> Poll<Option<T>>,
 {
-    PollFn { f }
+    assert_stream::<T, _>(PollFn { f })
 }
 
 impl<T, F> Stream for PollFn<F>
diff --git a/third_party/rust/futures-util/src/stream/repeat.rs b/third_party/rust/futures-util/src/stream/repeat.rs
index 6a2637d3f5a4c3b5c574e365691029a6f4b5eb26..3f9aa87d5c70b43bd18c637ae4bfd009ac4b0ad7 100644
--- a/third_party/rust/futures-util/src/stream/repeat.rs
+++ b/third_party/rust/futures-util/src/stream/repeat.rs
@@ -1,5 +1,6 @@
+use super::assert_stream;
 use core::pin::Pin;
-use futures_core::stream::{Stream, FusedStream};
+use futures_core::stream::{FusedStream, Stream};
 use futures_core::task::{Context, Poll};
 
 /// Stream for the [`repeat`] function.
@@ -24,15 +25,17 @@ pub struct Repeat<T> {
 /// # });
 /// ```
 pub fn repeat<T>(item: T) -> Repeat<T>
-    where T: Clone
+where
+    T: Clone,
 {
-    Repeat { item }
+    assert_stream::<T, _>(Repeat { item })
 }
 
 impl<T> Unpin for Repeat<T> {}
 
 impl<T> Stream for Repeat<T>
-    where T: Clone
+where
+    T: Clone,
 {
     type Item = T;
 
@@ -46,7 +49,8 @@ impl<T> Stream for Repeat<T>
 }
 
 impl<T> FusedStream for Repeat<T>
-    where T: Clone,
+where
+    T: Clone,
 {
     fn is_terminated(&self) -> bool {
         false
diff --git a/third_party/rust/futures-util/src/stream/repeat_with.rs b/third_party/rust/futures-util/src/stream/repeat_with.rs
index eb3313d8c4d001a4a3f64f2729740f4c1187fa1a..f5a81b4ed4c576dce8d8e44fbe40c8dd0c84632f 100644
--- a/third_party/rust/futures-util/src/stream/repeat_with.rs
+++ b/third_party/rust/futures-util/src/stream/repeat_with.rs
@@ -1,5 +1,6 @@
+use super::assert_stream;
 use core::pin::Pin;
-use futures_core::stream::{Stream, FusedStream};
+use futures_core::stream::{FusedStream, Stream};
 use futures_core::task::{Context, Poll};
 
 /// An stream that repeats elements of type `A` endlessly by
@@ -27,8 +28,7 @@ impl<A, F: FnMut() -> A> Stream for RepeatWith<F> {
     }
 }
 
-impl<A, F: FnMut() -> A> FusedStream for RepeatWith<F>
-{
+impl<A, F: FnMut() -> A> FusedStream for RepeatWith<F> {
     fn is_terminated(&self) -> bool {
         false
     }
@@ -89,5 +89,5 @@ impl<A, F: FnMut() -> A> FusedStream for RepeatWith<F>
 /// # });
 /// ```
 pub fn repeat_with<A, F: FnMut() -> A>(repeater: F) -> RepeatWith<F> {
-    RepeatWith { repeater }
+    assert_stream::<A, _>(RepeatWith { repeater })
 }
diff --git a/third_party/rust/futures-util/src/stream/select.rs b/third_party/rust/futures-util/src/stream/select.rs
index 2b7ebec5d65b57ca9450e0e06caf47a61d3efb8c..133ac6c7ac034727d4a168c204641f8972645eca 100644
--- a/third_party/rust/futures-util/src/stream/select.rs
+++ b/third_party/rust/futures-util/src/stream/select.rs
@@ -1,4 +1,5 @@
-use crate::stream::{StreamExt, Fuse};
+use super::assert_stream;
+use crate::stream::{Fuse, StreamExt};
 use core::pin::Pin;
 use futures_core::stream::{FusedStream, Stream};
 use futures_core::task::{Context, Poll};
@@ -28,14 +29,15 @@ pin_project! {
 /// Note that this function consumes both streams and returns a wrapped
 /// version of them.
 pub fn select<St1, St2>(stream1: St1, stream2: St2) -> Select<St1, St2>
-    where St1: Stream,
-          St2: Stream<Item = St1::Item>
+where
+    St1: Stream,
+    St2: Stream<Item = St1::Item>,
 {
-    Select {
+    assert_stream::<St1::Item, _>(Select {
         stream1: stream1.fuse(),
         stream2: stream2.fuse(),
         flag: false,
-    }
+    })
 }
 
 impl<St1, St2> Select<St1, St2> {
@@ -74,8 +76,9 @@ impl<St1, St2> Select<St1, St2> {
 }
 
 impl<St1, St2> FusedStream for Select<St1, St2>
-    where St1: Stream,
-          St2: Stream<Item = St1::Item>
+where
+    St1: Stream,
+    St2: Stream<Item = St1::Item>,
 {
     fn is_terminated(&self) -> bool {
         self.stream1.is_terminated() && self.stream2.is_terminated()
@@ -83,15 +86,13 @@ impl<St1, St2> FusedStream for Select<St1, St2>
 }
 
 impl<St1, St2> Stream for Select<St1, St2>
-    where St1: Stream,
-          St2: Stream<Item = St1::Item>
+where
+    St1: Stream,
+    St2: Stream<Item = St1::Item>,
 {
     type Item = St1::Item;
 
-    fn poll_next(
-        self: Pin<&mut Self>,
-        cx: &mut Context<'_>,
-    ) -> Poll<Option<St1::Item>> {
+    fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<St1::Item>> {
         let this = self.project();
         if !*this.flag {
             poll_inner(this.flag, this.stream1, this.stream2, cx)
@@ -105,24 +106,24 @@ fn poll_inner<St1, St2>(
     flag: &mut bool,
     a: Pin<&mut St1>,
     b: Pin<&mut St2>,
-    cx: &mut Context<'_>
+    cx: &mut Context<'_>,
 ) -> Poll<Option<St1::Item>>
-    where St1: Stream, St2: Stream<Item = St1::Item>
+where
+    St1: Stream,
+    St2: Stream<Item = St1::Item>,
 {
     let a_done = match a.poll_next(cx) {
         Poll::Ready(Some(item)) => {
             // give the other stream a chance to go first next time
             *flag = !*flag;
-            return Poll::Ready(Some(item))
-        },
+            return Poll::Ready(Some(item));
+        }
         Poll::Ready(None) => true,
         Poll::Pending => false,
     };
 
     match b.poll_next(cx) {
-        Poll::Ready(Some(item)) => {
-            Poll::Ready(Some(item))
-        }
+        Poll::Ready(Some(item)) => Poll::Ready(Some(item)),
         Poll::Ready(None) if a_done => Poll::Ready(None),
         Poll::Ready(None) | Poll::Pending => Poll::Pending,
     }
diff --git a/third_party/rust/futures-util/src/stream/select_all.rs b/third_party/rust/futures-util/src/stream/select_all.rs
index 00368bb969f950dec5c7c858fd1d639630ffcc85..3474331adc999262073c292790c62ba8a61694f7 100644
--- a/third_party/rust/futures-util/src/stream/select_all.rs
+++ b/third_party/rust/futures-util/src/stream/select_all.rs
@@ -5,26 +5,32 @@ use core::iter::FromIterator;
 use core::pin::Pin;
 
 use futures_core::ready;
-use futures_core::stream::{Stream, FusedStream};
+use futures_core::stream::{FusedStream, Stream};
 use futures_core::task::{Context, Poll};
 
-use crate::stream::{StreamExt, StreamFuture, FuturesUnordered};
+use pin_project_lite::pin_project;
 
-/// An unbounded set of streams
-///
-/// This "combinator" provides the ability to maintain a set of streams
-/// and drive them all to completion.
-///
-/// Streams are pushed into this set and their realized values are
-/// yielded as they become ready. Streams will only be polled when they
-/// generate notifications. This allows to coordinate a large number of streams.
-///
-/// Note that you can create a ready-made `SelectAll` via the
-/// `select_all` function in the `stream` module, or you can start with an
-/// empty set with the `SelectAll::new` constructor.
-#[must_use = "streams do nothing unless polled"]
-pub struct SelectAll<St> {
-    inner: FuturesUnordered<StreamFuture<St>>,
+use super::assert_stream;
+use crate::stream::{futures_unordered, FuturesUnordered, StreamExt, StreamFuture};
+
+pin_project! {
+    /// An unbounded set of streams
+    ///
+    /// This "combinator" provides the ability to maintain a set of streams
+    /// and drive them all to completion.
+    ///
+    /// Streams are pushed into this set and their realized values are
+    /// yielded as they become ready. Streams will only be polled when they
+    /// generate notifications. This allows to coordinate a large number of streams.
+    ///
+    /// Note that you can create a ready-made `SelectAll` via the
+    /// `select_all` function in the `stream` module, or you can start with an
+    /// empty set with the `SelectAll::new` constructor.
+    #[must_use = "streams do nothing unless polled"]
+    pub struct SelectAll<St> {
+        #[pin]
+        inner: FuturesUnordered<StreamFuture<St>>,
+    }
 }
 
 impl<St: Debug> Debug for SelectAll<St> {
@@ -63,6 +69,21 @@ impl<St: Stream + Unpin> SelectAll<St> {
     pub fn push(&mut self, stream: St) {
         self.inner.push(stream.into_future());
     }
+
+    /// Returns an iterator that allows inspecting each stream in the set.
+    pub fn iter(&self) -> Iter<'_, St> {
+        Iter(self.inner.iter())
+    }
+
+    /// Returns an iterator that allows modifying each stream in the set.
+    pub fn iter_mut(&mut self) -> IterMut<'_, St> {
+        IterMut(self.inner.iter_mut())
+    }
+
+    /// Clears the set, removing all streams.
+    pub fn clear(&mut self) {
+        self.inner.clear()
+    }
 }
 
 impl<St: Stream + Unpin> Default for SelectAll<St> {
@@ -74,10 +95,7 @@ impl<St: Stream + Unpin> Default for SelectAll<St> {
 impl<St: Stream + Unpin> Stream for SelectAll<St> {
     type Item = St::Item;
 
-    fn poll_next(
-        mut self: Pin<&mut Self>,
-        cx: &mut Context<'_>,
-    ) -> Poll<Option<Self::Item>> {
+    fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
         loop {
             match ready!(self.inner.poll_next_unpin(cx)) {
                 Some((Some(item), remaining)) => {
@@ -110,13 +128,14 @@ impl<St: Stream + Unpin> FusedStream for SelectAll<St> {
 /// streams internally, in the order they become available.
 ///
 /// Note that the returned set can also be used to dynamically push more
-/// futures into the set as they become available.
+/// streams into the set as they become available.
 ///
 /// This function is only available when the `std` or `alloc` feature of this
 /// library is activated, and it is activated by default.
 pub fn select_all<I>(streams: I) -> SelectAll<I::Item>
-    where I: IntoIterator,
-          I::Item: Stream + Unpin
+where
+    I: IntoIterator,
+    I::Item: Stream + Unpin,
 {
     let mut set = SelectAll::new();
 
@@ -124,7 +143,7 @@ pub fn select_all<I>(streams: I) -> SelectAll<I::Item>
         set.push(stream);
     }
 
-    set
+    assert_stream::<<I::Item as Stream>::Item, _>(set)
 }
 
 impl<St: Stream + Unpin> FromIterator<St> for SelectAll<St> {
@@ -140,3 +159,96 @@ impl<St: Stream + Unpin> Extend<St> for SelectAll<St> {
         }
     }
 }
+
+impl<St: Stream + Unpin> IntoIterator for SelectAll<St> {
+    type Item = St;
+    type IntoIter = IntoIter<St>;
+
+    fn into_iter(self) -> Self::IntoIter {
+        IntoIter(self.inner.into_iter())
+    }
+}
+
+impl<'a, St: Stream + Unpin> IntoIterator for &'a SelectAll<St> {
+    type Item = &'a St;
+    type IntoIter = Iter<'a, St>;
+
+    fn into_iter(self) -> Self::IntoIter {
+        self.iter()
+    }
+}
+
+impl<'a, St: Stream + Unpin> IntoIterator for &'a mut SelectAll<St> {
+    type Item = &'a mut St;
+    type IntoIter = IterMut<'a, St>;
+
+    fn into_iter(self) -> Self::IntoIter {
+        self.iter_mut()
+    }
+}
+
+/// Immutable iterator over all streams in the unordered set.
+#[derive(Debug)]
+pub struct Iter<'a, St: Unpin>(futures_unordered::Iter<'a, StreamFuture<St>>);
+
+/// Mutable iterator over all streams in the unordered set.
+#[derive(Debug)]
+pub struct IterMut<'a, St: Unpin>(futures_unordered::IterMut<'a, StreamFuture<St>>);
+
+/// Owned iterator over all streams in the unordered set.
+#[derive(Debug)]
+pub struct IntoIter<St: Unpin>(futures_unordered::IntoIter<StreamFuture<St>>);
+
+impl<'a, St: Stream + Unpin> Iterator for Iter<'a, St> {
+    type Item = &'a St;
+
+    fn next(&mut self) -> Option<Self::Item> {
+        let st = self.0.next()?;
+        let next = st.get_ref();
+        // This should always be true because FuturesUnordered removes completed futures.
+        debug_assert!(next.is_some());
+        next
+    }
+
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        self.0.size_hint()
+    }
+}
+
+impl<St: Stream + Unpin> ExactSizeIterator for Iter<'_, St> {}
+
+impl<'a, St: Stream + Unpin> Iterator for IterMut<'a, St> {
+    type Item = &'a mut St;
+
+    fn next(&mut self) -> Option<Self::Item> {
+        let st = self.0.next()?;
+        let next = st.get_mut();
+        // This should always be true because FuturesUnordered removes completed futures.
+        debug_assert!(next.is_some());
+        next
+    }
+
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        self.0.size_hint()
+    }
+}
+
+impl<St: Stream + Unpin> ExactSizeIterator for IterMut<'_, St> {}
+
+impl<St: Stream + Unpin> Iterator for IntoIter<St> {
+    type Item = St;
+
+    fn next(&mut self) -> Option<Self::Item> {
+        let st = self.0.next()?;
+        let next = st.into_inner();
+        // This should always be true because FuturesUnordered removes completed futures.
+        debug_assert!(next.is_some());
+        next
+    }
+
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        self.0.size_hint()
+    }
+}
+
+impl<St: Stream + Unpin> ExactSizeIterator for IntoIter<St> {}
diff --git a/third_party/rust/futures-util/src/stream/stream/buffer_unordered.rs b/third_party/rust/futures-util/src/stream/stream/buffer_unordered.rs
index de42cfd33031e765c113b6ef7b02ae0bb4285dca..d64c142b41c68315e2710cbed44811988dc63a82 100644
--- a/third_party/rust/futures-util/src/stream/stream/buffer_unordered.rs
+++ b/third_party/rust/futures-util/src/stream/stream/buffer_unordered.rs
@@ -1,12 +1,12 @@
 use crate::stream::{Fuse, FuturesUnordered, StreamExt};
+use core::fmt;
+use core::pin::Pin;
 use futures_core::future::Future;
-use futures_core::stream::{Stream, FusedStream};
+use futures_core::stream::{FusedStream, Stream};
 use futures_core::task::{Context, Poll};
 #[cfg(feature = "sink")]
 use futures_sink::Sink;
 use pin_project_lite::pin_project;
-use core::fmt;
-use core::pin::Pin;
 
 pin_project! {
     /// Stream for the [`buffer_unordered`](super::StreamExt::buffer_unordered)
@@ -63,10 +63,7 @@ where
 {
     type Item = <St::Item as Future>::Output;
 
-    fn poll_next(
-        self: Pin<&mut Self>,
-        cx: &mut Context<'_>,
-    ) -> Poll<Option<Self::Item>> {
+    fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
         let mut this = self.project();
 
         // First up, try to spawn off as many futures as possible by filling up
diff --git a/third_party/rust/futures-util/src/stream/stream/buffered.rs b/third_party/rust/futures-util/src/stream/stream/buffered.rs
index 1af9f492b933d4ddb507a4569108bae6b1eaca01..6052a737ba107a05b97af4f7b173eac2a52a6a8d 100644
--- a/third_party/rust/futures-util/src/stream/stream/buffered.rs
+++ b/third_party/rust/futures-util/src/stream/stream/buffered.rs
@@ -1,4 +1,6 @@
 use crate::stream::{Fuse, FuturesOrdered, StreamExt};
+use core::fmt;
+use core::pin::Pin;
 use futures_core::future::Future;
 use futures_core::ready;
 use futures_core::stream::Stream;
@@ -6,8 +8,6 @@ use futures_core::task::{Context, Poll};
 #[cfg(feature = "sink")]
 use futures_sink::Sink;
 use pin_project_lite::pin_project;
-use core::fmt;
-use core::pin::Pin;
 
 pin_project! {
     /// Stream for the [`buffered`](super::StreamExt::buffered) method.
@@ -44,11 +44,7 @@ where
     St::Item: Future,
 {
     pub(super) fn new(stream: St, n: usize) -> Self {
-        Self {
-            stream: super::Fuse::new(stream),
-            in_progress_queue: FuturesOrdered::new(),
-            max: n,
-        }
+        Self { stream: super::Fuse::new(stream), in_progress_queue: FuturesOrdered::new(), max: n }
     }
 
     delegate_access_inner!(stream, St, (.));
@@ -61,10 +57,7 @@ where
 {
     type Item = <St::Item as Future>::Output;
 
-    fn poll_next(
-        self: Pin<&mut Self>,
-        cx: &mut Context<'_>,
-    ) -> Poll<Option<Self::Item>> {
+    fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
         let mut this = self.project();
 
         // First up, try to spawn off as many futures as possible by filling up
@@ -79,7 +72,7 @@ where
         // Attempt to pull the next value from the in_progress_queue
         let res = this.in_progress_queue.poll_next_unpin(cx);
         if let Some(val) = ready!(res) {
-            return Poll::Ready(Some(val))
+            return Poll::Ready(Some(val));
         }
 
         // If more values are still coming from the stream, we're not done yet
diff --git a/third_party/rust/futures-util/src/stream/stream/catch_unwind.rs b/third_party/rust/futures-util/src/stream/stream/catch_unwind.rs
index d87a40a2e3ccc822120a31fd0a29b871d18f6490..09a6dc1b76dbdd254d224b1342e03e979bfb35f2 100644
--- a/third_party/rust/futures-util/src/stream/stream/catch_unwind.rs
+++ b/third_party/rust/futures-util/src/stream/stream/catch_unwind.rs
@@ -1,9 +1,9 @@
-use futures_core::stream::{Stream, FusedStream};
+use futures_core::stream::{FusedStream, Stream};
 use futures_core::task::{Context, Poll};
 use pin_project_lite::pin_project;
 use std::any::Any;
+use std::panic::{catch_unwind, AssertUnwindSafe, UnwindSafe};
 use std::pin::Pin;
-use std::panic::{catch_unwind, UnwindSafe, AssertUnwindSafe};
 
 pin_project! {
     /// Stream for the [`catch_unwind`](super::StreamExt::catch_unwind) method.
@@ -27,25 +27,20 @@ impl<St: Stream + UnwindSafe> CatchUnwind<St> {
 impl<St: Stream + UnwindSafe> Stream for CatchUnwind<St> {
     type Item = Result<St::Item, Box<dyn Any + Send>>;
 
-    fn poll_next(
-        self: Pin<&mut Self>,
-        cx: &mut Context<'_>,
-    ) -> Poll<Option<Self::Item>> {
+    fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
         let mut this = self.project();
 
         if *this.caught_unwind {
             Poll::Ready(None)
         } else {
-            let res = catch_unwind(AssertUnwindSafe(|| {
-                this.stream.as_mut().poll_next(cx)
-            }));
+            let res = catch_unwind(AssertUnwindSafe(|| this.stream.as_mut().poll_next(cx)));
 
             match res {
                 Ok(poll) => poll.map(|opt| opt.map(Ok)),
                 Err(e) => {
                     *this.caught_unwind = true;
                     Poll::Ready(Some(Err(e)))
-                },
+                }
             }
         }
     }
diff --git a/third_party/rust/futures-util/src/stream/stream/chain.rs b/third_party/rust/futures-util/src/stream/stream/chain.rs
index 2be710462a64a801472290bc6371ffa781a73262..c5da35e25ec72e09ae8a10d0009f4d70cc74be52 100644
--- a/third_party/rust/futures-util/src/stream/stream/chain.rs
+++ b/third_party/rust/futures-util/src/stream/stream/chain.rs
@@ -18,20 +18,19 @@ pin_project! {
 
 // All interactions with `Pin<&mut Chain<..>>` happen through these methods
 impl<St1, St2> Chain<St1, St2>
-where St1: Stream,
-      St2: Stream<Item = St1::Item>,
+where
+    St1: Stream,
+    St2: Stream<Item = St1::Item>,
 {
     pub(super) fn new(stream1: St1, stream2: St2) -> Self {
-        Self {
-            first: Some(stream1),
-            second: stream2,
-        }
+        Self { first: Some(stream1), second: stream2 }
     }
 }
 
 impl<St1, St2> FusedStream for Chain<St1, St2>
-where St1: Stream,
-      St2: FusedStream<Item=St1::Item>,
+where
+    St1: Stream,
+    St2: FusedStream<Item = St1::Item>,
 {
     fn is_terminated(&self) -> bool {
         self.first.is_none() && self.second.is_terminated()
@@ -39,19 +38,17 @@ where St1: Stream,
 }
 
 impl<St1, St2> Stream for Chain<St1, St2>
-where St1: Stream,
-      St2: Stream<Item=St1::Item>,
+where
+    St1: Stream,
+    St2: Stream<Item = St1::Item>,
 {
     type Item = St1::Item;
 
-    fn poll_next(
-        self: Pin<&mut Self>,
-        cx: &mut Context<'_>,
-    ) -> Poll<Option<Self::Item>> {
+    fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
         let mut this = self.project();
         if let Some(first) = this.first.as_mut().as_pin_mut() {
             if let Some(item) = ready!(first.poll_next(cx)) {
-                return Poll::Ready(Some(item))
+                return Poll::Ready(Some(item));
             }
         }
         this.first.set(None);
@@ -67,7 +64,7 @@ where St1: Stream,
 
             let upper = match (first_upper, second_upper) {
                 (Some(x), Some(y)) => x.checked_add(y),
-                _ => None
+                _ => None,
             };
 
             (lower, upper)
diff --git a/third_party/rust/futures-util/src/stream/stream/chunks.rs b/third_party/rust/futures-util/src/stream/stream/chunks.rs
index 45a3212582d3bcf30eceba3d42341592649b1953..8457869999448b78d3df57d9e0b95d0b0b50d4f6 100644
--- a/third_party/rust/futures-util/src/stream/stream/chunks.rs
+++ b/third_party/rust/futures-util/src/stream/stream/chunks.rs
@@ -1,13 +1,13 @@
 use crate::stream::Fuse;
+use alloc::vec::Vec;
+use core::mem;
+use core::pin::Pin;
 use futures_core::ready;
-use futures_core::stream::{Stream, FusedStream};
+use futures_core::stream::{FusedStream, Stream};
 use futures_core::task::{Context, Poll};
 #[cfg(feature = "sink")]
 use futures_sink::Sink;
 use pin_project_lite::pin_project;
-use core::mem;
-use core::pin::Pin;
-use alloc::vec::Vec;
 
 pin_project! {
     /// Stream for the [`chunks`](super::StreamExt::chunks) method.
@@ -21,7 +21,10 @@ pin_project! {
     }
 }
 
-impl<St: Stream> Chunks<St> where St: Stream {
+impl<St: Stream> Chunks<St>
+where
+    St: Stream,
+{
     pub(super) fn new(stream: St, capacity: usize) -> Self {
         assert!(capacity > 0);
 
@@ -43,10 +46,7 @@ impl<St: Stream> Chunks<St> where St: Stream {
 impl<St: Stream> Stream for Chunks<St> {
     type Item = Vec<St::Item>;
 
-    fn poll_next(
-        mut self: Pin<&mut Self>,
-        cx: &mut Context<'_>,
-    ) -> Poll<Option<Self::Item>> {
+    fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
         let mut this = self.as_mut().project();
         loop {
             match ready!(this.stream.as_mut().poll_next(cx)) {
@@ -56,7 +56,7 @@ impl<St: Stream> Stream for Chunks<St> {
                 Some(item) => {
                     this.items.push(item);
                     if this.items.len() >= *this.cap {
-                        return Poll::Ready(Some(self.take()))
+                        return Poll::Ready(Some(self.take()));
                     }
                 }
 
diff --git a/third_party/rust/futures-util/src/stream/stream/collect.rs b/third_party/rust/futures-util/src/stream/stream/collect.rs
index 774b34b39a98fa07df18a34237a7722312a6ead3..b0e81b9ce043d94325da48446fd30a01588fb14e 100644
--- a/third_party/rust/futures-util/src/stream/stream/collect.rs
+++ b/third_party/rust/futures-util/src/stream/stream/collect.rs
@@ -23,16 +23,14 @@ impl<St: Stream, C: Default> Collect<St, C> {
     }
 
     pub(super) fn new(stream: St) -> Self {
-        Self {
-            stream,
-            collection: Default::default(),
-        }
+        Self { stream, collection: Default::default() }
     }
 }
 
 impl<St, C> FusedFuture for Collect<St, C>
-where St: FusedStream,
-      C: Default + Extend<St:: Item>
+where
+    St: FusedStream,
+    C: Default + Extend<St::Item>,
 {
     fn is_terminated(&self) -> bool {
         self.stream.is_terminated()
@@ -40,8 +38,9 @@ where St: FusedStream,
 }
 
 impl<St, C> Future for Collect<St, C>
-where St: Stream,
-      C: Default + Extend<St:: Item>
+where
+    St: Stream,
+    C: Default + Extend<St::Item>,
 {
     type Output = C;
 
diff --git a/third_party/rust/futures-util/src/stream/stream/concat.rs b/third_party/rust/futures-util/src/stream/stream/concat.rs
index ee1349f86d70840c3c406b89c5c8aaba540e89fe..7e058b2315618238fd5a91dbecb23357d84697cd 100644
--- a/third_party/rust/futures-util/src/stream/stream/concat.rs
+++ b/third_party/rust/futures-util/src/stream/stream/concat.rs
@@ -1,7 +1,7 @@
 use core::pin::Pin;
-use futures_core::future::{Future, FusedFuture};
+use futures_core::future::{FusedFuture, Future};
 use futures_core::ready;
-use futures_core::stream::{Stream, FusedStream};
+use futures_core::stream::{FusedStream, Stream};
 use futures_core::task::{Context, Poll};
 use pin_project_lite::pin_project;
 
@@ -17,35 +17,28 @@ pin_project! {
 }
 
 impl<St> Concat<St>
-where St: Stream,
-      St::Item: Extend<<St::Item as IntoIterator>::Item> +
-                IntoIterator + Default,
+where
+    St: Stream,
+    St::Item: Extend<<St::Item as IntoIterator>::Item> + IntoIterator + Default,
 {
     pub(super) fn new(stream: St) -> Self {
-        Self {
-            stream,
-            accum: None,
-        }
+        Self { stream, accum: None }
     }
 }
 
 impl<St> Future for Concat<St>
-where St: Stream,
-      St::Item: Extend<<St::Item as IntoIterator>::Item> +
-                IntoIterator + Default,
+where
+    St: Stream,
+    St::Item: Extend<<St::Item as IntoIterator>::Item> + IntoIterator + Default,
 {
     type Output = St::Item;
 
-    fn poll(
-        self: Pin<&mut Self>, cx: &mut Context<'_>
-    ) -> Poll<Self::Output> {
+    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
         let mut this = self.project();
 
         loop {
             match ready!(this.stream.as_mut().poll_next(cx)) {
-                None => {
-                    return Poll::Ready(this.accum.take().unwrap_or_default())
-                }
+                None => return Poll::Ready(this.accum.take().unwrap_or_default()),
                 Some(e) => {
                     if let Some(a) = this.accum {
                         a.extend(e)
@@ -59,9 +52,9 @@ where St: Stream,
 }
 
 impl<St> FusedFuture for Concat<St>
-where St: FusedStream,
-      St::Item: Extend<<St::Item as IntoIterator>::Item> +
-                IntoIterator + Default,
+where
+    St: FusedStream,
+    St::Item: Extend<<St::Item as IntoIterator>::Item> + IntoIterator + Default,
 {
     fn is_terminated(&self) -> bool {
         self.accum.is_none() && self.stream.is_terminated()
diff --git a/third_party/rust/futures-util/src/stream/stream/cycle.rs b/third_party/rust/futures-util/src/stream/stream/cycle.rs
index a5b7dc08c50fa212dc19342a5655d7c10ee5454a..507431d24f984ea72ccced9c065eca1e325705fb 100644
--- a/third_party/rust/futures-util/src/stream/stream/cycle.rs
+++ b/third_party/rust/futures-util/src/stream/stream/cycle.rs
@@ -21,10 +21,7 @@ where
     St: Clone + Stream,
 {
     pub(super) fn new(stream: St) -> Self {
-        Self {
-            orig: stream.clone(),
-            stream,
-        }
+        Self { orig: stream.clone(), stream }
     }
 }
 
diff --git a/third_party/rust/futures-util/src/stream/stream/enumerate.rs b/third_party/rust/futures-util/src/stream/stream/enumerate.rs
index 7d4c9cbe68c6a7bdfe25090c93a7432c1c90dd06..1cf9d49aaa30728115690011d361a6716e8d80dd 100644
--- a/third_party/rust/futures-util/src/stream/stream/enumerate.rs
+++ b/third_party/rust/futures-util/src/stream/stream/enumerate.rs
@@ -19,10 +19,7 @@ pin_project! {
 
 impl<St: Stream> Enumerate<St> {
     pub(super) fn new(stream: St) -> Self {
-        Self {
-            stream,
-            count: 0,
-        }
+        Self { stream, count: 0 }
     }
 
     delegate_access_inner!(stream, St, ());
@@ -37,10 +34,7 @@ impl<St: Stream + FusedStream> FusedStream for Enumerate<St> {
 impl<St: Stream> Stream for Enumerate<St> {
     type Item = (usize, St::Item);
 
-    fn poll_next(
-        self: Pin<&mut Self>,
-        cx: &mut Context<'_>,
-    ) -> Poll<Option<Self::Item>> {
+    fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
         let this = self.project();
 
         match ready!(this.stream.poll_next(cx)) {
diff --git a/third_party/rust/futures-util/src/stream/stream/filter.rs b/third_party/rust/futures-util/src/stream/stream/filter.rs
index 57de0253a4502597c869fc78817efbddfa0376b4..ccf1a5122f3646b881d07adaa6131bffd87f58fb 100644
--- a/third_party/rust/futures-util/src/stream/stream/filter.rs
+++ b/third_party/rust/futures-util/src/stream/stream/filter.rs
@@ -1,3 +1,4 @@
+use crate::fns::FnMut1;
 use core::fmt;
 use core::pin::Pin;
 use futures_core::future::Future;
@@ -7,7 +8,6 @@ use futures_core::task::{Context, Poll};
 #[cfg(feature = "sink")]
 use futures_sink::Sink;
 use pin_project_lite::pin_project;
-use crate::fns::FnMut1;
 
 pin_project! {
     /// Stream for the [`filter`](super::StreamExt::filter) method.
@@ -41,26 +41,23 @@ where
 
 #[allow(single_use_lifetimes)] // https://github.com/rust-lang/rust/issues/55058
 impl<St, Fut, F> Filter<St, Fut, F>
-where St: Stream,
-      F: for<'a> FnMut1<&'a St::Item, Output=Fut>,
-      Fut: Future<Output = bool>,
+where
+    St: Stream,
+    F: for<'a> FnMut1<&'a St::Item, Output = Fut>,
+    Fut: Future<Output = bool>,
 {
     pub(super) fn new(stream: St, f: F) -> Self {
-        Self {
-            stream,
-            f,
-            pending_fut: None,
-            pending_item: None,
-        }
+        Self { stream, f, pending_fut: None, pending_item: None }
     }
 
     delegate_access_inner!(stream, St, ());
 }
 
 impl<St, Fut, F> FusedStream for Filter<St, Fut, F>
-    where St: Stream + FusedStream,
-          F: FnMut(&St::Item) -> Fut,
-          Fut: Future<Output = bool>,
+where
+    St: Stream + FusedStream,
+    F: FnMut(&St::Item) -> Fut,
+    Fut: Future<Output = bool>,
 {
     fn is_terminated(&self) -> bool {
         self.pending_fut.is_none() && self.stream.is_terminated()
@@ -69,16 +66,14 @@ impl<St, Fut, F> FusedStream for Filter<St, Fut, F>
 
 #[allow(single_use_lifetimes)] // https://github.com/rust-lang/rust/issues/55058
 impl<St, Fut, F> Stream for Filter<St, Fut, F>
-    where St: Stream,
-          F: for<'a> FnMut1<&'a St::Item, Output=Fut>,
-          Fut: Future<Output = bool>,
+where
+    St: Stream,
+    F: for<'a> FnMut1<&'a St::Item, Output = Fut>,
+    Fut: Future<Output = bool>,
 {
     type Item = St::Item;
 
-    fn poll_next(
-        self: Pin<&mut Self>,
-        cx: &mut Context<'_>,
-    ) -> Poll<Option<St::Item>> {
+    fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<St::Item>> {
         let mut this = self.project();
         Poll::Ready(loop {
             if let Some(fut) = this.pending_fut.as_mut().as_pin_mut() {
@@ -111,9 +106,10 @@ impl<St, Fut, F> Stream for Filter<St, Fut, F>
 // Forwarding impl of Sink from the underlying stream
 #[cfg(feature = "sink")]
 impl<S, Fut, F, Item> Sink<Item> for Filter<S, Fut, F>
-    where S: Stream + Sink<Item>,
-          F: FnMut(&S::Item) -> Fut,
-          Fut: Future<Output = bool>,
+where
+    S: Stream + Sink<Item>,
+    F: FnMut(&S::Item) -> Fut,
+    Fut: Future<Output = bool>,
 {
     type Error = S::Error;
 
diff --git a/third_party/rust/futures-util/src/stream/stream/filter_map.rs b/third_party/rust/futures-util/src/stream/stream/filter_map.rs
index b762face288285c7a3dc10b36bf61228a114484d..02a0a4386e4afeb5a8c09bd124dc3798aa3fdd04 100644
--- a/third_party/rust/futures-util/src/stream/stream/filter_map.rs
+++ b/third_party/rust/futures-util/src/stream/stream/filter_map.rs
@@ -1,3 +1,4 @@
+use crate::fns::FnMut1;
 use core::fmt;
 use core::pin::Pin;
 use futures_core::future::Future;
@@ -7,7 +8,6 @@ use futures_core::task::{Context, Poll};
 #[cfg(feature = "sink")]
 use futures_sink::Sink;
 use pin_project_lite::pin_project;
-use crate::fns::FnMut1;
 
 pin_project! {
     /// Stream for the [`filter_map`](super::StreamExt::filter_map) method.
@@ -35,9 +35,10 @@ where
 }
 
 impl<St, Fut, F> FilterMap<St, Fut, F>
-    where St: Stream,
-          F: FnMut(St::Item) -> Fut,
-          Fut: Future,
+where
+    St: Stream,
+    F: FnMut(St::Item) -> Fut,
+    Fut: Future,
 {
     pub(super) fn new(stream: St, f: F) -> Self {
         Self { stream, f, pending: None }
@@ -47,9 +48,10 @@ impl<St, Fut, F> FilterMap<St, Fut, F>
 }
 
 impl<St, Fut, F, T> FusedStream for FilterMap<St, Fut, F>
-    where St: Stream + FusedStream,
-          F: FnMut1<St::Item, Output=Fut>,
-          Fut: Future<Output = Option<T>>,
+where
+    St: Stream + FusedStream,
+    F: FnMut1<St::Item, Output = Fut>,
+    Fut: Future<Output = Option<T>>,
 {
     fn is_terminated(&self) -> bool {
         self.pending.is_none() && self.stream.is_terminated()
@@ -57,16 +59,14 @@ impl<St, Fut, F, T> FusedStream for FilterMap<St, Fut, F>
 }
 
 impl<St, Fut, F, T> Stream for FilterMap<St, Fut, F>
-    where St: Stream,
-          F: FnMut1<St::Item, Output=Fut>,
-          Fut: Future<Output = Option<T>>,
+where
+    St: Stream,
+    F: FnMut1<St::Item, Output = Fut>,
+    Fut: Future<Output = Option<T>>,
 {
     type Item = T;
 
-    fn poll_next(
-        self: Pin<&mut Self>,
-        cx: &mut Context<'_>,
-    ) -> Poll<Option<T>> {
+    fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<T>> {
         let mut this = self.project();
         Poll::Ready(loop {
             if let Some(p) = this.pending.as_mut().as_pin_mut() {
@@ -100,9 +100,10 @@ impl<St, Fut, F, T> Stream for FilterMap<St, Fut, F>
 // Forwarding impl of Sink from the underlying stream
 #[cfg(feature = "sink")]
 impl<S, Fut, F, Item> Sink<Item> for FilterMap<S, Fut, F>
-    where S: Stream + Sink<Item>,
-          F: FnMut1<S::Item, Output=Fut>,
-          Fut: Future,
+where
+    S: Stream + Sink<Item>,
+    F: FnMut1<S::Item, Output = Fut>,
+    Fut: Future,
 {
     type Error = S::Error;
 
diff --git a/third_party/rust/futures-util/src/stream/stream/fold.rs b/third_party/rust/futures-util/src/stream/stream/fold.rs
index e109c3bdcf013ecf6ce3ac94e9cce96f782400a0..b8b55ecb678fcf20ffb8e20efb6bd1bd463a4bf5 100644
--- a/third_party/rust/futures-util/src/stream/stream/fold.rs
+++ b/third_party/rust/futures-util/src/stream/stream/fold.rs
@@ -35,24 +35,21 @@ where
 }
 
 impl<St, Fut, T, F> Fold<St, Fut, T, F>
-where St: Stream,
-      F: FnMut(T, St::Item) -> Fut,
-      Fut: Future<Output = T>,
+where
+    St: Stream,
+    F: FnMut(T, St::Item) -> Fut,
+    Fut: Future<Output = T>,
 {
     pub(super) fn new(stream: St, f: F, t: T) -> Self {
-        Self {
-            stream,
-            f,
-            accum: Some(t),
-            future: None,
-        }
+        Self { stream, f, accum: Some(t), future: None }
     }
 }
 
 impl<St, Fut, T, F> FusedFuture for Fold<St, Fut, T, F>
-    where St: Stream,
-          F: FnMut(T, St::Item) -> Fut,
-          Fut: Future<Output = T>,
+where
+    St: Stream,
+    F: FnMut(T, St::Item) -> Fut,
+    Fut: Future<Output = T>,
 {
     fn is_terminated(&self) -> bool {
         self.accum.is_none() && self.future.is_none()
@@ -60,9 +57,10 @@ impl<St, Fut, T, F> FusedFuture for Fold<St, Fut, T, F>
 }
 
 impl<St, Fut, T, F> Future for Fold<St, Fut, T, F>
-    where St: Stream,
-          F: FnMut(T, St::Item) -> Fut,
-          Fut: Future<Output = T>,
+where
+    St: Stream,
+    F: FnMut(T, St::Item) -> Fut,
+    Fut: Future<Output = T>,
 {
     type Output = T;
 
diff --git a/third_party/rust/futures-util/src/stream/stream/for_each.rs b/third_party/rust/futures-util/src/stream/stream/for_each.rs
index ee90e666108452f6fefc5b8d18fb22d6863f8494..5302b0e034d29f0cc0a1cf18ba38b7c467dd2a76 100644
--- a/third_party/rust/futures-util/src/stream/stream/for_each.rs
+++ b/third_party/rust/futures-util/src/stream/stream/for_each.rs
@@ -32,23 +32,21 @@ where
 }
 
 impl<St, Fut, F> ForEach<St, Fut, F>
-where St: Stream,
-      F: FnMut(St::Item) -> Fut,
-      Fut: Future<Output = ()>,
+where
+    St: Stream,
+    F: FnMut(St::Item) -> Fut,
+    Fut: Future<Output = ()>,
 {
     pub(super) fn new(stream: St, f: F) -> Self {
-        Self {
-            stream,
-            f,
-            future: None,
-        }
+        Self { stream, f, future: None }
     }
 }
 
 impl<St, Fut, F> FusedFuture for ForEach<St, Fut, F>
-    where St: FusedStream,
-          F: FnMut(St::Item) -> Fut,
-          Fut: Future<Output = ()>,
+where
+    St: FusedStream,
+    F: FnMut(St::Item) -> Fut,
+    Fut: Future<Output = ()>,
 {
     fn is_terminated(&self) -> bool {
         self.future.is_none() && self.stream.is_terminated()
@@ -56,9 +54,10 @@ impl<St, Fut, F> FusedFuture for ForEach<St, Fut, F>
 }
 
 impl<St, Fut, F> Future for ForEach<St, Fut, F>
-    where St: Stream,
-          F: FnMut(St::Item) -> Fut,
-          Fut: Future<Output = ()>,
+where
+    St: Stream,
+    F: FnMut(St::Item) -> Fut,
+    Fut: Future<Output = ()>,
 {
     type Output = ();
 
diff --git a/third_party/rust/futures-util/src/stream/stream/for_each_concurrent.rs b/third_party/rust/futures-util/src/stream/stream/for_each_concurrent.rs
index cee0ba197e0e1823394e3287a9bd5ae994ae9e5a..6c18753eb9a8a13398cbf475f35d4ddb6c412dbd 100644
--- a/third_party/rust/futures-util/src/stream/stream/for_each_concurrent.rs
+++ b/third_party/rust/futures-util/src/stream/stream/for_each_concurrent.rs
@@ -1,7 +1,7 @@
 use crate::stream::{FuturesUnordered, StreamExt};
 use core::fmt;
-use core::pin::Pin;
 use core::num::NonZeroUsize;
+use core::pin::Pin;
 use futures_core::future::{FusedFuture, Future};
 use futures_core::stream::Stream;
 use futures_core::task::{Context, Poll};
@@ -35,9 +35,10 @@ where
 }
 
 impl<St, Fut, F> ForEachConcurrent<St, Fut, F>
-where St: Stream,
-      F: FnMut(St::Item) -> Fut,
-      Fut: Future<Output = ()>,
+where
+    St: Stream,
+    F: FnMut(St::Item) -> Fut,
+    Fut: Future<Output = ()>,
 {
     pub(super) fn new(stream: St, limit: Option<usize>, f: F) -> Self {
         Self {
@@ -51,9 +52,10 @@ where St: Stream,
 }
 
 impl<St, Fut, F> FusedFuture for ForEachConcurrent<St, Fut, F>
-    where St: Stream,
-          F: FnMut(St::Item) -> Fut,
-          Fut: Future<Output = ()>,
+where
+    St: Stream,
+    F: FnMut(St::Item) -> Fut,
+    Fut: Future<Output = ()>,
 {
     fn is_terminated(&self) -> bool {
         self.stream.is_none() && self.futures.is_empty()
@@ -61,9 +63,10 @@ impl<St, Fut, F> FusedFuture for ForEachConcurrent<St, Fut, F>
 }
 
 impl<St, Fut, F> Future for ForEachConcurrent<St, Fut, F>
-    where St: Stream,
-          F: FnMut(St::Item) -> Fut,
-          Fut: Future<Output = ()>,
+where
+    St: Stream,
+    F: FnMut(St::Item) -> Fut,
+    Fut: Future<Output = ()>,
 {
     type Output = ();
 
@@ -80,7 +83,7 @@ impl<St, Fut, F> Future for ForEachConcurrent<St, Fut, F>
                         Poll::Ready(Some(elem)) => {
                             made_progress_this_iter = true;
                             Some(elem)
-                        },
+                        }
                         Poll::Ready(None) => {
                             stream_completed = true;
                             None
@@ -102,9 +105,9 @@ impl<St, Fut, F> Future for ForEachConcurrent<St, Fut, F>
                 Poll::Ready(Some(())) => made_progress_this_iter = true,
                 Poll::Ready(None) => {
                     if this.stream.is_none() {
-                        return Poll::Ready(())
+                        return Poll::Ready(());
                     }
-                },
+                }
                 Poll::Pending => {}
             }
 
diff --git a/third_party/rust/futures-util/src/stream/stream/forward.rs b/third_party/rust/futures-util/src/stream/stream/forward.rs
index 2247b21e97f4c1ce2c710f42fdda52562bdabf87..1fe24273aafb704127c54ef0cea96bf84bd8b37b 100644
--- a/third_party/rust/futures-util/src/stream/stream/forward.rs
+++ b/third_party/rust/futures-util/src/stream/stream/forward.rs
@@ -23,11 +23,7 @@ pin_project! {
 
 impl<St, Si, Item> Forward<St, Si, Item> {
     pub(crate) fn new(stream: St, sink: Si) -> Self {
-        Self {
-            sink: Some(sink),
-            stream: Fuse::new(stream),
-            buffered_item: None,
-        }
+        Self { sink: Some(sink), stream: Fuse::new(stream), buffered_item: None }
     }
 }
 
@@ -48,10 +44,7 @@ where
 {
     type Output = Result<(), E>;
 
-    fn poll(
-        self: Pin<&mut Self>,
-        cx: &mut Context<'_>,
-    ) -> Poll<Self::Output> {
+    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
         let ForwardProj { mut sink, mut stream, buffered_item } = self.project();
         let mut si = sink.as_mut().as_pin_mut().expect("polled `Forward` after completion");
 
@@ -70,11 +63,11 @@ where
                 Poll::Ready(None) => {
                     ready!(si.poll_close(cx))?;
                     sink.set(None);
-                    return Poll::Ready(Ok(()))
+                    return Poll::Ready(Ok(()));
                 }
                 Poll::Pending => {
                     ready!(si.poll_flush(cx))?;
-                    return Poll::Pending
+                    return Poll::Pending;
                 }
             }
         }
diff --git a/third_party/rust/futures-util/src/stream/stream/fuse.rs b/third_party/rust/futures-util/src/stream/stream/fuse.rs
index e1d8c122b39d0a7988eb1be919ba6e69ccf1fb96..fe67813e81f2d2093cb18eea164d36c6b731e4f1 100644
--- a/third_party/rust/futures-util/src/stream/stream/fuse.rs
+++ b/third_party/rust/futures-util/src/stream/stream/fuse.rs
@@ -43,10 +43,7 @@ impl<S: Stream> FusedStream for Fuse<S> {
 impl<S: Stream> Stream for Fuse<S> {
     type Item = S::Item;
 
-    fn poll_next(
-        self: Pin<&mut Self>,
-        cx: &mut Context<'_>,
-    ) -> Poll<Option<S::Item>> {
+    fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<S::Item>> {
         let this = self.project();
 
         if *this.done {
diff --git a/third_party/rust/futures-util/src/stream/stream/into_future.rs b/third_party/rust/futures-util/src/stream/stream/into_future.rs
index a9a1e2374a8320e28b8b17b59256cfab202f6ee3..8abfddcccda4948db9e3c37aafbbb2549fc6ed4f 100644
--- a/third_party/rust/futures-util/src/stream/stream/into_future.rs
+++ b/third_party/rust/futures-util/src/stream/stream/into_future.rs
@@ -79,10 +79,7 @@ impl<St: Stream + Unpin> FusedFuture for StreamFuture<St> {
 impl<St: Stream + Unpin> Future for StreamFuture<St> {
     type Output = (Option<St::Item>, St);
 
-    fn poll(
-        mut self: Pin<&mut Self>,
-        cx: &mut Context<'_>,
-    ) -> Poll<Self::Output> {
+    fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
         let item = {
             let s = self.stream.as_mut().expect("polling StreamFuture twice");
             ready!(s.poll_next_unpin(cx))
diff --git a/third_party/rust/futures-util/src/stream/stream/map.rs b/third_party/rust/futures-util/src/stream/stream/map.rs
index 1a269f0c30543eba552f8dcb72db9e441c49ea64..88bb6129d43e751c4c81d33f3c33449b53121e09 100644
--- a/third_party/rust/futures-util/src/stream/stream/map.rs
+++ b/third_party/rust/futures-util/src/stream/stream/map.rs
@@ -24,9 +24,7 @@ where
     St: fmt::Debug,
 {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.debug_struct("Map")
-            .field("stream", &self.stream)
-            .finish()
+        f.debug_struct("Map").field("stream", &self.stream).finish()
     }
 }
 
@@ -39,8 +37,9 @@ impl<St, F> Map<St, F> {
 }
 
 impl<St, F> FusedStream for Map<St, F>
-    where St: FusedStream,
-          F: FnMut1<St::Item>,
+where
+    St: FusedStream,
+    F: FnMut1<St::Item>,
 {
     fn is_terminated(&self) -> bool {
         self.stream.is_terminated()
@@ -48,15 +47,13 @@ impl<St, F> FusedStream for Map<St, F>
 }
 
 impl<St, F> Stream for Map<St, F>
-    where St: Stream,
-          F: FnMut1<St::Item>,
+where
+    St: Stream,
+    F: FnMut1<St::Item>,
 {
     type Item = F::Output;
 
-    fn poll_next(
-        self: Pin<&mut Self>,
-        cx: &mut Context<'_>,
-    ) -> Poll<Option<Self::Item>> {
+    fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
         let mut this = self.project();
         let res = ready!(this.stream.as_mut().poll_next(cx));
         Poll::Ready(res.map(|x| this.f.call_mut(x)))
@@ -70,8 +67,9 @@ impl<St, F> Stream for Map<St, F>
 // Forwarding impl of Sink from the underlying stream
 #[cfg(feature = "sink")]
 impl<St, F, Item> Sink<Item> for Map<St, F>
-    where St: Stream + Sink<Item>,
-          F: FnMut1<St::Item>,
+where
+    St: Stream + Sink<Item>,
+    F: FnMut1<St::Item>,
 {
     type Error = St::Error;
 
diff --git a/third_party/rust/futures-util/src/stream/stream/mod.rs b/third_party/rust/futures-util/src/stream/stream/mod.rs
index b1b4384279ba5da1bb50a2b660efa24560a4477c..9089e6e3df812134c04d2eb63b58d650c3fd7635 100644
--- a/third_party/rust/futures-util/src/stream/stream/mod.rs
+++ b/third_party/rust/futures-util/src/stream/stream/mod.rs
@@ -4,8 +4,11 @@
 //! including the `StreamExt` trait which adds methods to `Stream` types.
 
 use crate::future::{assert_future, Either};
+use crate::stream::assert_stream;
 #[cfg(feature = "alloc")]
 use alloc::boxed::Box;
+#[cfg(feature = "alloc")]
+use alloc::vec::Vec;
 use core::pin::Pin;
 #[cfg(feature = "sink")]
 use futures_core::stream::TryStream;
@@ -19,7 +22,7 @@ use futures_core::{
 #[cfg(feature = "sink")]
 use futures_sink::Sink;
 
-use crate::fns::{InspectFn, inspect_fn};
+use crate::fns::{inspect_fn, InspectFn};
 
 mod chain;
 #[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411
@@ -120,7 +123,7 @@ pub use self::select_next_some::SelectNextSome;
 
 mod peek;
 #[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411
-pub use self::peek::{Peek, Peekable};
+pub use self::peek::{NextIf, NextIfEq, Peek, Peekable};
 
 mod skip;
 #[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411
@@ -201,7 +204,6 @@ mod catch_unwind;
 #[cfg(feature = "std")]
 #[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411
 pub use self::catch_unwind::CatchUnwind;
-use crate::stream::assert_stream;
 
 impl<T: ?Sized> StreamExt for T where T: Stream {}
 
@@ -689,7 +691,7 @@ pub trait StreamExt: Stream {
         U: Stream,
         Self: Sized,
     {
-        FlatMap::new(self, f)
+        assert_stream::<U::Item, _>(FlatMap::new(self, f))
     }
 
     /// Combinator similar to [`StreamExt::fold`] that holds internal state
@@ -722,7 +724,7 @@ pub trait StreamExt: Stream {
         Fut: Future<Output = Option<B>>,
         Self: Sized,
     {
-        Scan::new(self, initial_state, f)
+        assert_stream::<B, _>(Scan::new(self, initial_state, f))
     }
 
     /// Skip elements on this stream while the provided asynchronous predicate
@@ -793,7 +795,7 @@ pub trait StreamExt: Stream {
     /// this stream combinator will always return that the stream is done.
     ///
     /// The stopping future may return any type. Once the stream is stopped
-    /// the result of the stopping future may be aceessed with `TakeUntil::take_result()`.
+    /// the result of the stopping future may be accessed with `TakeUntil::take_result()`.
     /// The stream may also be resumed with `TakeUntil::take_future()`.
     /// See the documentation of [`TakeUntil`] for more information.
     ///
@@ -827,7 +829,7 @@ pub trait StreamExt: Stream {
         Fut: Future,
         Self: Sized,
     {
-        TakeUntil::new(self, fut)
+        assert_stream::<Self::Item, _>(TakeUntil::new(self, fut))
     }
 
     /// Runs this stream to completion, executing the provided asynchronous
@@ -917,7 +919,7 @@ pub trait StreamExt: Stream {
     /// fut.await;
     /// # })
     /// ```
-    #[cfg_attr(feature = "cfg-target-has-atomic", cfg(target_has_atomic = "ptr"))]
+    #[cfg(not(futures_no_atomic_cas))]
     #[cfg(feature = "alloc")]
     fn for_each_concurrent<Fut, F>(
         self,
@@ -1140,7 +1142,7 @@ pub trait StreamExt: Stream {
     ///
     /// This method is only available when the `std` or `alloc` feature of this
     /// library is activated, and it is activated by default.
-    #[cfg_attr(feature = "cfg-target-has-atomic", cfg(target_has_atomic = "ptr"))]
+    #[cfg(not(futures_no_atomic_cas))]
     #[cfg(feature = "alloc")]
     fn buffered(self, n: usize) -> Buffered<Self>
     where
@@ -1185,7 +1187,7 @@ pub trait StreamExt: Stream {
     /// assert_eq!(buffered.next().await, None);
     /// # Ok::<(), i32>(()) }).unwrap();
     /// ```
-    #[cfg_attr(feature = "cfg-target-has-atomic", cfg(target_has_atomic = "ptr"))]
+    #[cfg(not(futures_no_atomic_cas))]
     #[cfg(feature = "alloc")]
     fn buffer_unordered(self, n: usize) -> BufferUnordered<Self>
     where
@@ -1289,7 +1291,7 @@ pub trait StreamExt: Stream {
     where
         Self: Sized,
     {
-        assert_stream::<alloc::vec::Vec<Self::Item>, _>(Chunks::new(self, capacity))
+        assert_stream::<Vec<Self::Item>, _>(Chunks::new(self, capacity))
     }
 
     /// An adaptor for chunking up ready items of the stream inside a vector.
@@ -1312,10 +1314,10 @@ pub trait StreamExt: Stream {
     /// This method will panic if `capacity` is zero.
     #[cfg(feature = "alloc")]
     fn ready_chunks(self, capacity: usize) -> ReadyChunks<Self>
-        where
-            Self: Sized,
+    where
+        Self: Sized,
     {
-        ReadyChunks::new(self, capacity)
+        assert_stream::<Vec<Self::Item>, _>(ReadyChunks::new(self, capacity))
     }
 
     /// A future that completes after the given stream has been fully processed
@@ -1327,14 +1329,18 @@ pub trait StreamExt: Stream {
     /// the sink is closed. Note that neither the original stream nor provided
     /// sink will be output by this future. Pass the sink by `Pin<&mut S>`
     /// (for example, via `forward(&mut sink)` inside an `async` fn/block) in
-    /// order to preserve access to the `Sink`.
+    /// order to preserve access to the `Sink`. If the stream produces an error,
+    /// that error will be returned by this future without flushing/closing the sink.
     #[cfg(feature = "sink")]
     #[cfg_attr(docsrs, doc(cfg(feature = "sink")))]
     fn forward<S>(self, sink: S) -> Forward<Self, S>
     where
         S: Sink<Self::Ok, Error = Self::Error>,
         Self: TryStream + Sized,
+        // Self: TryStream + Sized + Stream<Item = Result<<Self as TryStream>::Ok, <Self as TryStream>::Error>>,
     {
+        // TODO: type mismatch resolving `<Self as futures_core::Stream>::Item == std::result::Result<<Self as futures_core::TryStream>::Ok, <Self as futures_core::TryStream>::Error>`
+        // assert_future::<Result<(), Self::Error>, _>(Forward::new(self, sink))
         Forward::new(self, sink)
     }
 
@@ -1349,14 +1355,17 @@ pub trait StreamExt: Stream {
     /// library is activated, and it is activated by default.
     #[cfg(feature = "sink")]
     #[cfg_attr(docsrs, doc(cfg(feature = "sink")))]
-    #[cfg_attr(feature = "cfg-target-has-atomic", cfg(target_has_atomic = "ptr"))]
+    #[cfg(not(futures_no_atomic_cas))]
     #[cfg(feature = "alloc")]
     fn split<Item>(self) -> (SplitSink<Self, Item>, SplitStream<Self>)
     where
         Self: Sink<Item> + Sized,
     {
         let (sink, stream) = split::split(self);
-        (sink, assert_stream::<Self::Item, _>(stream))
+        (
+            crate::sink::assert_sink::<Item, Self::Error, _>(sink),
+            assert_stream::<Self::Item, _>(stream),
+        )
     }
 
     /// Do something with each item of this stream, afterwards passing it on.
@@ -1459,6 +1468,6 @@ pub trait StreamExt: Stream {
     where
         Self: Unpin + FusedStream,
     {
-        SelectNextSome::new(self)
+        assert_future::<Self::Item, _>(SelectNextSome::new(self))
     }
 }
diff --git a/third_party/rust/futures-util/src/stream/stream/next.rs b/third_party/rust/futures-util/src/stream/stream/next.rs
index 6949878bef7155c932a8910f0461e8eecd94a0a8..8d8347aa03392d5bc29e726d0769ad8e1265f791 100644
--- a/third_party/rust/futures-util/src/stream/stream/next.rs
+++ b/third_party/rust/futures-util/src/stream/stream/next.rs
@@ -28,10 +28,7 @@ impl<St: ?Sized + FusedStream + Unpin> FusedFuture for Next<'_, St> {
 impl<St: ?Sized + Stream + Unpin> Future for Next<'_, St> {
     type Output = Option<St::Item>;
 
-    fn poll(
-        mut self: Pin<&mut Self>,
-        cx: &mut Context<'_>,
-    ) -> Poll<Self::Output> {
+    fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
         self.stream.poll_next_unpin(cx)
     }
 }
diff --git a/third_party/rust/futures-util/src/stream/stream/peek.rs b/third_party/rust/futures-util/src/stream/stream/peek.rs
index a4031102ab38dc5f71498e4d9d28880d807edcb8..217fabaa6eab102634ac1b7d40623e206052626d 100644
--- a/third_party/rust/futures-util/src/stream/stream/peek.rs
+++ b/third_party/rust/futures-util/src/stream/stream/peek.rs
@@ -1,5 +1,7 @@
+use crate::fns::FnOnce1;
 use crate::stream::{Fuse, StreamExt};
 use core::fmt;
+use core::marker::PhantomData;
 use core::pin::Pin;
 use futures_core::future::{FusedFuture, Future};
 use futures_core::ready;
@@ -26,10 +28,7 @@ pin_project! {
 
 impl<St: Stream> Peekable<St> {
     pub(super) fn new(stream: St) -> Self {
-        Self {
-            stream: stream.fuse(),
-            peeked: None,
-        }
+        Self { stream: stream.fuse(), peeked: None }
     }
 
     delegate_access_inner!(stream, St, (.));
@@ -44,10 +43,7 @@ impl<St: Stream> Peekable<St> {
     ///
     /// This method polls the underlying stream and return either a reference
     /// to the next item if the stream is ready or passes through any errors.
-    pub fn poll_peek(
-        self: Pin<&mut Self>,
-        cx: &mut Context<'_>,
-    ) -> Poll<Option<&St::Item>> {
+    pub fn poll_peek(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<&St::Item>> {
         let mut this = self.project();
 
         Poll::Ready(loop {
@@ -60,6 +56,86 @@ impl<St: Stream> Peekable<St> {
             }
         })
     }
+
+    /// Creates a future which will consume and return the next value of this
+    /// stream if a condition is true.
+    ///
+    /// If `func` returns `true` for the next value of this stream, consume and
+    /// return it. Otherwise, return `None`.
+    ///
+    /// # Examples
+    ///
+    /// Consume a number if it's equal to 0.
+    ///
+    /// ```
+    /// # futures::executor::block_on(async {
+    /// use futures::stream::{self, StreamExt};
+    /// use futures::pin_mut;
+    ///
+    /// let stream = stream::iter(0..5).peekable();
+    /// pin_mut!(stream);
+    /// // The first item of the stream is 0; consume it.
+    /// assert_eq!(stream.as_mut().next_if(|&x| x == 0).await, Some(0));
+    /// // The next item returned is now 1, so `consume` will return `false`.
+    /// assert_eq!(stream.as_mut().next_if(|&x| x == 0).await, None);
+    /// // `next_if` saves the value of the next item if it was not equal to `expected`.
+    /// assert_eq!(stream.next().await, Some(1));
+    /// # });
+    /// ```
+    ///
+    /// Consume any number less than 10.
+    ///
+    /// ```
+    /// # futures::executor::block_on(async {
+    /// use futures::stream::{self, StreamExt};
+    /// use futures::pin_mut;
+    ///
+    /// let stream = stream::iter(1..20).peekable();
+    /// pin_mut!(stream);
+    /// // Consume all numbers less than 10
+    /// while stream.as_mut().next_if(|&x| x < 10).await.is_some() {}
+    /// // The next value returned will be 10
+    /// assert_eq!(stream.next().await, Some(10));
+    /// # });
+    /// ```
+    pub fn next_if<F>(self: Pin<&mut Self>, func: F) -> NextIf<'_, St, F>
+    where
+        F: FnOnce(&St::Item) -> bool,
+    {
+        NextIf { inner: Some((self, func)) }
+    }
+
+    /// Creates a future which will consume and return the next item if it is
+    /// equal to `expected`.
+    ///
+    /// # Example
+    ///
+    /// Consume a number if it's equal to 0.
+    ///
+    /// ```
+    /// # futures::executor::block_on(async {
+    /// use futures::stream::{self, StreamExt};
+    /// use futures::pin_mut;
+    ///
+    /// let stream = stream::iter(0..5).peekable();
+    /// pin_mut!(stream);
+    /// // The first item of the stream is 0; consume it.
+    /// assert_eq!(stream.as_mut().next_if_eq(&0).await, Some(0));
+    /// // The next item returned is now 1, so `consume` will return `false`.
+    /// assert_eq!(stream.as_mut().next_if_eq(&0).await, None);
+    /// // `next_if_eq` saves the value of the next item if it was not equal to `expected`.
+    /// assert_eq!(stream.next().await, Some(1));
+    /// # });
+    /// ```
+    pub fn next_if_eq<'a, T>(self: Pin<&'a mut Self>, expected: &'a T) -> NextIfEq<'a, St, T>
+    where
+        T: ?Sized,
+        St::Item: PartialEq<T>,
+    {
+        NextIfEq {
+            inner: NextIf { inner: Some((self, NextIfEqFn { expected, _next: PhantomData })) },
+        }
+    }
 }
 
 impl<St: Stream> FusedStream for Peekable<St> {
@@ -103,7 +179,7 @@ where
 }
 
 pin_project! {
-    /// Future for the [`Peekable::peek()`](self::Peekable::peek) function from [`Peekable`]
+    /// Future for the [`Peekable::peek`](self::Peekable::peek) method.
     #[must_use = "futures do nothing unless polled"]
     pub struct Peek<'a, St: Stream> {
         inner: Option<Pin<&'a mut Peekable<St>>>,
@@ -116,9 +192,7 @@ where
     St::Item: fmt::Debug,
 {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.debug_struct("Peek")
-            .field("inner", &self.inner)
-            .finish()
+        f.debug_struct("Peek").field("inner", &self.inner).finish()
     }
 }
 
@@ -133,6 +207,7 @@ where
     St: Stream,
 {
     type Output = Option<&'a St::Item>;
+
     fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
         let inner = self.project().inner;
         if let Some(peekable) = inner {
@@ -144,3 +219,125 @@ where
         }
     }
 }
+
+pin_project! {
+    /// Future for the [`Peekable::next_if`](self::Peekable::next_if) method.
+    #[must_use = "futures do nothing unless polled"]
+    pub struct NextIf<'a, St: Stream, F> {
+        inner: Option<(Pin<&'a mut Peekable<St>>, F)>,
+    }
+}
+
+impl<St, F> fmt::Debug for NextIf<'_, St, F>
+where
+    St: Stream + fmt::Debug,
+    St::Item: fmt::Debug,
+{
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        f.debug_struct("NextIf").field("inner", &self.inner.as_ref().map(|(s, _f)| s)).finish()
+    }
+}
+
+#[allow(single_use_lifetimes)] // https://github.com/rust-lang/rust/issues/55058
+impl<St, F> FusedFuture for NextIf<'_, St, F>
+where
+    St: Stream,
+    F: for<'a> FnOnce1<&'a St::Item, Output = bool>,
+{
+    fn is_terminated(&self) -> bool {
+        self.inner.is_none()
+    }
+}
+
+#[allow(single_use_lifetimes)] // https://github.com/rust-lang/rust/issues/55058
+impl<St, F> Future for NextIf<'_, St, F>
+where
+    St: Stream,
+    F: for<'a> FnOnce1<&'a St::Item, Output = bool>,
+{
+    type Output = Option<St::Item>;
+
+    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
+        let inner = self.project().inner;
+        if let Some((peekable, _)) = inner {
+            let res = ready!(peekable.as_mut().poll_next(cx));
+
+            let (peekable, func) = inner.take().unwrap();
+            match res {
+                Some(ref matched) if func.call_once(matched) => Poll::Ready(res),
+                other => {
+                    let peekable = peekable.project();
+                    // Since we called `self.next()`, we consumed `self.peeked`.
+                    assert!(peekable.peeked.is_none());
+                    *peekable.peeked = other;
+                    Poll::Ready(None)
+                }
+            }
+        } else {
+            panic!("NextIf polled after completion")
+        }
+    }
+}
+
+pin_project! {
+    /// Future for the [`Peekable::next_if_eq`](self::Peekable::next_if_eq) method.
+    #[must_use = "futures do nothing unless polled"]
+    pub struct NextIfEq<'a, St: Stream, T: ?Sized> {
+        #[pin]
+        inner: NextIf<'a, St, NextIfEqFn<'a, T, St::Item>>,
+    }
+}
+
+impl<St, T> fmt::Debug for NextIfEq<'_, St, T>
+where
+    St: Stream + fmt::Debug,
+    St::Item: fmt::Debug,
+    T: ?Sized,
+{
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        f.debug_struct("NextIfEq")
+            .field("inner", &self.inner.inner.as_ref().map(|(s, _f)| s))
+            .finish()
+    }
+}
+
+impl<St, T> FusedFuture for NextIfEq<'_, St, T>
+where
+    St: Stream,
+    T: ?Sized,
+    St::Item: PartialEq<T>,
+{
+    fn is_terminated(&self) -> bool {
+        self.inner.is_terminated()
+    }
+}
+
+impl<St, T> Future for NextIfEq<'_, St, T>
+where
+    St: Stream,
+    T: ?Sized,
+    St::Item: PartialEq<T>,
+{
+    type Output = Option<St::Item>;
+
+    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
+        self.project().inner.poll(cx)
+    }
+}
+
+struct NextIfEqFn<'a, T: ?Sized, Item> {
+    expected: &'a T,
+    _next: PhantomData<Item>,
+}
+
+impl<T, Item> FnOnce1<&Item> for NextIfEqFn<'_, T, Item>
+where
+    T: ?Sized,
+    Item: PartialEq<T>,
+{
+    type Output = bool;
+
+    fn call_once(self, next: &Item) -> Self::Output {
+        next == self.expected
+    }
+}
diff --git a/third_party/rust/futures-util/src/stream/stream/ready_chunks.rs b/third_party/rust/futures-util/src/stream/stream/ready_chunks.rs
index b6e3e5c2de1c713f9d02b59bb1b0928f21ff7152..5ebc9582dbd1df174ec768cbe69c21c72de96fde 100644
--- a/third_party/rust/futures-util/src/stream/stream/ready_chunks.rs
+++ b/third_party/rust/futures-util/src/stream/stream/ready_chunks.rs
@@ -1,12 +1,12 @@
 use crate::stream::Fuse;
-use futures_core::stream::{Stream, FusedStream};
+use alloc::vec::Vec;
+use core::mem;
+use core::pin::Pin;
+use futures_core::stream::{FusedStream, Stream};
 use futures_core::task::{Context, Poll};
 #[cfg(feature = "sink")]
 use futures_sink::Sink;
 use pin_project_lite::pin_project;
-use core::mem;
-use core::pin::Pin;
-use alloc::vec::Vec;
 
 pin_project! {
     /// Stream for the [`ready_chunks`](super::StreamExt::ready_chunks) method.
@@ -20,7 +20,10 @@ pin_project! {
     }
 }
 
-impl<St: Stream> ReadyChunks<St> where St: Stream {
+impl<St: Stream> ReadyChunks<St>
+where
+    St: Stream,
+{
     pub(super) fn new(stream: St, capacity: usize) -> Self {
         assert!(capacity > 0);
 
@@ -37,10 +40,7 @@ impl<St: Stream> ReadyChunks<St> where St: Stream {
 impl<St: Stream> Stream for ReadyChunks<St> {
     type Item = Vec<St::Item>;
 
-    fn poll_next(
-        self: Pin<&mut Self>,
-        cx: &mut Context<'_>,
-    ) -> Poll<Option<Self::Item>> {
+    fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
         let mut this = self.project();
 
         loop {
@@ -61,7 +61,10 @@ impl<St: Stream> Stream for ReadyChunks<St> {
                 Poll::Ready(Some(item)) => {
                     this.items.push(item);
                     if this.items.len() >= *this.cap {
-                        return Poll::Ready(Some(mem::replace(this.items, Vec::with_capacity(*this.cap))))
+                        return Poll::Ready(Some(mem::replace(
+                            this.items,
+                            Vec::with_capacity(*this.cap),
+                        )));
                     }
                 }
 
diff --git a/third_party/rust/futures-util/src/stream/stream/scan.rs b/third_party/rust/futures-util/src/stream/stream/scan.rs
index 20972807ce74d0a64a87a4abbdb128b726319f02..8724145ef30bdac83157514156cf55a0e30c1482 100644
--- a/third_party/rust/futures-util/src/stream/stream/scan.rs
+++ b/third_party/rust/futures-util/src/stream/stream/scan.rs
@@ -56,14 +56,7 @@ where
     Fut: Future<Output = Option<B>>,
 {
     pub(super) fn new(stream: St, initial_state: S, f: F) -> Self {
-        Self {
-            stream,
-            state_f: Some(StateFn {
-                state: initial_state,
-                f,
-            }),
-            future: None,
-        }
+        Self { stream, state_f: Some(StateFn { state: initial_state, f }), future: None }
     }
 
     delegate_access_inner!(stream, St, ());
diff --git a/third_party/rust/futures-util/src/stream/stream/select_next_some.rs b/third_party/rust/futures-util/src/stream/stream/select_next_some.rs
index fe7a089899dd2106664522339112cdbfc8a633d1..3115e14d9a5598ab8cb214a26213e45d568c8b57 100644
--- a/third_party/rust/futures-util/src/stream/stream/select_next_some.rs
+++ b/third_party/rust/futures-util/src/stream/stream/select_next_some.rs
@@ -1,9 +1,9 @@
+use crate::stream::StreamExt;
 use core::pin::Pin;
+use futures_core::future::{FusedFuture, Future};
 use futures_core::ready;
 use futures_core::stream::FusedStream;
-use futures_core::future::{Future, FusedFuture};
 use futures_core::task::{Context, Poll};
-use crate::stream::StreamExt;
 
 /// Future for the [`select_next_some`](super::StreamExt::select_next_some)
 /// method.
diff --git a/third_party/rust/futures-util/src/stream/stream/skip.rs b/third_party/rust/futures-util/src/stream/stream/skip.rs
index 6ffcf57d778464f33b23bd9fe492a8d3693b70bc..f4957795212de83de2c96bda7dd95d09374e648e 100644
--- a/third_party/rust/futures-util/src/stream/stream/skip.rs
+++ b/third_party/rust/futures-util/src/stream/stream/skip.rs
@@ -19,10 +19,7 @@ pin_project! {
 
 impl<St: Stream> Skip<St> {
     pub(super) fn new(stream: St, n: usize) -> Self {
-        Self {
-            stream,
-            remaining: n,
-        }
+        Self { stream, remaining: n }
     }
 
     delegate_access_inner!(stream, St, ());
@@ -37,10 +34,7 @@ impl<St: FusedStream> FusedStream for Skip<St> {
 impl<St: Stream> Stream for Skip<St> {
     type Item = St::Item;
 
-    fn poll_next(
-        self: Pin<&mut Self>,
-        cx: &mut Context<'_>,
-    ) -> Poll<Option<St::Item>> {
+    fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<St::Item>> {
         let mut this = self.project();
 
         while *this.remaining > 0 {
@@ -57,11 +51,8 @@ impl<St: Stream> Stream for Skip<St> {
     fn size_hint(&self) -> (usize, Option<usize>) {
         let (lower, upper) = self.stream.size_hint();
 
-        let lower = lower.saturating_sub(self.remaining as usize);
-        let upper = match upper {
-            Some(x) => Some(x.saturating_sub(self.remaining as usize)),
-            None => None,
-        };
+        let lower = lower.saturating_sub(self.remaining);
+        let upper = upper.map(|x| x.saturating_sub(self.remaining));
 
         (lower, upper)
     }
diff --git a/third_party/rust/futures-util/src/stream/stream/skip_while.rs b/third_party/rust/futures-util/src/stream/stream/skip_while.rs
index e1aa3f904b71b3de2020d562b45719e2415bb615..50a21a21ae5e1a086f6e39077d07cc38f9b43198 100644
--- a/third_party/rust/futures-util/src/stream/stream/skip_while.rs
+++ b/third_party/rust/futures-util/src/stream/stream/skip_while.rs
@@ -39,27 +39,23 @@ where
 }
 
 impl<St, Fut, F> SkipWhile<St, Fut, F>
-    where St: Stream,
-          F: FnMut(&St::Item) -> Fut,
-          Fut: Future<Output = bool>,
+where
+    St: Stream,
+    F: FnMut(&St::Item) -> Fut,
+    Fut: Future<Output = bool>,
 {
     pub(super) fn new(stream: St, f: F) -> Self {
-        Self {
-            stream,
-            f,
-            pending_fut: None,
-            pending_item: None,
-            done_skipping: false,
-        }
+        Self { stream, f, pending_fut: None, pending_item: None, done_skipping: false }
     }
 
     delegate_access_inner!(stream, St, ());
 }
 
 impl<St, Fut, F> FusedStream for SkipWhile<St, Fut, F>
-    where St: FusedStream,
-          F: FnMut(&St::Item) -> Fut,
-          Fut: Future<Output = bool>,
+where
+    St: FusedStream,
+    F: FnMut(&St::Item) -> Fut,
+    Fut: Future<Output = bool>,
 {
     fn is_terminated(&self) -> bool {
         self.pending_item.is_none() && self.stream.is_terminated()
@@ -67,16 +63,14 @@ impl<St, Fut, F> FusedStream for SkipWhile<St, Fut, F>
 }
 
 impl<St, Fut, F> Stream for SkipWhile<St, Fut, F>
-    where St: Stream,
-          F: FnMut(&St::Item) -> Fut,
-          Fut: Future<Output = bool>,
+where
+    St: Stream,
+    F: FnMut(&St::Item) -> Fut,
+    Fut: Future<Output = bool>,
 {
     type Item = St::Item;
 
-    fn poll_next(
-        self: Pin<&mut Self>,
-        cx: &mut Context<'_>,
-    ) -> Poll<Option<St::Item>> {
+    fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<St::Item>> {
         let mut this = self.project();
 
         if *this.done_skipping {
@@ -119,9 +113,10 @@ impl<St, Fut, F> Stream for SkipWhile<St, Fut, F>
 // Forwarding impl of Sink from the underlying stream
 #[cfg(feature = "sink")]
 impl<S, Fut, F, Item> Sink<Item> for SkipWhile<S, Fut, F>
-    where S: Stream + Sink<Item>,
-          F: FnMut(&S::Item) -> Fut,
-          Fut: Future<Output = bool>,
+where
+    S: Stream + Sink<Item>,
+    F: FnMut(&S::Item) -> Fut,
+    Fut: Future<Output = bool>,
 {
     type Error = S::Error;
 
diff --git a/third_party/rust/futures-util/src/stream/stream/split.rs b/third_party/rust/futures-util/src/stream/stream/split.rs
index 997b9747a2d183d76ca0f098799502aee956127f..3a72fee30b698b37754733ede9f26deb2b06b3f4 100644
--- a/third_party/rust/futures-util/src/stream/stream/split.rs
+++ b/third_party/rust/futures-util/src/stream/stream/split.rs
@@ -1,9 +1,9 @@
+use core::fmt;
+use core::pin::Pin;
 use futures_core::ready;
 use futures_core::stream::Stream;
 use futures_core::task::{Context, Poll};
 use futures_sink::Sink;
-use core::fmt;
-use core::pin::Pin;
 
 use crate::lock::BiLock;
 
@@ -20,7 +20,8 @@ impl<S: Unpin> SplitStream<S> {
     /// together. Succeeds only if the `SplitStream<S>` and `SplitSink<S>` are
     /// a matching pair originating from the same call to `StreamExt::split`.
     pub fn reunite<Item>(self, other: SplitSink<S, Item>) -> Result<S, ReuniteError<S, Item>>
-        where S: Sink<Item>,
+    where
+        S: Sink<Item>,
     {
         other.reunite(self)
     }
@@ -36,10 +37,7 @@ impl<S: Stream> Stream for SplitStream<S> {
 
 #[allow(bad_style)]
 fn SplitSink<S: Sink<Item>, Item>(lock: BiLock<S>) -> SplitSink<S, Item> {
-    SplitSink {
-        lock,
-        slot: None,
-    }
+    SplitSink { lock, slot: None }
 }
 
 /// A `Sink` part of the split pair
@@ -58,14 +56,16 @@ impl<S: Sink<Item> + Unpin, Item> SplitSink<S, Item> {
     /// together. Succeeds only if the `SplitStream<S>` and `SplitSink<S>` are
     /// a matching pair originating from the same call to `StreamExt::split`.
     pub fn reunite(self, other: SplitStream<S>) -> Result<S, ReuniteError<S, Item>> {
-        self.lock.reunite(other.0).map_err(|err| {
-            ReuniteError(SplitSink(err.0), SplitStream(err.1))
-        })
+        self.lock.reunite(other.0).map_err(|err| ReuniteError(SplitSink(err.0), SplitStream(err.1)))
     }
 }
 
 impl<S: Sink<Item>, Item> SplitSink<S, Item> {
-    fn poll_flush_slot(mut inner: Pin<&mut S>, slot: &mut Option<Item>, cx: &mut Context<'_>) -> Poll<Result<(), S::Error>> {
+    fn poll_flush_slot(
+        mut inner: Pin<&mut S>,
+        slot: &mut Option<Item>,
+        cx: &mut Context<'_>,
+    ) -> Poll<Result<(), S::Error>> {
         if slot.is_some() {
             ready!(inner.as_mut().poll_ready(cx))?;
             Poll::Ready(inner.start_send(slot.take().unwrap()))
@@ -74,7 +74,10 @@ impl<S: Sink<Item>, Item> SplitSink<S, Item> {
         }
     }
 
-    fn poll_lock_and_flush_slot(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), S::Error>> {
+    fn poll_lock_and_flush_slot(
+        mut self: Pin<&mut Self>,
+        cx: &mut Context<'_>,
+    ) -> Poll<Result<(), S::Error>> {
         let this = &mut *self;
         let mut inner = ready!(this.lock.poll_lock(cx));
         Self::poll_flush_slot(inner.as_pin_mut(), &mut this.slot, cx)
@@ -127,9 +130,7 @@ pub struct ReuniteError<T, Item>(pub SplitSink<T, Item>, pub SplitStream<T>);
 
 impl<T, Item> fmt::Debug for ReuniteError<T, Item> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.debug_tuple("ReuniteError")
-            .field(&"...")
-            .finish()
+        f.debug_tuple("ReuniteError").field(&"...").finish()
     }
 }
 
diff --git a/third_party/rust/futures-util/src/stream/stream/take.rs b/third_party/rust/futures-util/src/stream/stream/take.rs
index 124d397c460a4b7aa1fab668bb3815805470b8fd..b1c728e3335acbf87de472c0dbaa5c1aadbd84f2 100644
--- a/third_party/rust/futures-util/src/stream/stream/take.rs
+++ b/third_party/rust/futures-util/src/stream/stream/take.rs
@@ -1,7 +1,7 @@
 use core::cmp;
 use core::pin::Pin;
 use futures_core::ready;
-use futures_core::stream::{Stream, FusedStream};
+use futures_core::stream::{FusedStream, Stream};
 use futures_core::task::{Context, Poll};
 #[cfg(feature = "sink")]
 use futures_sink::Sink;
@@ -20,24 +20,19 @@ pin_project! {
 
 impl<St: Stream> Take<St> {
     pub(super) fn new(stream: St, n: usize) -> Self {
-        Self {
-            stream,
-            remaining: n,
-        }
+        Self { stream, remaining: n }
     }
 
     delegate_access_inner!(stream, St, ());
 }
 
 impl<St> Stream for Take<St>
-    where St: Stream,
+where
+    St: Stream,
 {
     type Item = St::Item;
 
-    fn poll_next(
-        self: Pin<&mut Self>,
-        cx: &mut Context<'_>,
-    ) -> Poll<Option<St::Item>> {
+    fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<St::Item>> {
         if self.remaining == 0 {
             Poll::Ready(None)
         } else {
@@ -63,7 +58,7 @@ impl<St> Stream for Take<St>
 
         let upper = match upper {
             Some(x) if x < self.remaining as usize => Some(x),
-            _ => Some(self.remaining as usize)
+            _ => Some(self.remaining as usize),
         };
 
         (lower, upper)
@@ -71,7 +66,8 @@ impl<St> Stream for Take<St>
 }
 
 impl<St> FusedStream for Take<St>
-    where St: FusedStream,
+where
+    St: FusedStream,
 {
     fn is_terminated(&self) -> bool {
         self.remaining == 0 || self.stream.is_terminated()
@@ -81,7 +77,8 @@ impl<St> FusedStream for Take<St>
 // Forwarding impl of Sink from the underlying stream
 #[cfg(feature = "sink")]
 impl<S, Item> Sink<Item> for Take<S>
-    where S: Stream + Sink<Item>,
+where
+    S: Stream + Sink<Item>,
 {
     type Error = S::Error;
 
diff --git a/third_party/rust/futures-util/src/stream/stream/take_until.rs b/third_party/rust/futures-util/src/stream/stream/take_until.rs
index 4dea01aae99ae4f0d533ab18ebb12593ce150e6d..d14f9ce100be0730b2f35d5d39c51d8f6000e8b8 100644
--- a/third_party/rust/futures-util/src/stream/stream/take_until.rs
+++ b/third_party/rust/futures-util/src/stream/stream/take_until.rs
@@ -34,10 +34,7 @@ where
     Fut: Future + fmt::Debug,
 {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.debug_struct("TakeUntil")
-            .field("stream", &self.stream)
-            .field("fut", &self.fut)
-            .finish()
+        f.debug_struct("TakeUntil").field("stream", &self.stream).field("fut", &self.fut).finish()
     }
 }
 
@@ -47,12 +44,7 @@ where
     Fut: Future,
 {
     pub(super) fn new(stream: St, fut: Fut) -> Self {
-        Self {
-            stream,
-            fut: Some(fut),
-            fut_result: None,
-            free: false,
-        }
+        Self { stream, fut: Some(fut), fut_result: None, free: false }
     }
 
     delegate_access_inner!(stream, St, ());
diff --git a/third_party/rust/futures-util/src/stream/stream/take_while.rs b/third_party/rust/futures-util/src/stream/stream/take_while.rs
index 4cdba8356470aa2beefaedd121b2e50b26a9682c..01b27654b87cf1f971fac321d7afecb1c1068a90 100644
--- a/third_party/rust/futures-util/src/stream/stream/take_while.rs
+++ b/third_party/rust/futures-util/src/stream/stream/take_while.rs
@@ -2,7 +2,7 @@ use core::fmt;
 use core::pin::Pin;
 use futures_core::future::Future;
 use futures_core::ready;
-use futures_core::stream::{Stream, FusedStream};
+use futures_core::stream::{FusedStream, Stream};
 use futures_core::task::{Context, Poll};
 #[cfg(feature = "sink")]
 use futures_sink::Sink;
@@ -39,34 +39,27 @@ where
 }
 
 impl<St, Fut, F> TakeWhile<St, Fut, F>
-    where St: Stream,
-          F: FnMut(&St::Item) -> Fut,
-          Fut: Future<Output = bool>,
+where
+    St: Stream,
+    F: FnMut(&St::Item) -> Fut,
+    Fut: Future<Output = bool>,
 {
     pub(super) fn new(stream: St, f: F) -> Self {
-        Self {
-            stream,
-            f,
-            pending_fut: None,
-            pending_item: None,
-            done_taking: false,
-        }
+        Self { stream, f, pending_fut: None, pending_item: None, done_taking: false }
     }
 
     delegate_access_inner!(stream, St, ());
 }
 
 impl<St, Fut, F> Stream for TakeWhile<St, Fut, F>
-    where St: Stream,
-          F: FnMut(&St::Item) -> Fut,
-          Fut: Future<Output = bool>,
+where
+    St: Stream,
+    F: FnMut(&St::Item) -> Fut,
+    Fut: Future<Output = bool>,
 {
     type Item = St::Item;
 
-    fn poll_next(
-        self: Pin<&mut Self>,
-        cx: &mut Context<'_>,
-    ) -> Poll<Option<St::Item>> {
+    fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<St::Item>> {
         if self.done_taking {
             return Poll::Ready(None);
         }
@@ -109,9 +102,10 @@ impl<St, Fut, F> Stream for TakeWhile<St, Fut, F>
 }
 
 impl<St, Fut, F> FusedStream for TakeWhile<St, Fut, F>
-    where St: FusedStream,
-          F: FnMut(&St::Item) -> Fut,
-          Fut: Future<Output = bool>,
+where
+    St: FusedStream,
+    F: FnMut(&St::Item) -> Fut,
+    Fut: Future<Output = bool>,
 {
     fn is_terminated(&self) -> bool {
         self.done_taking || self.pending_item.is_none() && self.stream.is_terminated()
@@ -121,7 +115,8 @@ impl<St, Fut, F> FusedStream for TakeWhile<St, Fut, F>
 // Forwarding impl of Sink from the underlying stream
 #[cfg(feature = "sink")]
 impl<S, Fut, F, Item> Sink<Item> for TakeWhile<S, Fut, F>
-    where S: Stream + Sink<Item>,
+where
+    S: Stream + Sink<Item>,
 {
     type Error = S::Error;
 
diff --git a/third_party/rust/futures-util/src/stream/stream/then.rs b/third_party/rust/futures-util/src/stream/stream/then.rs
index 3d42bdd5c2d4111c7d1c3565324d244d648326f7..d4531d4b948963703b1ed039cc3f4cd29a4d2415 100644
--- a/third_party/rust/futures-util/src/stream/stream/then.rs
+++ b/third_party/rust/futures-util/src/stream/stream/then.rs
@@ -26,32 +26,27 @@ where
     Fut: fmt::Debug,
 {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.debug_struct("Then")
-            .field("stream", &self.stream)
-            .field("future", &self.future)
-            .finish()
+        f.debug_struct("Then").field("stream", &self.stream).field("future", &self.future).finish()
     }
 }
 
 impl<St, Fut, F> Then<St, Fut, F>
-    where St: Stream,
-          F: FnMut(St::Item) -> Fut,
+where
+    St: Stream,
+    F: FnMut(St::Item) -> Fut,
 {
     pub(super) fn new(stream: St, f: F) -> Self {
-        Self {
-            stream,
-            future: None,
-            f,
-        }
+        Self { stream, future: None, f }
     }
 
     delegate_access_inner!(stream, St, ());
 }
 
 impl<St, Fut, F> FusedStream for Then<St, Fut, F>
-    where St: FusedStream,
-          F: FnMut(St::Item) -> Fut,
-          Fut: Future,
+where
+    St: FusedStream,
+    F: FnMut(St::Item) -> Fut,
+    Fut: Future,
 {
     fn is_terminated(&self) -> bool {
         self.future.is_none() && self.stream.is_terminated()
@@ -59,16 +54,14 @@ impl<St, Fut, F> FusedStream for Then<St, Fut, F>
 }
 
 impl<St, Fut, F> Stream for Then<St, Fut, F>
-    where St: Stream,
-          F: FnMut(St::Item) -> Fut,
-          Fut: Future,
+where
+    St: Stream,
+    F: FnMut(St::Item) -> Fut,
+    Fut: Future,
 {
     type Item = Fut::Output;
 
-    fn poll_next(
-        self: Pin<&mut Self>,
-        cx: &mut Context<'_>,
-    ) -> Poll<Option<Self::Item>> {
+    fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
         let mut this = self.project();
 
         Poll::Ready(loop {
@@ -99,7 +92,8 @@ impl<St, Fut, F> Stream for Then<St, Fut, F>
 // Forwarding impl of Sink from the underlying stream
 #[cfg(feature = "sink")]
 impl<S, Fut, F, Item> Sink<Item> for Then<S, Fut, F>
-    where S: Sink<Item>,
+where
+    S: Sink<Item>,
 {
     type Error = S::Error;
 
diff --git a/third_party/rust/futures-util/src/stream/stream/unzip.rs b/third_party/rust/futures-util/src/stream/stream/unzip.rs
index 50247707695908220339d046564045ea80fc392c..15f22e80b08bd3ede0c2403f34a433fe95e8c4e5 100644
--- a/third_party/rust/futures-util/src/stream/stream/unzip.rs
+++ b/third_party/rust/futures-util/src/stream/stream/unzip.rs
@@ -21,25 +21,19 @@ pin_project! {
 impl<St: Stream, FromA: Default, FromB: Default> Unzip<St, FromA, FromB> {
     fn finish(self: Pin<&mut Self>) -> (FromA, FromB) {
         let this = self.project();
-        (
-            mem::replace(this.left, Default::default()),
-            mem::replace(this.right, Default::default()),
-        )
+        (mem::replace(this.left, Default::default()), mem::replace(this.right, Default::default()))
     }
 
     pub(super) fn new(stream: St) -> Self {
-        Self {
-            stream,
-            left: Default::default(),
-            right: Default::default(),
-        }
+        Self { stream, left: Default::default(), right: Default::default() }
     }
 }
 
 impl<St, A, B, FromA, FromB> FusedFuture for Unzip<St, FromA, FromB>
-where St: FusedStream<Item = (A, B)>,
-      FromA: Default + Extend<A>,
-      FromB: Default + Extend<B>,
+where
+    St: FusedStream<Item = (A, B)>,
+    FromA: Default + Extend<A>,
+    FromB: Default + Extend<B>,
 {
     fn is_terminated(&self) -> bool {
         self.stream.is_terminated()
@@ -47,9 +41,10 @@ where St: FusedStream<Item = (A, B)>,
 }
 
 impl<St, A, B, FromA, FromB> Future for Unzip<St, FromA, FromB>
-where St: Stream<Item = (A, B)>,
-      FromA: Default + Extend<A>,
-      FromB: Default + Extend<B>,
+where
+    St: Stream<Item = (A, B)>,
+    FromA: Default + Extend<A>,
+    FromB: Default + Extend<B>,
 {
     type Output = (FromA, FromB);
 
@@ -60,7 +55,7 @@ where St: Stream<Item = (A, B)>,
                 Some(e) => {
                     this.left.extend(Some(e.0));
                     this.right.extend(Some(e.1));
-                },
+                }
                 None => return Poll::Ready(self.finish()),
             }
         }
diff --git a/third_party/rust/futures-util/src/stream/stream/zip.rs b/third_party/rust/futures-util/src/stream/stream/zip.rs
index 588531a4684332663229b03fd918ad1032cdd719..360a8b63bb7d0269099bc9f7d0b258974a43ff3e 100644
--- a/third_party/rust/futures-util/src/stream/stream/zip.rs
+++ b/third_party/rust/futures-util/src/stream/stream/zip.rs
@@ -1,4 +1,4 @@
-use crate::stream::{StreamExt, Fuse};
+use crate::stream::{Fuse, StreamExt};
 use core::cmp;
 use core::pin::Pin;
 use futures_core::stream::{FusedStream, Stream};
@@ -21,12 +21,7 @@ pin_project! {
 
 impl<St1: Stream, St2: Stream> Zip<St1, St2> {
     pub(super) fn new(stream1: St1, stream2: St2) -> Self {
-        Self {
-            stream1: stream1.fuse(),
-            stream2: stream2.fuse(),
-            queued1: None,
-            queued2: None,
-        }
+        Self { stream1: stream1.fuse(), stream2: stream2.fuse(), queued1: None, queued2: None }
     }
 
     /// Acquires a reference to the underlying streams that this combinator is
@@ -64,7 +59,9 @@ impl<St1: Stream, St2: Stream> Zip<St1, St2> {
 }
 
 impl<St1, St2> FusedStream for Zip<St1, St2>
-    where St1: Stream, St2: Stream,
+where
+    St1: Stream,
+    St2: Stream,
 {
     fn is_terminated(&self) -> bool {
         self.stream1.is_terminated() && self.stream2.is_terminated()
@@ -72,14 +69,13 @@ impl<St1, St2> FusedStream for Zip<St1, St2>
 }
 
 impl<St1, St2> Stream for Zip<St1, St2>
-    where St1: Stream, St2: Stream
+where
+    St1: Stream,
+    St2: Stream,
 {
     type Item = (St1::Item, St2::Item);
 
-    fn poll_next(
-        self: Pin<&mut Self>,
-        cx: &mut Context<'_>,
-    ) -> Poll<Option<Self::Item>> {
+    fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
         let mut this = self.project();
 
         if this.queued1.is_none() {
@@ -124,7 +120,7 @@ impl<St1, St2> Stream for Zip<St1, St2>
             }
             (Some(x), None) => x.checked_add(queued1_len),
             (None, Some(y)) => y.checked_add(queued2_len),
-            (None, None) => None
+            (None, None) => None,
         };
 
         (lower, upper)
diff --git a/third_party/rust/futures-util/src/stream/try_stream/and_then.rs b/third_party/rust/futures-util/src/stream/try_stream/and_then.rs
index b18564649a13badf7aa8a99c56df6b77f7764932..a7b50db0b16491611e79ac41325f34357454950a 100644
--- a/third_party/rust/futures-util/src/stream/try_stream/and_then.rs
+++ b/third_party/rust/futures-util/src/stream/try_stream/and_then.rs
@@ -2,7 +2,7 @@ use core::fmt;
 use core::pin::Pin;
 use futures_core::future::TryFuture;
 use futures_core::ready;
-use futures_core::stream::{Stream, TryStream, FusedStream};
+use futures_core::stream::{FusedStream, Stream, TryStream};
 use futures_core::task::{Context, Poll};
 #[cfg(feature = "sink")]
 use futures_sink::Sink;
@@ -34,9 +34,10 @@ where
 }
 
 impl<St, Fut, F> AndThen<St, Fut, F>
-    where St: TryStream,
-          F: FnMut(St::Ok) -> Fut,
-          Fut: TryFuture<Error = St::Error>,
+where
+    St: TryStream,
+    F: FnMut(St::Ok) -> Fut,
+    Fut: TryFuture<Error = St::Error>,
 {
     pub(super) fn new(stream: St, f: F) -> Self {
         Self { stream, future: None, f }
@@ -46,16 +47,14 @@ impl<St, Fut, F> AndThen<St, Fut, F>
 }
 
 impl<St, Fut, F> Stream for AndThen<St, Fut, F>
-    where St: TryStream,
-          F: FnMut(St::Ok) -> Fut,
-          Fut: TryFuture<Error = St::Error>,
+where
+    St: TryStream,
+    F: FnMut(St::Ok) -> Fut,
+    Fut: TryFuture<Error = St::Error>,
 {
     type Item = Result<Fut::Ok, St::Error>;
 
-    fn poll_next(
-        self: Pin<&mut Self>,
-        cx: &mut Context<'_>,
-    ) -> Poll<Option<Self::Item>> {
+    fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
         let mut this = self.project();
 
         Poll::Ready(loop {
@@ -84,9 +83,10 @@ impl<St, Fut, F> Stream for AndThen<St, Fut, F>
 }
 
 impl<St, Fut, F> FusedStream for AndThen<St, Fut, F>
-    where St: TryStream + FusedStream,
-          F: FnMut(St::Ok) -> Fut,
-          Fut: TryFuture<Error = St::Error>,
+where
+    St: TryStream + FusedStream,
+    F: FnMut(St::Ok) -> Fut,
+    Fut: TryFuture<Error = St::Error>,
 {
     fn is_terminated(&self) -> bool {
         self.future.is_none() && self.stream.is_terminated()
@@ -96,7 +96,8 @@ impl<St, Fut, F> FusedStream for AndThen<St, Fut, F>
 // Forwarding impl of Sink from the underlying stream
 #[cfg(feature = "sink")]
 impl<S, Fut, F, Item> Sink<Item> for AndThen<S, Fut, F>
-    where S: Sink<Item>,
+where
+    S: Sink<Item>,
 {
     type Error = S::Error;
 
diff --git a/third_party/rust/futures-util/src/stream/try_stream/into_async_read.rs b/third_party/rust/futures-util/src/stream/try_stream/into_async_read.rs
index 197c10502dd97984f1922aed3a93186e6cd3bb5e..914b277a025a582c6b57bc7220ab46e1ef71dda7 100644
--- a/third_party/rust/futures-util/src/stream/try_stream/into_async_read.rs
+++ b/third_party/rust/futures-util/src/stream/try_stream/into_async_read.rs
@@ -3,7 +3,7 @@ use core::pin::Pin;
 use futures_core::ready;
 use futures_core::stream::TryStream;
 use futures_core::task::{Context, Poll};
-use futures_io::{AsyncRead, AsyncWrite, AsyncBufRead};
+use futures_io::{AsyncBufRead, AsyncRead, AsyncWrite};
 use std::cmp;
 use std::io::{Error, Result};
 
@@ -40,10 +40,7 @@ where
     St::Ok: AsRef<[u8]>,
 {
     pub(super) fn new(stream: St) -> Self {
-        Self {
-            stream,
-            state: ReadState::PendingChunk,
-        }
+        Self { stream, state: ReadState::PendingChunk }
     }
 }
 
@@ -63,9 +60,7 @@ where
                     let chunk = chunk.as_ref();
                     let len = cmp::min(buf.len(), chunk.len() - *chunk_start);
 
-                    buf[..len].copy_from_slice(
-                        &chunk[*chunk_start..*chunk_start + len],
-                    );
+                    buf[..len].copy_from_slice(&chunk[*chunk_start..*chunk_start + len]);
                     *chunk_start += len;
 
                     if chunk.len() == *chunk_start {
@@ -74,26 +69,21 @@ where
 
                     return Poll::Ready(Ok(len));
                 }
-                ReadState::PendingChunk => {
-                    match ready!(self.stream.try_poll_next_unpin(cx)) {
-                        Some(Ok(chunk)) => {
-                            if !chunk.as_ref().is_empty() {
-                                self.state = ReadState::Ready {
-                                    chunk,
-                                    chunk_start: 0,
-                                };
-                            }
-                        }
-                        Some(Err(err)) => {
-                            self.state = ReadState::Eof;
-                            return Poll::Ready(Err(err));
-                        }
-                        None => {
-                            self.state = ReadState::Eof;
-                            return Poll::Ready(Ok(0));
+                ReadState::PendingChunk => match ready!(self.stream.try_poll_next_unpin(cx)) {
+                    Some(Ok(chunk)) => {
+                        if !chunk.as_ref().is_empty() {
+                            self.state = ReadState::Ready { chunk, chunk_start: 0 };
                         }
                     }
-                }
+                    Some(Err(err)) => {
+                        self.state = ReadState::Eof;
+                        return Poll::Ready(Err(err));
+                    }
+                    None => {
+                        self.state = ReadState::Eof;
+                        return Poll::Ready(Ok(0));
+                    }
+                },
                 ReadState::Eof => {
                     return Poll::Ready(Ok(0));
                 }
@@ -110,23 +100,17 @@ where
     fn poll_write(
         mut self: Pin<&mut Self>,
         cx: &mut Context<'_>,
-        buf: &[u8]
+        buf: &[u8],
     ) -> Poll<Result<usize>> {
-        Pin::new( &mut self.stream ).poll_write( cx, buf )
+        Pin::new(&mut self.stream).poll_write(cx, buf)
     }
 
-    fn poll_flush(
-        mut self: Pin<&mut Self>,
-        cx: &mut Context<'_>
-    ) -> Poll<Result<()>> {
-        Pin::new( &mut self.stream ).poll_flush( cx )
+    fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<()>> {
+        Pin::new(&mut self.stream).poll_flush(cx)
     }
 
-    fn poll_close(
-        mut self: Pin<&mut Self>,
-        cx: &mut Context<'_>
-    ) -> Poll<Result<()>> {
-        Pin::new( &mut self.stream ).poll_close( cx )
+    fn poll_close(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<()>> {
+        Pin::new(&mut self.stream).poll_close(cx)
     }
 }
 
@@ -135,18 +119,12 @@ where
     St: TryStream<Error = Error> + Unpin,
     St::Ok: AsRef<[u8]>,
 {
-    fn poll_fill_buf(
-        mut self: Pin<&mut Self>,
-        cx: &mut Context<'_>,
-    ) -> Poll<Result<&[u8]>> {
+    fn poll_fill_buf(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<&[u8]>> {
         while let ReadState::PendingChunk = self.state {
             match ready!(self.stream.try_poll_next_unpin(cx)) {
                 Some(Ok(chunk)) => {
                     if !chunk.as_ref().is_empty() {
-                        self.state = ReadState::Ready {
-                            chunk,
-                            chunk_start: 0,
-                        };
+                        self.state = ReadState::Ready { chunk, chunk_start: 0 };
                     }
                 }
                 Some(Err(err)) => {
@@ -169,12 +147,11 @@ where
         Poll::Ready(Ok(&[]))
     }
 
-    fn consume(
-        mut self: Pin<&mut Self>,
-        amount: usize,
-    ) {
-         // https://github.com/rust-lang/futures-rs/pull/1556#discussion_r281644295
-        if amount == 0 { return }
+    fn consume(mut self: Pin<&mut Self>, amount: usize) {
+        // https://github.com/rust-lang/futures-rs/pull/1556#discussion_r281644295
+        if amount == 0 {
+            return;
+        }
         if let ReadState::Ready { chunk, chunk_start } = &mut self.state {
             *chunk_start += amount;
             debug_assert!(*chunk_start <= chunk.as_ref().len());
diff --git a/third_party/rust/futures-util/src/stream/try_stream/into_stream.rs b/third_party/rust/futures-util/src/stream/try_stream/into_stream.rs
index 89bc3ef177c967594afef6d3eebf6dd34d3aa262..2126258af7aa9ccbbf8c0306313d67ccbdce0748 100644
--- a/third_party/rust/futures-util/src/stream/try_stream/into_stream.rs
+++ b/third_party/rust/futures-util/src/stream/try_stream/into_stream.rs
@@ -34,10 +34,7 @@ impl<St: TryStream> Stream for IntoStream<St> {
     type Item = Result<St::Ok, St::Error>;
 
     #[inline]
-    fn poll_next(
-        self: Pin<&mut Self>,
-        cx: &mut Context<'_>,
-    ) -> Poll<Option<Self::Item>> {
+    fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
         self.project().stream.try_poll_next(cx)
     }
 
diff --git a/third_party/rust/futures-util/src/stream/try_stream/mod.rs b/third_party/rust/futures-util/src/stream/try_stream/mod.rs
index 6a48a4c4b4c01256e8776d612407efd716747803..11cd9c0d31e4e595de1ab0d45af703185bf9fa35 100644
--- a/third_party/rust/futures-util/src/stream/try_stream/mod.rs
+++ b/third_party/rust/futures-util/src/stream/try_stream/mod.rs
@@ -5,16 +5,19 @@
 
 #[cfg(feature = "compat")]
 use crate::compat::Compat;
+use crate::fns::{
+    inspect_err_fn, inspect_ok_fn, into_fn, map_err_fn, map_ok_fn, InspectErrFn, InspectOkFn,
+    IntoFn, MapErrFn, MapOkFn,
+};
+use crate::future::assert_future;
+use crate::stream::assert_stream;
+use crate::stream::{Inspect, Map};
 use core::pin::Pin;
 use futures_core::{
     future::{Future, TryFuture},
     stream::TryStream,
     task::{Context, Poll},
 };
-use crate::fns::{
-    InspectOkFn, inspect_ok_fn, InspectErrFn, inspect_err_fn, MapErrFn, map_err_fn, IntoFn, into_fn, MapOkFn, map_ok_fn,
-};
-use crate::stream::{Map, Inspect};
 
 mod and_then;
 #[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411
@@ -135,8 +138,6 @@ mod into_async_read;
 #[cfg(feature = "std")]
 #[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411
 pub use self::into_async_read::IntoAsyncRead;
-use crate::future::assert_future;
-use crate::stream::assert_stream;
 
 impl<S: ?Sized + TryStream> TryStreamExt for S {}
 
@@ -471,7 +472,7 @@ pub trait TryStreamExt: TryStream {
         Fut: TryFuture<Ok = bool, Error = Self::Error>,
         Self: Sized,
     {
-        TryTakeWhile::new(self, f)
+        assert_stream::<Result<Self::Ok, Self::Error>, _>(TryTakeWhile::new(self, f))
     }
 
     /// Attempts to run this stream to completion, executing the provided asynchronous
@@ -515,7 +516,7 @@ pub trait TryStreamExt: TryStream {
     /// assert_eq!(Err(oneshot::Canceled), fut.await);
     /// # })
     /// ```
-    #[cfg_attr(feature = "cfg-target-has-atomic", cfg(target_has_atomic = "ptr"))]
+    #[cfg(not(futures_no_atomic_cas))]
     #[cfg(feature = "alloc")]
     fn try_for_each_concurrent<Fut, F>(
         self,
@@ -836,7 +837,7 @@ pub trait TryStreamExt: TryStream {
     /// assert_eq!(buffered.next().await, Some(Err("error in the stream")));
     /// # Ok::<(), Box<dyn std::error::Error>>(()) }).unwrap();
     /// ```
-    #[cfg_attr(feature = "cfg-target-has-atomic", cfg(target_has_atomic = "ptr"))]
+    #[cfg(not(futures_no_atomic_cas))]
     #[cfg(feature = "alloc")]
     fn try_buffer_unordered(self, n: usize) -> TryBufferUnordered<Self>
     where
@@ -912,14 +913,16 @@ pub trait TryStreamExt: TryStream {
     /// assert_eq!(buffered.next().await, Some(Err("error in the stream")));
     /// # Ok::<(), Box<dyn std::error::Error>>(()) }).unwrap();
     /// ```
-    #[cfg_attr(feature = "cfg-target-has-atomic", cfg(target_has_atomic = "ptr"))]
+    #[cfg(not(futures_no_atomic_cas))]
     #[cfg(feature = "alloc")]
     fn try_buffered(self, n: usize) -> TryBuffered<Self>
     where
         Self::Ok: TryFuture<Error = Self::Error>,
         Self: Sized,
     {
-        TryBuffered::new(self, n)
+        assert_stream::<Result<<Self::Ok as TryFuture>::Ok, Self::Error>, _>(TryBuffered::new(
+            self, n,
+        ))
     }
 
     // TODO: false positive warning from rustdoc. Verify once #43466 settles
@@ -997,6 +1000,6 @@ pub trait TryStreamExt: TryStream {
         Self: Sized + TryStreamExt<Error = std::io::Error> + Unpin,
         Self::Ok: AsRef<[u8]>,
     {
-        IntoAsyncRead::new(self)
+        crate::io::assert_read(IntoAsyncRead::new(self))
     }
 }
diff --git a/third_party/rust/futures-util/src/stream/try_stream/or_else.rs b/third_party/rust/futures-util/src/stream/try_stream/or_else.rs
index 999123a4375cb9be6d5c535d7425287d72cc3e4b..cb69e813233a4fa4e7b0381cd24a25a7a6bc74e7 100644
--- a/third_party/rust/futures-util/src/stream/try_stream/or_else.rs
+++ b/third_party/rust/futures-util/src/stream/try_stream/or_else.rs
@@ -2,7 +2,7 @@ use core::fmt;
 use core::pin::Pin;
 use futures_core::future::TryFuture;
 use futures_core::ready;
-use futures_core::stream::{Stream, TryStream, FusedStream};
+use futures_core::stream::{FusedStream, Stream, TryStream};
 use futures_core::task::{Context, Poll};
 #[cfg(feature = "sink")]
 use futures_sink::Sink;
@@ -34,9 +34,10 @@ where
 }
 
 impl<St, Fut, F> OrElse<St, Fut, F>
-    where St: TryStream,
-          F: FnMut(St::Error) -> Fut,
-          Fut: TryFuture<Ok = St::Ok>,
+where
+    St: TryStream,
+    F: FnMut(St::Error) -> Fut,
+    Fut: TryFuture<Ok = St::Ok>,
 {
     pub(super) fn new(stream: St, f: F) -> Self {
         Self { stream, future: None, f }
@@ -46,16 +47,14 @@ impl<St, Fut, F> OrElse<St, Fut, F>
 }
 
 impl<St, Fut, F> Stream for OrElse<St, Fut, F>
-    where St: TryStream,
-          F: FnMut(St::Error) -> Fut,
-          Fut: TryFuture<Ok = St::Ok>,
+where
+    St: TryStream,
+    F: FnMut(St::Error) -> Fut,
+    Fut: TryFuture<Ok = St::Ok>,
 {
     type Item = Result<St::Ok, Fut::Error>;
 
-    fn poll_next(
-        self: Pin<&mut Self>,
-        cx: &mut Context<'_>,
-    ) -> Poll<Option<Self::Item>> {
+    fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
         let mut this = self.project();
 
         Poll::Ready(loop {
@@ -68,7 +67,7 @@ impl<St, Fut, F> Stream for OrElse<St, Fut, F>
                     Some(Ok(item)) => break Some(Ok(item)),
                     Some(Err(e)) => {
                         this.future.set(Some((this.f)(e)));
-                    },
+                    }
                     None => break None,
                 }
             }
@@ -88,9 +87,10 @@ impl<St, Fut, F> Stream for OrElse<St, Fut, F>
 }
 
 impl<St, Fut, F> FusedStream for OrElse<St, Fut, F>
-    where St: TryStream + FusedStream,
-          F: FnMut(St::Error) -> Fut,
-          Fut: TryFuture<Ok = St::Ok>,
+where
+    St: TryStream + FusedStream,
+    F: FnMut(St::Error) -> Fut,
+    Fut: TryFuture<Ok = St::Ok>,
 {
     fn is_terminated(&self) -> bool {
         self.future.is_none() && self.stream.is_terminated()
@@ -100,7 +100,8 @@ impl<St, Fut, F> FusedStream for OrElse<St, Fut, F>
 // Forwarding impl of Sink from the underlying stream
 #[cfg(feature = "sink")]
 impl<S, Fut, F, Item> Sink<Item> for OrElse<S, Fut, F>
-    where S: Sink<Item>,
+where
+    S: Sink<Item>,
 {
     type Error = S::Error;
 
diff --git a/third_party/rust/futures-util/src/stream/try_stream/try_buffer_unordered.rs b/third_party/rust/futures-util/src/stream/try_stream/try_buffer_unordered.rs
index 71c6fc7e26c0647aa6e8f74066b2563d1ee97218..9a899d4ea6d61d99dfef27affeb808b68e9aa8a8 100644
--- a/third_party/rust/futures-util/src/stream/try_stream/try_buffer_unordered.rs
+++ b/third_party/rust/futures-util/src/stream/try_stream/try_buffer_unordered.rs
@@ -1,12 +1,12 @@
-use crate::stream::{Fuse, FuturesUnordered, StreamExt, IntoStream};
 use crate::future::{IntoFuture, TryFutureExt};
+use crate::stream::{Fuse, FuturesUnordered, IntoStream, StreamExt};
+use core::pin::Pin;
 use futures_core::future::TryFuture;
 use futures_core::stream::{Stream, TryStream};
 use futures_core::task::{Context, Poll};
 #[cfg(feature = "sink")]
 use futures_sink::Sink;
 use pin_project_lite::pin_project;
-use core::pin::Pin;
 
 pin_project! {
     /// Stream for the
@@ -24,8 +24,9 @@ pin_project! {
 }
 
 impl<St> TryBufferUnordered<St>
-    where St: TryStream,
-          St::Ok: TryFuture,
+where
+    St: TryStream,
+    St::Ok: TryFuture,
 {
     pub(super) fn new(stream: St, n: usize) -> Self {
         Self {
@@ -39,15 +40,13 @@ impl<St> TryBufferUnordered<St>
 }
 
 impl<St> Stream for TryBufferUnordered<St>
-    where St: TryStream,
-          St::Ok: TryFuture<Error = St::Error>,
+where
+    St: TryStream,
+    St::Ok: TryFuture<Error = St::Error>,
 {
     type Item = Result<<St::Ok as TryFuture>::Ok, St::Error>;
 
-    fn poll_next(
-        self: Pin<&mut Self>,
-        cx: &mut Context<'_>,
-    ) -> Poll<Option<Self::Item>> {
+    fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
         let mut this = self.project();
 
         // First up, try to spawn off as many futures as possible by filling up
@@ -77,8 +76,9 @@ impl<St> Stream for TryBufferUnordered<St>
 // Forwarding impl of Sink from the underlying stream
 #[cfg(feature = "sink")]
 impl<S, Item, E> Sink<Item> for TryBufferUnordered<S>
-    where S: TryStream + Sink<Item, Error = E>,
-          S::Ok: TryFuture<Error = E>,
+where
+    S: TryStream + Sink<Item, Error = E>,
+    S::Ok: TryFuture<Error = E>,
 {
     type Error = E;
 
diff --git a/third_party/rust/futures-util/src/stream/try_stream/try_buffered.rs b/third_party/rust/futures-util/src/stream/try_stream/try_buffered.rs
index ff7e8447f902be39349e40ba05851e85bbf278c7..45bd3f8c7a62b48b98a8e29f62ee972752405191 100644
--- a/third_party/rust/futures-util/src/stream/try_stream/try_buffered.rs
+++ b/third_party/rust/futures-util/src/stream/try_stream/try_buffered.rs
@@ -1,12 +1,12 @@
-use crate::stream::{Fuse, FuturesOrdered, StreamExt, IntoStream};
 use crate::future::{IntoFuture, TryFutureExt};
+use crate::stream::{Fuse, FuturesOrdered, IntoStream, StreamExt};
+use core::pin::Pin;
 use futures_core::future::TryFuture;
 use futures_core::stream::{Stream, TryStream};
 use futures_core::task::{Context, Poll};
 #[cfg(feature = "sink")]
 use futures_sink::Sink;
 use pin_project_lite::pin_project;
-use core::pin::Pin;
 
 pin_project! {
     /// Stream for the [`try_buffered`](super::TryStreamExt::try_buffered) method.
@@ -47,10 +47,7 @@ where
 {
     type Item = Result<<St::Ok as TryFuture>::Ok, St::Error>;
 
-    fn poll_next(
-        self: Pin<&mut Self>,
-        cx: &mut Context<'_>,
-    ) -> Poll<Option<Self::Item>> {
+    fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
         let mut this = self.project();
 
         // First up, try to spawn off as many futures as possible by filling up
diff --git a/third_party/rust/futures-util/src/stream/try_stream/try_collect.rs b/third_party/rust/futures-util/src/stream/try_stream/try_collect.rs
index 387de9703b79d58bd0e48253178c03146920b5d3..5d3b3d7668fda6c96fce51da98b78ac663428415 100644
--- a/third_party/rust/futures-util/src/stream/try_stream/try_collect.rs
+++ b/third_party/rust/futures-util/src/stream/try_stream/try_collect.rs
@@ -19,10 +19,7 @@ pin_project! {
 
 impl<St: TryStream, C: Default> TryCollect<St, C> {
     pub(super) fn new(s: St) -> Self {
-        Self {
-            stream: s,
-            items: Default::default(),
-        }
+        Self { stream: s, items: Default::default() }
     }
 }
 
@@ -43,10 +40,7 @@ where
 {
     type Output = Result<C, St::Error>;
 
-    fn poll(
-        self: Pin<&mut Self>,
-        cx: &mut Context<'_>,
-    ) -> Poll<Self::Output> {
+    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
         let mut this = self.project();
         Poll::Ready(Ok(loop {
             match ready!(this.stream.as_mut().try_poll_next(cx)?) {
diff --git a/third_party/rust/futures-util/src/stream/try_stream/try_concat.rs b/third_party/rust/futures-util/src/stream/try_stream/try_concat.rs
index 2451332448472a6e04ecd5a0835f502b1b1a4688..58fb6a5413f8473414b5a9d85f4817ee18e29a64 100644
--- a/third_party/rust/futures-util/src/stream/try_stream/try_concat.rs
+++ b/third_party/rust/futures-util/src/stream/try_stream/try_concat.rs
@@ -22,10 +22,7 @@ where
     St::Ok: Extend<<St::Ok as IntoIterator>::Item> + IntoIterator + Default,
 {
     pub(super) fn new(stream: St) -> Self {
-        Self {
-            stream,
-            accum: None,
-        }
+        Self { stream, accum: None }
     }
 }
 
diff --git a/third_party/rust/futures-util/src/stream/try_stream/try_filter.rs b/third_party/rust/futures-util/src/stream/try_stream/try_filter.rs
index eacefd20dbac31e8ec4c9b494b3cd5531390f194..61e6105c374ea4410c13c16881b47824d775f013 100644
--- a/third_party/rust/futures-util/src/stream/try_stream/try_filter.rs
+++ b/third_party/rust/futures-util/src/stream/try_stream/try_filter.rs
@@ -2,7 +2,7 @@ use core::fmt;
 use core::pin::Pin;
 use futures_core::future::Future;
 use futures_core::ready;
-use futures_core::stream::{Stream, TryStream, FusedStream};
+use futures_core::stream::{FusedStream, Stream, TryStream};
 use futures_core::task::{Context, Poll};
 #[cfg(feature = "sink")]
 use futures_sink::Sink;
@@ -40,24 +40,21 @@ where
 }
 
 impl<St, Fut, F> TryFilter<St, Fut, F>
-    where St: TryStream
+where
+    St: TryStream,
 {
     pub(super) fn new(stream: St, f: F) -> Self {
-        Self {
-            stream,
-            f,
-            pending_fut: None,
-            pending_item: None,
-        }
+        Self { stream, f, pending_fut: None, pending_item: None }
     }
 
     delegate_access_inner!(stream, St, ());
 }
 
 impl<St, Fut, F> FusedStream for TryFilter<St, Fut, F>
-    where St: TryStream + FusedStream,
-          F: FnMut(&St::Ok) -> Fut,
-          Fut: Future<Output = bool>,
+where
+    St: TryStream + FusedStream,
+    F: FnMut(&St::Ok) -> Fut,
+    Fut: Future<Output = bool>,
 {
     fn is_terminated(&self) -> bool {
         self.pending_fut.is_none() && self.stream.is_terminated()
@@ -65,16 +62,14 @@ impl<St, Fut, F> FusedStream for TryFilter<St, Fut, F>
 }
 
 impl<St, Fut, F> Stream for TryFilter<St, Fut, F>
-    where St: TryStream,
-          Fut: Future<Output = bool>,
-          F: FnMut(&St::Ok) -> Fut,
+where
+    St: TryStream,
+    Fut: Future<Output = bool>,
+    F: FnMut(&St::Ok) -> Fut,
 {
     type Item = Result<St::Ok, St::Error>;
 
-    fn poll_next(
-        self: Pin<&mut Self>,
-        cx: &mut Context<'_>,
-    ) -> Poll<Option<Self::Item>> {
+    fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
         let mut this = self.project();
 
         Poll::Ready(loop {
@@ -108,7 +103,8 @@ impl<St, Fut, F> Stream for TryFilter<St, Fut, F>
 // Forwarding impl of Sink from the underlying stream
 #[cfg(feature = "sink")]
 impl<S, Fut, F, Item, E> Sink<Item> for TryFilter<S, Fut, F>
-    where S: TryStream + Sink<Item, Error = E>,
+where
+    S: TryStream + Sink<Item, Error = E>,
 {
     type Error = E;
 
diff --git a/third_party/rust/futures-util/src/stream/try_stream/try_filter_map.rs b/third_party/rust/futures-util/src/stream/try_stream/try_filter_map.rs
index 335649bfc94c5cceeb70f9850c0949cad2225eba..bb1b5b9db6df270621a302a0960c20043e54aecd 100644
--- a/third_party/rust/futures-util/src/stream/try_stream/try_filter_map.rs
+++ b/third_party/rust/futures-util/src/stream/try_stream/try_filter_map.rs
@@ -1,8 +1,8 @@
 use core::fmt;
 use core::pin::Pin;
-use futures_core::future::{TryFuture};
+use futures_core::future::TryFuture;
 use futures_core::ready;
-use futures_core::stream::{Stream, TryStream, FusedStream};
+use futures_core::stream::{FusedStream, Stream, TryStream};
 use futures_core::task::{Context, Poll};
 #[cfg(feature = "sink")]
 use futures_sink::Sink;
@@ -43,9 +43,10 @@ impl<St, Fut, F> TryFilterMap<St, Fut, F> {
 }
 
 impl<St, Fut, F, T> FusedStream for TryFilterMap<St, Fut, F>
-    where St: TryStream + FusedStream,
-          Fut: TryFuture<Ok = Option<T>, Error = St::Error>,
-          F: FnMut(St::Ok) -> Fut,
+where
+    St: TryStream + FusedStream,
+    Fut: TryFuture<Ok = Option<T>, Error = St::Error>,
+    F: FnMut(St::Ok) -> Fut,
 {
     fn is_terminated(&self) -> bool {
         self.pending.is_none() && self.stream.is_terminated()
@@ -53,16 +54,14 @@ impl<St, Fut, F, T> FusedStream for TryFilterMap<St, Fut, F>
 }
 
 impl<St, Fut, F, T> Stream for TryFilterMap<St, Fut, F>
-    where St: TryStream,
-          Fut: TryFuture<Ok = Option<T>, Error = St::Error>,
-          F: FnMut(St::Ok) -> Fut,
+where
+    St: TryStream,
+    Fut: TryFuture<Ok = Option<T>, Error = St::Error>,
+    F: FnMut(St::Ok) -> Fut,
 {
     type Item = Result<T, St::Error>;
 
-    fn poll_next(
-        self: Pin<&mut Self>,
-        cx: &mut Context<'_>,
-    ) -> Poll<Option<Self::Item>> {
+    fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
         let mut this = self.project();
 
         Poll::Ready(loop {
@@ -98,7 +97,8 @@ impl<St, Fut, F, T> Stream for TryFilterMap<St, Fut, F>
 // Forwarding impl of Sink from the underlying stream
 #[cfg(feature = "sink")]
 impl<S, Fut, F, Item> Sink<Item> for TryFilterMap<S, Fut, F>
-    where S: Sink<Item>,
+where
+    S: Sink<Item>,
 {
     type Error = S::Error;
 
diff --git a/third_party/rust/futures-util/src/stream/try_stream/try_fold.rs b/third_party/rust/futures-util/src/stream/try_stream/try_fold.rs
index 1d41e4bc2b6553cd4f1ebafc72d9823b8b062705..d344d96e7d0dcae45add32490bfce0843f0311bd 100644
--- a/third_party/rust/futures-util/src/stream/try_stream/try_fold.rs
+++ b/third_party/rust/futures-util/src/stream/try_stream/try_fold.rs
@@ -35,24 +35,21 @@ where
 }
 
 impl<St, Fut, T, F> TryFold<St, Fut, T, F>
-where St: TryStream,
-      F: FnMut(T, St::Ok) -> Fut,
-      Fut: TryFuture<Ok = T, Error = St::Error>,
+where
+    St: TryStream,
+    F: FnMut(T, St::Ok) -> Fut,
+    Fut: TryFuture<Ok = T, Error = St::Error>,
 {
     pub(super) fn new(stream: St, f: F, t: T) -> Self {
-        Self {
-            stream,
-            f,
-            accum: Some(t),
-            future: None,
-        }
+        Self { stream, f, accum: Some(t), future: None }
     }
 }
 
 impl<St, Fut, T, F> FusedFuture for TryFold<St, Fut, T, F>
-    where St: TryStream,
-          F: FnMut(T, St::Ok) -> Fut,
-          Fut: TryFuture<Ok = T, Error = St::Error>,
+where
+    St: TryStream,
+    F: FnMut(T, St::Ok) -> Fut,
+    Fut: TryFuture<Ok = T, Error = St::Error>,
 {
     fn is_terminated(&self) -> bool {
         self.accum.is_none() && self.future.is_none()
@@ -60,9 +57,10 @@ impl<St, Fut, T, F> FusedFuture for TryFold<St, Fut, T, F>
 }
 
 impl<St, Fut, T, F> Future for TryFold<St, Fut, T, F>
-    where St: TryStream,
-          F: FnMut(T, St::Ok) -> Fut,
-          Fut: TryFuture<Ok = T, Error = St::Error>,
+where
+    St: TryStream,
+    F: FnMut(T, St::Ok) -> Fut,
+    Fut: TryFuture<Ok = T, Error = St::Error>,
 {
     type Output = Result<T, St::Error>;
 
diff --git a/third_party/rust/futures-util/src/stream/try_stream/try_for_each.rs b/third_party/rust/futures-util/src/stream/try_stream/try_for_each.rs
index 0a814ae86c2b8a8fc96b35c8ed621dde81d957e4..6a081d84e74e3a980dcc02b1dcb16f56c86d2612 100644
--- a/third_party/rust/futures-util/src/stream/try_stream/try_for_each.rs
+++ b/third_party/rust/futures-util/src/stream/try_stream/try_for_each.rs
@@ -32,23 +32,21 @@ where
 }
 
 impl<St, Fut, F> TryForEach<St, Fut, F>
-where St: TryStream,
-      F: FnMut(St::Ok) -> Fut,
-      Fut: TryFuture<Ok = (), Error = St::Error>,
+where
+    St: TryStream,
+    F: FnMut(St::Ok) -> Fut,
+    Fut: TryFuture<Ok = (), Error = St::Error>,
 {
     pub(super) fn new(stream: St, f: F) -> Self {
-        Self {
-            stream,
-            f,
-            future: None,
-        }
+        Self { stream, f, future: None }
     }
 }
 
 impl<St, Fut, F> Future for TryForEach<St, Fut, F>
-    where St: TryStream,
-          F: FnMut(St::Ok) -> Fut,
-          Fut: TryFuture<Ok = (), Error = St::Error>,
+where
+    St: TryStream,
+    F: FnMut(St::Ok) -> Fut,
+    Fut: TryFuture<Ok = (), Error = St::Error>,
 {
     type Output = Result<(), St::Error>;
 
diff --git a/third_party/rust/futures-util/src/stream/try_stream/try_for_each_concurrent.rs b/third_party/rust/futures-util/src/stream/try_stream/try_for_each_concurrent.rs
index d2f4b0fed2be15f7b9883d588caad0b2da686937..62734c746b796ac8b701f78217025c9f52479e4f 100644
--- a/third_party/rust/futures-util/src/stream/try_stream/try_for_each_concurrent.rs
+++ b/third_party/rust/futures-util/src/stream/try_stream/try_for_each_concurrent.rs
@@ -1,8 +1,8 @@
 use crate::stream::{FuturesUnordered, StreamExt};
 use core::fmt;
 use core::mem;
-use core::pin::Pin;
 use core::num::NonZeroUsize;
+use core::pin::Pin;
 use futures_core::future::{FusedFuture, Future};
 use futures_core::stream::TryStream;
 use futures_core::task::{Context, Poll};
@@ -37,9 +37,10 @@ where
 }
 
 impl<St, Fut, F> FusedFuture for TryForEachConcurrent<St, Fut, F>
-    where St: TryStream,
-          F: FnMut(St::Ok) -> Fut,
-          Fut: Future<Output = Result<(), St::Error>>,
+where
+    St: TryStream,
+    F: FnMut(St::Ok) -> Fut,
+    Fut: Future<Output = Result<(), St::Error>>,
 {
     fn is_terminated(&self) -> bool {
         self.stream.is_none() && self.futures.is_empty()
@@ -47,9 +48,10 @@ impl<St, Fut, F> FusedFuture for TryForEachConcurrent<St, Fut, F>
 }
 
 impl<St, Fut, F> TryForEachConcurrent<St, Fut, F>
-where St: TryStream,
-      F: FnMut(St::Ok) -> Fut,
-      Fut: Future<Output = Result<(), St::Error>>,
+where
+    St: TryStream,
+    F: FnMut(St::Ok) -> Fut,
+    Fut: Future<Output = Result<(), St::Error>>,
 {
     pub(super) fn new(stream: St, limit: Option<usize>, f: F) -> Self {
         Self {
@@ -63,9 +65,10 @@ where St: TryStream,
 }
 
 impl<St, Fut, F> Future for TryForEachConcurrent<St, Fut, F>
-    where St: TryStream,
-          F: FnMut(St::Ok) -> Fut,
-          Fut: Future<Output = Result<(), St::Error>>,
+where
+    St: TryStream,
+    F: FnMut(St::Ok) -> Fut,
+    Fut: Future<Output = Result<(), St::Error>>,
 {
     type Output = Result<(), St::Error>;
 
@@ -85,7 +88,7 @@ impl<St, Fut, F> Future for TryForEachConcurrent<St, Fut, F>
                     Poll::Ready(Some(Ok(elem))) => {
                         made_progress_this_iter = true;
                         Some(elem)
-                    },
+                    }
                     Poll::Ready(None) => {
                         this.stream.set(None);
                         None
@@ -109,9 +112,9 @@ impl<St, Fut, F> Future for TryForEachConcurrent<St, Fut, F>
                 Poll::Ready(Some(Ok(()))) => made_progress_this_iter = true,
                 Poll::Ready(None) => {
                     if this.stream.is_none() {
-                        return Poll::Ready(Ok(()))
+                        return Poll::Ready(Ok(()));
                     }
-                },
+                }
                 Poll::Pending => {}
                 Poll::Ready(Some(Err(e))) => {
                     // Empty the stream and futures so that we know
diff --git a/third_party/rust/futures-util/src/stream/try_stream/try_next.rs b/third_party/rust/futures-util/src/stream/try_stream/try_next.rs
index 1bc00fbc2d4a401c4f74eb76a3e66a9669059d54..13fcf80caefb8e029bf43d346bf6133b261fd8cc 100644
--- a/third_party/rust/futures-util/src/stream/try_stream/try_next.rs
+++ b/third_party/rust/futures-util/src/stream/try_stream/try_next.rs
@@ -28,10 +28,7 @@ impl<St: ?Sized + TryStream + Unpin + FusedStream> FusedFuture for TryNext<'_, S
 impl<St: ?Sized + TryStream + Unpin> Future for TryNext<'_, St> {
     type Output = Result<Option<St::Ok>, St::Error>;
 
-    fn poll(
-        mut self: Pin<&mut Self>,
-        cx: &mut Context<'_>,
-    ) -> Poll<Self::Output> {
+    fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
         self.stream.try_poll_next_unpin(cx)?.map(Ok)
     }
 }
diff --git a/third_party/rust/futures-util/src/stream/try_stream/try_skip_while.rs b/third_party/rust/futures-util/src/stream/try_stream/try_skip_while.rs
index 0603b10f854a98c2fd48d3201708fde835193eb2..a424b6c5b16c99f96f55001f406b6e4a34c41964 100644
--- a/third_party/rust/futures-util/src/stream/try_stream/try_skip_while.rs
+++ b/third_party/rust/futures-util/src/stream/try_stream/try_skip_while.rs
@@ -2,7 +2,7 @@ use core::fmt;
 use core::pin::Pin;
 use futures_core::future::TryFuture;
 use futures_core::ready;
-use futures_core::stream::{Stream, TryStream, FusedStream};
+use futures_core::stream::{FusedStream, Stream, TryStream};
 use futures_core::task::{Context, Poll};
 #[cfg(feature = "sink")]
 use futures_sink::Sink;
@@ -40,34 +40,27 @@ where
 }
 
 impl<St, Fut, F> TrySkipWhile<St, Fut, F>
-    where St: TryStream,
-          F: FnMut(&St::Ok) -> Fut,
-          Fut: TryFuture<Ok = bool, Error = St::Error>,
+where
+    St: TryStream,
+    F: FnMut(&St::Ok) -> Fut,
+    Fut: TryFuture<Ok = bool, Error = St::Error>,
 {
     pub(super) fn new(stream: St, f: F) -> Self {
-        Self {
-            stream,
-            f,
-            pending_fut: None,
-            pending_item: None,
-            done_skipping: false,
-        }
+        Self { stream, f, pending_fut: None, pending_item: None, done_skipping: false }
     }
 
     delegate_access_inner!(stream, St, ());
 }
 
 impl<St, Fut, F> Stream for TrySkipWhile<St, Fut, F>
-    where St: TryStream,
-          F: FnMut(&St::Ok) -> Fut,
-          Fut: TryFuture<Ok = bool, Error = St::Error>,
+where
+    St: TryStream,
+    F: FnMut(&St::Ok) -> Fut,
+    Fut: TryFuture<Ok = bool, Error = St::Error>,
 {
     type Item = Result<St::Ok, St::Error>;
 
-    fn poll_next(
-        self: Pin<&mut Self>,
-        cx: &mut Context<'_>,
-    ) -> Poll<Option<Self::Item>> {
+    fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
         let mut this = self.project();
 
         if *this.done_skipping {
@@ -105,9 +98,10 @@ impl<St, Fut, F> Stream for TrySkipWhile<St, Fut, F>
 }
 
 impl<St, Fut, F> FusedStream for TrySkipWhile<St, Fut, F>
-    where St: TryStream + FusedStream,
-          F: FnMut(&St::Ok) -> Fut,
-          Fut: TryFuture<Ok = bool, Error = St::Error>,
+where
+    St: TryStream + FusedStream,
+    F: FnMut(&St::Ok) -> Fut,
+    Fut: TryFuture<Ok = bool, Error = St::Error>,
 {
     fn is_terminated(&self) -> bool {
         self.pending_item.is_none() && self.stream.is_terminated()
@@ -117,7 +111,8 @@ impl<St, Fut, F> FusedStream for TrySkipWhile<St, Fut, F>
 // Forwarding impl of Sink from the underlying stream
 #[cfg(feature = "sink")]
 impl<S, Fut, F, Item, E> Sink<Item> for TrySkipWhile<S, Fut, F>
-    where S: TryStream + Sink<Item, Error = E>,
+where
+    S: TryStream + Sink<Item, Error = E>,
 {
     type Error = E;
 
diff --git a/third_party/rust/futures-util/src/stream/try_stream/try_take_while.rs b/third_party/rust/futures-util/src/stream/try_stream/try_take_while.rs
index 624157290ca43136e7769f30e9ac448c8fd4d881..3375960ef4b19288b03c6e04e85949da6c80e4d6 100644
--- a/third_party/rust/futures-util/src/stream/try_stream/try_take_while.rs
+++ b/third_party/rust/futures-util/src/stream/try_stream/try_take_while.rs
@@ -49,13 +49,7 @@ where
     Fut: TryFuture<Ok = bool, Error = St::Error>,
 {
     pub(super) fn new(stream: St, f: F) -> Self {
-        Self {
-            stream,
-            f,
-            pending_fut: None,
-            pending_item: None,
-            done_taking: false,
-        }
+        Self { stream, f, pending_fut: None, pending_item: None, done_taking: false }
     }
 
     delegate_access_inner!(stream, St, ());
diff --git a/third_party/rust/futures-util/src/stream/try_stream/try_unfold.rs b/third_party/rust/futures-util/src/stream/try_stream/try_unfold.rs
index c8fc421386189f36f1b15e4583a702862be21e9a..fd9cdf1d8ca483c02aa72f71a16e28ab3965bdc8 100644
--- a/third_party/rust/futures-util/src/stream/try_stream/try_unfold.rs
+++ b/third_party/rust/futures-util/src/stream/try_stream/try_unfold.rs
@@ -1,3 +1,4 @@
+use super::assert_stream;
 use core::fmt;
 use core::pin::Pin;
 use futures_core::future::TryFuture;
@@ -60,11 +61,7 @@ where
     F: FnMut(T) -> Fut,
     Fut: TryFuture<Ok = Option<(Item, T)>>,
 {
-    TryUnfold {
-        f,
-        state: Some(init),
-        fut: None,
-    }
+    assert_stream::<Result<Item, Fut::Error>, _>(TryUnfold { f, state: Some(init), fut: None })
 }
 
 pin_project! {
@@ -84,10 +81,7 @@ where
     Fut: fmt::Debug,
 {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.debug_struct("TryUnfold")
-            .field("state", &self.state)
-            .field("fut", &self.fut)
-            .finish()
+        f.debug_struct("TryUnfold").field("state", &self.state).field("fut", &self.fut).finish()
     }
 }
 
@@ -98,10 +92,7 @@ where
 {
     type Item = Result<Item, Fut::Error>;
 
-    fn poll_next(
-        self: Pin<&mut Self>,
-        cx: &mut Context<'_>,
-    ) -> Poll<Option<Self::Item>> {
+    fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
         let mut this = self.project();
 
         if let Some(state) = this.state.take() {
diff --git a/third_party/rust/futures-util/src/stream/unfold.rs b/third_party/rust/futures-util/src/stream/unfold.rs
index 473bb67bec92d577df515856a400553d6f50acc0..7d8ef6babc442309be81ed88756646d581c0fdf1 100644
--- a/third_party/rust/futures-util/src/stream/unfold.rs
+++ b/third_party/rust/futures-util/src/stream/unfold.rs
@@ -1,3 +1,4 @@
+use super::assert_stream;
 use crate::unfold_state::UnfoldState;
 use core::fmt;
 use core::pin::Pin;
@@ -51,10 +52,7 @@ where
     F: FnMut(T) -> Fut,
     Fut: Future<Output = Option<(Item, T)>>,
 {
-    Unfold {
-        f,
-        state: UnfoldState::Value { value: init },
-    }
+    assert_stream::<Item, _>(Unfold { f, state: UnfoldState::Value { value: init } })
 }
 
 pin_project! {
@@ -73,9 +71,7 @@ where
     Fut: fmt::Debug,
 {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.debug_struct("Unfold")
-            .field("state", &self.state)
-            .finish()
+        f.debug_struct("Unfold").field("state", &self.state).finish()
     }
 }
 
@@ -104,9 +100,7 @@ where
         let mut this = self.project();
 
         if let Some(state) = this.state.as_mut().take_value() {
-            this.state.set(UnfoldState::Future {
-                future: (this.f)(state),
-            });
+            this.state.set(UnfoldState::Future { future: (this.f)(state) });
         }
 
         let step = match this.state.as_mut().project_future() {
diff --git a/third_party/rust/futures-util/src/task/mod.rs b/third_party/rust/futures-util/src/task/mod.rs
index 77e5a966195bbdc3cbe16ff29e8ada3c09be169b..c4afe308cd2d776d05e0d9ac1753da14aadeea7e 100644
--- a/third_party/rust/futures-util/src/task/mod.rs
+++ b/third_party/rust/futures-util/src/task/mod.rs
@@ -10,12 +10,10 @@
 //! The remaining types and traits in the module are used for implementing
 //! executors or dealing with synchronization issues around task wakeup.
 
-pub use futures_core::task::{Context, Poll, Waker, RawWaker, RawWakerVTable};
+#[doc(no_inline)]
+pub use core::task::{Context, Poll, RawWaker, RawWakerVTable, Waker};
 
-pub use futures_task::{
-    Spawn, LocalSpawn, SpawnError,
-    FutureObj, LocalFutureObj, UnsafeFutureObj,
-};
+pub use futures_task::{FutureObj, LocalFutureObj, LocalSpawn, Spawn, SpawnError, UnsafeFutureObj};
 
 pub use futures_task::noop_waker;
 #[cfg(feature = "std")]
@@ -35,4 +33,4 @@ cfg_target_has_atomic! {
 }
 
 mod spawn;
-pub use self::spawn::{SpawnExt, LocalSpawnExt};
+pub use self::spawn::{LocalSpawnExt, SpawnExt};
diff --git a/third_party/rust/futures/.cargo-checksum.json b/third_party/rust/futures/.cargo-checksum.json
index d5749659515b948f0ebe8d263fa5377029e25479..640b94ec50706d7a7f670b4bfbaa3889e4c4ca22 100644
--- a/third_party/rust/futures/.cargo-checksum.json
+++ b/third_party/rust/futures/.cargo-checksum.json
@@ -1 +1 @@
-{"files":{"Cargo.toml":"a6fbdf6b46a8d7c573d34f0a66b61a256286c1daea10e2c53a4a9b1ad3e1a024","LICENSE-APACHE":"275c491d6d1160553c32fd6127061d7f9606c3ea25abfad6ca3f6ed088785427","LICENSE-MIT":"6652c868f35dfe5e8ef636810a4e576b9d663f3a17fb0f5613ad73583e1b88fd","src/lib.rs":"ada4ba0ec233762435320510d5806c80482e6e95278d506472a4cdd33a55b51e","tests/_require_features.rs":"9ada801a1008101250b8a8f8fccfb2bc5d08348d70d50c2b2cd0c208930c07fe","tests/abortable.rs":"51d972ce72b24b6120c7acf038ed58e50491d0c5422c4aefb24eb5d6f53cf660","tests/arc_wake.rs":"7976c1f7178305b1b0aa9bda2c609c5df41f46f56acbc9b20ad2685f9ed8ae82","tests/async_await_macros.rs":"27a8cf6f60c0572f8c0c53dc2956d1637fade5b84107d6cfd0c0476824bc0072","tests/atomic_waker.rs":"8186be2328c6ab4d6da08ff45a71df71ae09b65a41dccf3a95ddcc178a6e09e2","tests/basic_combinators.rs":"6e37b0a62f16abb66576136f248439f4a2d496e337507d1033dc8f0a059b832d","tests/buffer_unordered.rs":"3cc91adb1dbc932fe412d78d5332dcc324c0fc0ae92a6edc46fcaf7d341fef66","tests/compat.rs":"6d9eb9bcd360935e9fe1e59e4d57abda93370d6cb3a80ac5b751a43dbd5d078c","tests/eager_drop.rs":"a19cd1faba9c9150f6f2a704023d553ecb1b0c5bad24a100559e1e8d0b9eb2b6","tests/eventual.rs":"4e3db25ac3f5ebb191caf538c460234eb95413b17441372cc3234d2cbecdc551","tests/fuse.rs":"bb63141f1486e755d0cdea1d93e302ad864a2186aa5287f909a0b3a922e82065","tests/future_obj.rs":"d3583f9caed8369e510650b0a7e260cd70b56faf483b395cfa6f1d7bdb9b5fdc","tests/future_try_flatten_stream.rs":"c3a96f69a68f1f05395831037e33bbacfe547c068f59b219f4e1cb80ad5dc503","tests/futures_ordered.rs":"2fd64d53c6f2b922a7c42211fc8d632c0569eed0bc1ff91739b90727967b8da6","tests/futures_unordered.rs":"db657f4a49ac6bbfb03a53d6a5d1825c1e5958fe900b44373578b66dff786db4","tests/inspect.rs":"edd4127f23a11dbda5e01c398165802744b48c05fdc2102f45d7c4c4dcff4735","tests/io_buf_reader.rs":"80330de847914895f38b211283ca8be01af7651762c63284d0e80b1d642c9c8c","tests/io_buf_writer.rs":"3317297f94589bda55847cd16da6b2ffe56f8b55e82fc6006d9af46309a62e09","tests/io_cursor.rs":"ba680826f1fccec31e7e5d41607042b951ec3737756faa141dbaed4d91a276f8","tests/io_lines.rs":"9836a9b505b8d98b570579858a4ca19e6ee535c03f8bc8fe88a8e3314eb31ae1","tests/io_read.rs":"3e3514a9c36a4eb725c90a7a1603b8cf1f4ae223f6062deef125839cca439b71","tests/io_read_exact.rs":"1c25bcba969d338f6dc4d078d05c1461a0f9cd24fe559fd45df01f780c9da878","tests/io_read_line.rs":"16552df0f0e8cd970eb1932e3bd425c7f3d52bc4245104bc2f39cba11d94d101","tests/io_read_to_end.rs":"a92523170ec52d9a5089959cc8eca73ca6589a27bcbadda5954a902139a0abdd","tests/io_read_to_string.rs":"a425f2352309c56e4927ff6c90dcf9f77632601d2b2441c95eced22ba061b206","tests/io_read_until.rs":"28a7f8a9b3b2c38f4f6c0ecec101241c3532d9c5426ec8fa5e9e92681e56cf24","tests/io_window.rs":"0d18334b1eb35f5e93099e19c0cab22abe5971d8531176b81345fc89d07692a8","tests/io_write.rs":"2676c41b74bb86a225aab4bd855920c696bf6b630227b93b5a686ea91eeab306","tests/join_all.rs":"ad4160975feffe9aa5be75290925cdd8420e90796a579a2557a39ec4b09dbef8","tests/macro_comma_support.rs":"8724177c1d0b1d91205437a5b2577a42a14acd46272e72de61048c5bc61d2401","tests/mutex.rs":"70103a673615e8497ce27fe1dbd12fdc11ef5b8c38b2258047d653deb157434e","tests/object_safety.rs":"9d047190387ed8334113687003c23407c80c858411f5ec7d5c505500f9639dfc","tests/oneshot.rs":"b0c126acac05d01d0d359561ab757256363fadf977b33e7cad3fa1b344cfc0af","tests/ready_queue.rs":"c0162775a4cf35e8131b361cb577a5485875ed1be518440794110c535176f968","tests/recurse.rs":"da05cb74736182fd358e543eecdc039648e31e4818864e3ac6c64b08232ef524","tests/select_all.rs":"ce4853a7f64a84778cc8400c0d46ecb5e4a1c01f94a366f14c374acf709db50e","tests/select_ok.rs":"35161a60336dcba9316f9f90db87634261022846e35c2601eb7ff7aa3661d7c9","tests/shared.rs":"559e568e0275c68adf10ae302b2678f684acb89cd4596182a9bc39f3e7612451","tests/sink.rs":"abc11c02b5d47a13ebe46d6e0f233fa12e857679ce3ec82ea993fe4fc7282eb1","tests/sink_fanout.rs":"5ce5fc6b73f973ef0e4ca51feea41505f91279713de97cbfc470b6880f3d6cd4","tests/split.rs":"72b16e19c1efe1bfab47b723e1ac55a28e69f831734b592887d1474c1adbef1a","tests/stream.rs":"e14a56043168bdeae713b250653946d4ae275ceab2480ff7ae905758445192df","tests/stream_catch_unwind.rs":"d8c8a07b57f67d8905f5a4f471304e84d6495410ae17b1f4ae26707c0327a1c9","tests/stream_into_async_read.rs":"83c05452566edd82f7247f532cb661bd81315411c7ed52cf173552e6d0474f95","tests/stream_peekable.rs":"07d9a42299943f6b616cccdace7ca564b2241ccd639b6baa25b91558cf79ab49","tests/stream_select_all.rs":"d1f6478f17d75c7f31698dcda94151aaad5169a08b3d58f304ede216e098bf47","tests/stream_select_next_some.rs":"d7f6a85eafc7ae950595081a895a8684098f2cf4ec56924037262b1d1b922d59","tests/try_join.rs":"1eda385b53b1d99af140f54ddad26fe652cf558baf43e0aa2a69f6491c1d731f","tests/try_join_all.rs":"1f5e71db731826b8b7adad43d33ccad5b182f38bd40adf08fcadd286b48bee5c","tests/try_stream.rs":"cf9af07a31697a43ab0071d958f71fba6d84b2f3031301fd309821a72f3de5f7","tests/unfold.rs":"b04075b4dce395aea72393ea7d562f7ff63539ef32c6cccdf74c6f6634b19e8b","tests_disabled/all.rs":"038e4dc5b6a3585437a20ef3218bcc3f1010d59395d261ab0a71ecc2530fb348","tests_disabled/bilock.rs":"53e2cc7eb28a21b7b65e4cd2949dada2c505d5649586c8ffe79ca6d8cecba1b3","tests_disabled/stream.rs":"54d19c97376c1d5220b3e8b872da1be615e66a39c6a2e3dc7d12506b21596940"},"package":"da9052a1a50244d8d5aa9bf55cbc2fb6f357c86cc52e46c62ed390a7180cf150"}
\ No newline at end of file
+{"files":{"Cargo.toml":"c3b301df931f984ece9c2f85d3762fa3aeb071427b2fcd5b1b2634904e19afb9","LICENSE-APACHE":"275c491d6d1160553c32fd6127061d7f9606c3ea25abfad6ca3f6ed088785427","LICENSE-MIT":"6652c868f35dfe5e8ef636810a4e576b9d663f3a17fb0f5613ad73583e1b88fd","src/lib.rs":"f479308b46950a34c369a85d379ffc3c2e4a1ff57fbce76d55caa1d597b57f55","tests/_require_features.rs":"5ad24019430b498addfc1fd853e955c7b646d78d0727a8ca29f586c9aab45cff","tests/async_await_macros.rs":"62962e688b74839ea7602327f407cbb53eddfdeec2894f74b143632b206bcbe3","tests/auto_traits.rs":"f542b66df4bba223425e617ac347819fb9d2eae80103c2a92bcc16e0b9c42783","tests/compat.rs":"1ab5af07f13fad9b8fbf29c0df89102687b6abe855ce92bac153d5f916b28689","tests/eager_drop.rs":"dc25d067207c06bbe094752d70bf161e206f00e162ffa3219583c8b4eb0816a1","tests/eventual.rs":"4e3db25ac3f5ebb191caf538c460234eb95413b17441372cc3234d2cbecdc551","tests/future_abortable.rs":"4c81607472a85c5d87a5fe8a510a24cf1e8793fedf7f6cd6741ba1efd66615cd","tests/future_basic_combinators.rs":"4508c1250b85a4f749b7261bbd0ba728d3970e7ba277e84a006e76cf068fb54f","tests/future_fuse.rs":"bb63141f1486e755d0cdea1d93e302ad864a2186aa5287f909a0b3a922e82065","tests/future_inspect.rs":"9c03ceb770ce04fe9fd88a3489362642a0e34ae86a7b4958703e89e8b7a1ecf4","tests/future_join_all.rs":"4c7ab90afc4a0ae721e16f92615cd990a7a608de50b88ba06e6f931478ea04cd","tests/future_obj.rs":"a6aae88a194dc7d3bb961c20db78f180a01796cf7ea4bf106da98c40d89ed36d","tests/future_select_all.rs":"4cefc84d6b7ae2cf0007912cd0325fff6b926a4c26310e7b14a21868de61616f","tests/future_select_ok.rs":"1cabd03268641e1ac42b880344528bad73e3aeb6d6a8a141e652f339dd40184b","tests/future_shared.rs":"778e8763dea8df205581ec8dd9bf1453ca9f17065b496cecb6728147a148efeb","tests/future_try_flatten_stream.rs":"aa4542b5d88f62522b736fac4567613081df45ad3eb54b0b659cdadc9409c4db","tests/future_try_join_all.rs":"2bdd2e7d7f6d8b9c28b05e374906e10a914c2ff36762a0fd81ca4d892fad1341","tests/io_buf_reader.rs":"9e292fd404e4db64b7c7d0e553656ec3029ecf80abc6a67871b95275a6dc576b","tests/io_buf_writer.rs":"8f7a78ab2955d2beb69d0881321d4191235540aef6448e875e7f76a2ffc55b89","tests/io_cursor.rs":"cba5a7b968b9f816ac33316ce1e4da67cb320aa5a21332c0f9a45694fa445dd7","tests/io_lines.rs":"72a310c885591793ed724d0aa2158ac2c9d1af22de417044d96b714f78317586","tests/io_read.rs":"e0a8fa9b27e042f03c9fe14e8f0f329a67e24afad1ce40b906a1ab4d2abef23a","tests/io_read_exact.rs":"42049cd67589992dc09764ffb3836c475115b26dee441fd4cc7e847b2d166667","tests/io_read_line.rs":"f360c30c32fc8c73b371281e86c3f1095da7ef23b702debb30d335046dc77dac","tests/io_read_to_end.rs":"ea3e961e39a0b92930bded05e8ba26e4902461ab53818843d40fae8065b1a803","tests/io_read_to_string.rs":"824921601ac49f15b9a0b349c900f9cc9081cf2646e6a86f443166f841f1320e","tests/io_read_until.rs":"36d9a98149b2410894121ccba49e5134e3209826b2225acfc787016cea2bc92a","tests/io_window.rs":"0d18334b1eb35f5e93099e19c0cab22abe5971d8531176b81345fc89d07692a8","tests/io_write.rs":"701032ff3d5a6e6a3d8cb4e373d1c93e4708f2e5ee0a6742fa626f27b6094b4d","tests/lock_mutex.rs":"055ec0365e7ccd3698aa4b02336fd4dd801017aeb2c19345c58b43415d40fa06","tests/macro_comma_support.rs":"627024ccadfe95194469d5bae2cc29b897b0118a664d7222408a2e234a10e939","tests/object_safety.rs":"9d047190387ed8334113687003c23407c80c858411f5ec7d5c505500f9639dfc","tests/oneshot.rs":"2109a8b3b524f4b36be9fb100f9b8c0d38bbd38d51716adcafdb65994b4a81d6","tests/ready_queue.rs":"cf7047cefab12ff0e2e0ca1ff2123ae87b85a2464fa4c2b6a0e2fc8ee5f25aa1","tests/recurse.rs":"b01b3d73b69ad90a767d297f974dac435817c39e12556fa6a3e6c725dd84f706","tests/sink.rs":"a96700307d6b2bea87c5567a93e0ac81d9ebc7ed354a35fa1b893b39ac8b3759","tests/sink_fanout.rs":"67ab58422040308353955311f75222e55378e4cc34557c7b34140bd20c259132","tests/stream.rs":"78be652d49845b2562e275293398686079b512d88e12661ea644e0881c97be27","tests/stream_abortable.rs":"60052b83b5eeb2395b77bc213f35098d2d5880529f0d83884582a8bbff78b139","tests/stream_buffer_unordered.rs":"143ee19056b9ee9e480903cf4a1b00da7d4e528c5804569bf8c40869e6ac6eed","tests/stream_catch_unwind.rs":"5cdaaf70436c49d3a7107bdc5547ddb8757c3d2057635aded70e485d0cb9cbfc","tests/stream_futures_ordered.rs":"b6f8beafd37e44e82c1f6de322ecba752f9d833d5520ed3ea63c303ea1979644","tests/stream_futures_unordered.rs":"32dac90b8abfe896b07f5bb5c9faa473c174f4df16440cb75aacc0fd683ccd29","tests/stream_into_async_read.rs":"00ecb18289ebc8f46ea0cf43e0dce0631d7698bd1303a7bcd84d0addc9d8b645","tests/stream_peekable.rs":"995ce4a916268b6ac1b3bc16bb1540beea409f333a59c9c9a0a1a72fb2e1cd63","tests/stream_select_all.rs":"3a9045754939da5b30305e78f0571d79a03aaa77030c6ccf82225f076e9843c9","tests/stream_select_next_some.rs":"871edcee3ffc16c697251b29c9ba500aa4e3e503aa738748d7392e3462c82dce","tests/stream_split.rs":"074e9c9b51b6f7ea83d77347b5a0c8d414ca32b90445fec9b85f7f4cd2a6049f","tests/stream_try_stream.rs":"cf9af07a31697a43ab0071d958f71fba6d84b2f3031301fd309821a72f3de5f7","tests/stream_unfold.rs":"7c6fbd10c782828793cbe1eb347ec776d99b185dad498e886f7161da76f76880","tests/task_arc_wake.rs":"5a49d074d1d5d9d5ec383dcd9a3868f636c1d7e34662e2573e467948db126206","tests/task_atomic_waker.rs":"8e85b4bc1360788646a52633dfe896d852773d6b482f81626cf534b97b7d937a","tests/test_macro.rs":"a46a946169c342c576936b60909165a50b94350501280ed9bba89d365af69287","tests/try_join.rs":"66cd0b9f2c27129d82f0b6b61a01ddfbcd6d23c8924e3fcf06303d2c3561996f","tests_disabled/all.rs":"ddcd8fefb0d4a4a91a78328e7e652c35f93dc3669639d76fa0f56452b51abc23","tests_disabled/bilock.rs":"74e598568403df45460085166b7b90012d40dae8670b1c8dec126322a4ce171f","tests_disabled/stream.rs":"10e701f0eb83bcc6ec74d96529ad7dad5ad38bf5826574049501aeb07c5b76fa"},"package":"0e7e43a803dae2fa37c1f6a8fe121e1f7bf9548b4dfc0522a42f34145dadfc27"}
\ No newline at end of file
diff --git a/third_party/rust/futures/Cargo.toml b/third_party/rust/futures/Cargo.toml
index bb846bf35eb055239da32d63449d34b12c993729..fec0a465ba96c7a45b43d1d115b63074225bc8de 100644
--- a/third_party/rust/futures/Cargo.toml
+++ b/third_party/rust/futures/Cargo.toml
@@ -13,7 +13,7 @@
 [package]
 edition = "2018"
 name = "futures"
-version = "0.3.12"
+version = "0.3.15"
 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"
@@ -30,33 +30,33 @@ rustdoc-args = ["--cfg", "docsrs"]
 [package.metadata.playground]
 features = ["std", "async-await", "compat", "io-compat", "executor", "thread-pool"]
 [dependencies.futures-channel]
-version = "0.3.12"
+version = "0.3.15"
 features = ["sink"]
 default-features = false
 
 [dependencies.futures-core]
-version = "0.3.12"
+version = "0.3.15"
 default-features = false
 
 [dependencies.futures-executor]
-version = "0.3.12"
+version = "0.3.15"
 optional = true
 default-features = false
 
 [dependencies.futures-io]
-version = "0.3.12"
+version = "0.3.15"
 default-features = false
 
 [dependencies.futures-sink]
-version = "0.3.12"
+version = "0.3.15"
 default-features = false
 
 [dependencies.futures-task]
-version = "0.3.12"
+version = "0.3.15"
 default-features = false
 
 [dependencies.futures-util]
-version = "0.3.12"
+version = "0.3.15"
 features = ["sink"]
 default-features = false
 [dev-dependencies.assert_matches]
@@ -68,6 +68,9 @@ version = "1.0.1"
 [dev-dependencies.pin-utils]
 version = "0.1.0"
 
+[dev-dependencies.static_assertions]
+version = "1"
+
 [dev-dependencies.tokio]
 version = "0.1.11"
 
@@ -75,7 +78,7 @@ version = "0.1.11"
 alloc = ["futures-core/alloc", "futures-task/alloc", "futures-sink/alloc", "futures-channel/alloc", "futures-util/alloc"]
 async-await = ["futures-util/async-await", "futures-util/async-await-macro"]
 bilock = ["futures-util/bilock"]
-cfg-target-has-atomic = ["futures-core/cfg-target-has-atomic", "futures-task/cfg-target-has-atomic", "futures-channel/cfg-target-has-atomic", "futures-util/cfg-target-has-atomic"]
+cfg-target-has-atomic = []
 compat = ["std", "futures-util/compat"]
 default = ["std", "async-await", "executor"]
 executor = ["std", "futures-executor/std"]
diff --git a/third_party/rust/futures/src/lib.rs b/third_party/rust/futures/src/lib.rs
index de29ace218a4e6ba206d75c8ace11bfc2c882390..d15c16c3778bfa2972f52fb71677926ec8d76351 100644
--- a/third_party/rust/futures/src/lib.rs
+++ b/third_party/rust/futures/src/lib.rs
@@ -3,12 +3,12 @@
 //! This crate provides a number of core abstractions for writing asynchronous
 //! code:
 //!
-//! - [Futures](crate::future::Future) are single eventual values produced by
+//! - [Futures](crate::future) are single eventual values produced by
 //!   asynchronous computations. Some programming languages (e.g. JavaScript)
 //!   call this concept "promise".
-//! - [Streams](crate::stream::Stream) represent a series of values
+//! - [Streams](crate::stream) represent a series of values
 //!   produced asynchronously.
-//! - [Sinks](crate::sink::Sink) provide support for asynchronous writing of
+//! - [Sinks](crate::sink) provide support for asynchronous writing of
 //!   data.
 //! - [Executors](crate::executor) are responsible for running asynchronous
 //!   tasks.
@@ -29,7 +29,7 @@
 //! # use futures::executor; ///standard executors to provide a context for futures and streams
 //! # use futures::executor::ThreadPool;
 //! # use futures::StreamExt;
-//!
+//! #
 //! fn main() {
 //!     let pool = ThreadPool::new().expect("Failed to build pool");
 //!     let (tx, rx) = mpsc::unbounded::<i32>();
@@ -78,22 +78,15 @@
 //! The majority of examples and code snippets in this crate assume that they are
 //! inside an async block as written above.
 
-#![cfg_attr(feature = "cfg-target-has-atomic", feature(cfg_target_has_atomic))]
 #![cfg_attr(feature = "read-initializer", feature(read_initializer))]
-
 #![cfg_attr(not(feature = "std"), no_std)]
-
 #![warn(missing_docs, missing_debug_implementations, rust_2018_idioms, unreachable_pub)]
 // It cannot be included in the published code because this lints have false positives in the minimum required version.
 #![cfg_attr(test, warn(single_use_lifetimes))]
 #![warn(clippy::all)]
 #![doc(test(attr(deny(warnings), allow(dead_code, unused_assignments, unused_variables))))]
-
 #![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");
-
 #[cfg(all(feature = "bilock", not(feature = "unstable")))]
 compile_error!("The `bilock` feature requires the `unstable` feature as an explicit opt-in to unstable features");
 
diff --git a/third_party/rust/futures/tests/_require_features.rs b/third_party/rust/futures/tests/_require_features.rs
index da76dcd1e9ac37b90b1ea8e0603f110b85c3cd31..8046cc99a41b7f55c62256855a5755c494dcf04d 100644
--- a/third_party/rust/futures/tests/_require_features.rs
+++ b/third_party/rust/futures/tests/_require_features.rs
@@ -1,8 +1,13 @@
 #[cfg(not(all(
-    feature = "std", feature = "alloc", feature = "async-await",
-    feature = "compat", feature = "io-compat",
-    feature = "executor", feature = "thread-pool",
+    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: \
+compile_error!(
+    "`futures` tests must have all stable features activated: \
     use `--all-features` or `--features default,thread-pool,io-compat`"
 );
diff --git a/third_party/rust/futures/tests/arc_wake.rs b/third_party/rust/futures/tests/arc_wake.rs
deleted file mode 100644
index d19a83dfac54ff784f157cde25864836e4da9a56..0000000000000000000000000000000000000000
--- a/third_party/rust/futures/tests/arc_wake.rs
+++ /dev/null
@@ -1,82 +0,0 @@
-mod countingwaker {
-    use futures::task::{self, ArcWake, Waker};
-    use std::sync::{Arc, Mutex};
-
-    struct CountingWaker {
-        nr_wake: Mutex<i32>,
-    }
-
-    impl CountingWaker {
-        fn new() -> Self {
-            Self {
-                nr_wake: Mutex::new(0),
-            }
-        }
-
-        fn wakes(&self) -> i32 {
-            *self.nr_wake.lock().unwrap()
-        }
-    }
-
-    impl ArcWake for CountingWaker {
-        fn wake_by_ref(arc_self: &Arc<Self>) {
-            let mut lock = arc_self.nr_wake.lock().unwrap();
-            *lock += 1;
-        }
-    }
-
-    #[test]
-    fn create_from_arc() {
-        let some_w = Arc::new(CountingWaker::new());
-
-        let w1: Waker = task::waker(some_w.clone());
-        assert_eq!(2, Arc::strong_count(&some_w));
-        w1.wake_by_ref();
-        assert_eq!(1, some_w.wakes());
-
-        let w2 = w1.clone();
-        assert_eq!(3, Arc::strong_count(&some_w));
-
-        w2.wake_by_ref();
-        assert_eq!(2, some_w.wakes());
-
-        drop(w2);
-        assert_eq!(2, Arc::strong_count(&some_w));
-        drop(w1);
-        assert_eq!(1, Arc::strong_count(&some_w));
-    }
-
-    #[test]
-    fn ref_wake_same() {
-        let some_w = Arc::new(CountingWaker::new());
-
-        let w1: Waker = task::waker(some_w.clone());
-        let w2 = task::waker_ref(&some_w);
-        let w3 = w2.clone();
-
-        assert!(w1.will_wake(&w2));
-        assert!(w2.will_wake(&w3));
-    }
-}
-
-#[test]
-fn proper_refcount_on_wake_panic() {
-    use futures::task::{self, ArcWake, Waker};
-    use std::sync::Arc;
-
-    struct PanicWaker;
-
-    impl ArcWake for PanicWaker {
-        fn wake_by_ref(_arc_self: &Arc<Self>) {
-            panic!("WAKE UP");
-        }
-    }
-
-    let some_w = Arc::new(PanicWaker);
-
-    let w1: Waker = task::waker(some_w.clone());
-    assert_eq!("WAKE UP", *std::panic::catch_unwind(|| w1.wake_by_ref()).unwrap_err().downcast::<&str>().unwrap());
-    assert_eq!(2, Arc::strong_count(&some_w)); // some_w + w1
-    drop(w1);
-    assert_eq!(1, Arc::strong_count(&some_w)); // some_w
-}
diff --git a/third_party/rust/futures/tests/async_await_macros.rs b/third_party/rust/futures/tests/async_await_macros.rs
index bd586d6e52baecd251c69a7265aec8621fb3bf79..3e461b50ebdc749f8ad0f69b1391695bb4ab357d 100644
--- a/third_party/rust/futures/tests/async_await_macros.rs
+++ b/third_party/rust/futures/tests/async_await_macros.rs
@@ -1,9 +1,14 @@
+use futures::channel::{mpsc, oneshot};
+use futures::executor::block_on;
+use futures::future::{self, poll_fn, FutureExt};
+use futures::sink::SinkExt;
+use futures::stream::StreamExt;
+use futures::task::{Context, Poll};
+use futures::{join, pending, pin_mut, poll, select, select_biased, try_join};
+use std::mem;
+
 #[test]
 fn poll_and_pending() {
-    use futures::{pending, pin_mut, poll};
-    use futures::executor::block_on;
-    use futures::task::Poll;
-
     let pending_once = async { pending!() };
     block_on(async {
         pin_mut!(pending_once);
@@ -14,11 +19,6 @@ fn poll_and_pending() {
 
 #[test]
 fn join() {
-    use futures::{pin_mut, poll, join};
-    use futures::channel::oneshot;
-    use futures::executor::block_on;
-    use futures::task::Poll;
-
     let (tx1, rx1) = oneshot::channel::<i32>();
     let (tx2, rx2) = oneshot::channel::<i32>();
 
@@ -39,11 +39,6 @@ fn join() {
 
 #[test]
 fn select() {
-    use futures::select;
-    use futures::channel::oneshot;
-    use futures::executor::block_on;
-    use futures::future::FutureExt;
-
     let (tx1, rx1) = oneshot::channel::<i32>();
     let (_tx2, rx2) = oneshot::channel::<i32>();
     tx1.send(1).unwrap();
@@ -62,11 +57,6 @@ fn select() {
 
 #[test]
 fn select_biased() {
-    use futures::channel::oneshot;
-    use futures::executor::block_on;
-    use futures::future::FutureExt;
-    use futures::select_biased;
-
     let (tx1, rx1) = oneshot::channel::<i32>();
     let (_tx2, rx2) = oneshot::channel::<i32>();
     tx1.send(1).unwrap();
@@ -85,12 +75,6 @@ fn select_biased() {
 
 #[test]
 fn select_streams() {
-    use futures::select;
-    use futures::channel::mpsc;
-    use futures::executor::block_on;
-    use futures::sink::SinkExt;
-    use futures::stream::StreamExt;
-
     let (mut tx1, rx1) = mpsc::channel::<i32>(1);
     let (mut tx2, rx2) = mpsc::channel::<i32>(1);
     let mut rx1 = rx1.fuse();
@@ -134,11 +118,6 @@ fn select_streams() {
 
 #[test]
 fn select_can_move_uncompleted_futures() {
-    use futures::select;
-    use futures::channel::oneshot;
-    use futures::executor::block_on;
-    use futures::future::FutureExt;
-
     let (tx1, rx1) = oneshot::channel::<i32>();
     let (tx2, rx2) = oneshot::channel::<i32>();
     tx1.send(1).unwrap();
@@ -165,10 +144,6 @@ fn select_can_move_uncompleted_futures() {
 
 #[test]
 fn select_nested() {
-    use futures::select;
-    use futures::executor::block_on;
-    use futures::future;
-
     let mut outer_fut = future::ready(1);
     let mut inner_fut = future::ready(2);
     let res = block_on(async {
@@ -185,16 +160,13 @@ fn select_nested() {
 
 #[test]
 fn select_size() {
-    use futures::select;
-    use futures::future;
-
     let fut = async {
         let mut ready = future::ready(0i32);
         select! {
             _ = ready => {},
         }
     };
-    assert_eq!(::std::mem::size_of_val(&fut), 24);
+    assert_eq!(mem::size_of_val(&fut), 24);
 
     let fut = async {
         let mut ready1 = future::ready(0i32);
@@ -204,19 +176,13 @@ fn select_size() {
             _ = ready2 => {},
         }
     };
-    assert_eq!(::std::mem::size_of_val(&fut), 40);
+    assert_eq!(mem::size_of_val(&fut), 40);
 }
 
 #[test]
 fn select_on_non_unpin_expressions() {
-    use futures::select;
-    use futures::executor::block_on;
-    use futures::future::FutureExt;
-
     // The returned Future is !Unpin
-    let make_non_unpin_fut = || { async {
-        5
-    }};
+    let make_non_unpin_fut = || async { 5 };
 
     let res = block_on(async {
         let select_res;
@@ -231,14 +197,8 @@ fn select_on_non_unpin_expressions() {
 
 #[test]
 fn select_on_non_unpin_expressions_with_default() {
-    use futures::select;
-    use futures::executor::block_on;
-    use futures::future::FutureExt;
-
     // The returned Future is !Unpin
-    let make_non_unpin_fut = || { async {
-        5
-    }};
+    let make_non_unpin_fut = || async { 5 };
 
     let res = block_on(async {
         let select_res;
@@ -254,13 +214,8 @@ fn select_on_non_unpin_expressions_with_default() {
 
 #[test]
 fn select_on_non_unpin_size() {
-    use futures::select;
-    use futures::future::FutureExt;
-
     // The returned Future is !Unpin
-    let make_non_unpin_fut = || { async {
-        5
-    }};
+    let make_non_unpin_fut = || async { 5 };
 
     let fut = async {
         let select_res;
@@ -271,15 +226,11 @@ fn select_on_non_unpin_size() {
         select_res
     };
 
-    assert_eq!(32, std::mem::size_of_val(&fut));
+    assert_eq!(32, mem::size_of_val(&fut));
 }
 
 #[test]
 fn select_can_be_used_as_expression() {
-    use futures::select;
-    use futures::executor::block_on;
-    use futures::future;
-
     block_on(async {
         let res = select! {
             x = future::ready(7) => x,
@@ -291,11 +242,6 @@ fn select_can_be_used_as_expression() {
 
 #[test]
 fn select_with_default_can_be_used_as_expression() {
-    use futures::select;
-    use futures::executor::block_on;
-    use futures::future::{FutureExt, poll_fn};
-    use futures::task::{Context, Poll};
-
     fn poll_always_pending<T>(_cx: &mut Context<'_>) -> Poll<T> {
         Poll::Pending
     }
@@ -312,10 +258,6 @@ fn select_with_default_can_be_used_as_expression() {
 
 #[test]
 fn select_with_complete_can_be_used_as_expression() {
-    use futures::select;
-    use futures::executor::block_on;
-    use futures::future;
-
     block_on(async {
         let res = select! {
             x = future::pending::<i32>() => x,
@@ -330,10 +272,6 @@ fn select_with_complete_can_be_used_as_expression() {
 #[test]
 #[allow(unused_assignments)]
 fn select_on_mutable_borrowing_future_with_same_borrow_in_block() {
-    use futures::select;
-    use futures::executor::block_on;
-    use futures::future::FutureExt;
-
     async fn require_mutable(_: &mut i32) {}
     async fn async_noop() {}
 
@@ -351,10 +289,6 @@ fn select_on_mutable_borrowing_future_with_same_borrow_in_block() {
 #[test]
 #[allow(unused_assignments)]
 fn select_on_mutable_borrowing_future_with_same_borrow_in_block_and_default() {
-    use futures::select;
-    use futures::executor::block_on;
-    use futures::future::FutureExt;
-
     async fn require_mutable(_: &mut i32) {}
     async fn async_noop() {}
 
@@ -374,59 +308,42 @@ fn select_on_mutable_borrowing_future_with_same_borrow_in_block_and_default() {
 
 #[test]
 fn join_size() {
-    use futures::join;
-    use futures::future;
-
     let fut = async {
         let ready = future::ready(0i32);
         join!(ready)
     };
-    assert_eq!(::std::mem::size_of_val(&fut), 16);
+    assert_eq!(mem::size_of_val(&fut), 16);
 
     let fut = async {
         let ready1 = future::ready(0i32);
         let ready2 = future::ready(0i32);
         join!(ready1, ready2)
     };
-    assert_eq!(::std::mem::size_of_val(&fut), 28);
+    assert_eq!(mem::size_of_val(&fut), 28);
 }
 
 #[test]
 fn try_join_size() {
-    use futures::try_join;
-    use futures::future;
-
     let fut = async {
         let ready = future::ready(Ok::<i32, i32>(0));
         try_join!(ready)
     };
-    assert_eq!(::std::mem::size_of_val(&fut), 16);
+    assert_eq!(mem::size_of_val(&fut), 16);
 
     let fut = async {
         let ready1 = future::ready(Ok::<i32, i32>(0));
         let ready2 = future::ready(Ok::<i32, i32>(0));
         try_join!(ready1, ready2)
     };
-    assert_eq!(::std::mem::size_of_val(&fut), 28);
+    assert_eq!(mem::size_of_val(&fut), 28);
 }
 
 #[test]
 fn join_doesnt_require_unpin() {
-    use futures::join;
-
-    let _ = async {
-        join!(async {}, async {})
-    };
+    let _ = async { join!(async {}, async {}) };
 }
 
 #[test]
 fn try_join_doesnt_require_unpin() {
-    use futures::try_join;
-
-    let _ = async {
-        try_join!(
-            async { Ok::<(), ()>(()) },
-            async { Ok::<(), ()>(()) },
-        )
-    };
+    let _ = async { try_join!(async { Ok::<(), ()>(()) }, async { Ok::<(), ()>(()) },) };
 }
diff --git a/third_party/rust/futures/tests/auto_traits.rs b/third_party/rust/futures/tests/auto_traits.rs
new file mode 100644
index 0000000000000000000000000000000000000000..e0192a118b8a0db5c2c46c21f9a8afff6cd64a0f
--- /dev/null
+++ b/third_party/rust/futures/tests/auto_traits.rs
@@ -0,0 +1,1863 @@
+#![cfg(feature = "compat")]
+
+//! Assert Send/Sync/Unpin for all public types.
+
+use futures::{
+    future::Future,
+    sink::Sink,
+    stream::Stream,
+    task::{Context, Poll},
+};
+use static_assertions::{assert_impl_all as assert_impl, assert_not_impl_all as assert_not_impl};
+use std::marker::PhantomPinned;
+use std::{marker::PhantomData, pin::Pin};
+
+pub type LocalFuture<T = *const ()> = Pin<Box<dyn Future<Output = T>>>;
+pub type LocalTryFuture<T = *const (), E = *const ()> = LocalFuture<Result<T, E>>;
+pub type SendFuture<T = *const ()> = Pin<Box<dyn Future<Output = T> + Send>>;
+pub type SendTryFuture<T = *const (), E = *const ()> = SendFuture<Result<T, E>>;
+pub type SyncFuture<T = *const ()> = Pin<Box<dyn Future<Output = T> + Sync>>;
+pub type SyncTryFuture<T = *const (), E = *const ()> = SyncFuture<Result<T, E>>;
+pub type UnpinFuture<T = PhantomPinned> = LocalFuture<T>;
+pub type UnpinTryFuture<T = PhantomPinned, E = PhantomPinned> = UnpinFuture<Result<T, E>>;
+pub struct PinnedFuture<T = PhantomPinned>(PhantomPinned, PhantomData<T>);
+impl<T> Future for PinnedFuture<T> {
+    type Output = T;
+    fn poll(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<Self::Output> {
+        unimplemented!()
+    }
+}
+pub type PinnedTryFuture<T = PhantomPinned, E = PhantomPinned> = PinnedFuture<Result<T, E>>;
+
+pub type LocalStream<T = *const ()> = Pin<Box<dyn Stream<Item = T>>>;
+pub type LocalTryStream<T = *const (), E = *const ()> = LocalStream<Result<T, E>>;
+pub type SendStream<T = *const ()> = Pin<Box<dyn Stream<Item = T> + Send>>;
+pub type SendTryStream<T = *const (), E = *const ()> = SendStream<Result<T, E>>;
+pub type SyncStream<T = *const ()> = Pin<Box<dyn Stream<Item = T> + Sync>>;
+pub type SyncTryStream<T = *const (), E = *const ()> = SyncStream<Result<T, E>>;
+pub type UnpinStream<T = PhantomPinned> = LocalStream<T>;
+pub type UnpinTryStream<T = PhantomPinned, E = PhantomPinned> = UnpinStream<Result<T, E>>;
+pub struct PinnedStream<T = PhantomPinned>(PhantomPinned, PhantomData<T>);
+impl<T> Stream for PinnedStream<T> {
+    type Item = T;
+    fn poll_next(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<Option<Self::Item>> {
+        unimplemented!()
+    }
+}
+pub type PinnedTryStream<T = PhantomPinned, E = PhantomPinned> = PinnedStream<Result<T, E>>;
+
+pub type LocalSink<T = *const (), E = *const ()> = Pin<Box<dyn Sink<T, Error = E>>>;
+pub type SendSink<T = *const (), E = *const ()> = Pin<Box<dyn Sink<T, Error = E> + Send>>;
+pub type SyncSink<T = *const (), E = *const ()> = Pin<Box<dyn Sink<T, Error = E> + Sync>>;
+pub type UnpinSink<T = PhantomPinned, E = PhantomPinned> = LocalSink<T, E>;
+pub struct PinnedSink<T = PhantomPinned, E = PhantomPinned>(PhantomPinned, PhantomData<(T, E)>);
+impl<T, E> Sink<T> for PinnedSink<T, E> {
+    type Error = E;
+    fn poll_ready(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
+        unimplemented!()
+    }
+    fn start_send(self: Pin<&mut Self>, _: T) -> Result<(), Self::Error> {
+        unimplemented!()
+    }
+    fn poll_flush(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
+        unimplemented!()
+    }
+    fn poll_close(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
+        unimplemented!()
+    }
+}
+
+/// Assert Send/Sync/Unpin for all public types in `futures::channel`.
+pub mod channel {
+    use super::*;
+    use futures::channel::*;
+
+    assert_impl!(mpsc::Receiver<()>: Send);
+    assert_not_impl!(mpsc::Receiver<*const ()>: Send);
+    assert_impl!(mpsc::Receiver<()>: Sync);
+    assert_not_impl!(mpsc::Receiver<*const ()>: Sync);
+    assert_impl!(mpsc::Receiver<PhantomPinned>: Unpin);
+
+    assert_impl!(mpsc::SendError: Send);
+    assert_impl!(mpsc::SendError: Sync);
+    assert_impl!(mpsc::SendError: Unpin);
+
+    assert_impl!(mpsc::Sender<()>: Send);
+    assert_not_impl!(mpsc::Sender<*const ()>: Send);
+    assert_impl!(mpsc::Sender<()>: Sync);
+    assert_not_impl!(mpsc::Sender<*const ()>: Sync);
+    assert_impl!(mpsc::Sender<PhantomPinned>: Unpin);
+
+    assert_impl!(mpsc::TryRecvError: Send);
+    assert_impl!(mpsc::TryRecvError: Sync);
+    assert_impl!(mpsc::TryRecvError: Unpin);
+
+    assert_impl!(mpsc::TrySendError<()>: Send);
+    assert_not_impl!(mpsc::TrySendError<*const ()>: Send);
+    assert_impl!(mpsc::TrySendError<()>: Sync);
+    assert_not_impl!(mpsc::TrySendError<*const ()>: Sync);
+    assert_impl!(mpsc::TrySendError<()>: Unpin);
+    assert_not_impl!(mpsc::TrySendError<PhantomPinned>: Unpin);
+
+    assert_impl!(mpsc::UnboundedReceiver<()>: Send);
+    assert_not_impl!(mpsc::UnboundedReceiver<*const ()>: Send);
+    assert_impl!(mpsc::UnboundedReceiver<()>: Sync);
+    assert_not_impl!(mpsc::UnboundedReceiver<*const ()>: Sync);
+    assert_impl!(mpsc::UnboundedReceiver<PhantomPinned>: Unpin);
+
+    assert_impl!(mpsc::UnboundedReceiver<()>: Send);
+    assert_not_impl!(mpsc::UnboundedReceiver<*const ()>: Send);
+    assert_impl!(mpsc::UnboundedReceiver<()>: Sync);
+    assert_not_impl!(mpsc::UnboundedReceiver<*const ()>: Sync);
+    assert_impl!(mpsc::UnboundedReceiver<PhantomPinned>: Unpin);
+
+    assert_impl!(oneshot::Canceled: Send);
+    assert_impl!(oneshot::Canceled: Sync);
+    assert_impl!(oneshot::Canceled: Unpin);
+
+    assert_impl!(oneshot::Cancellation<()>: Send);
+    assert_not_impl!(oneshot::Cancellation<*const ()>: Send);
+    assert_impl!(oneshot::Cancellation<()>: Sync);
+    assert_not_impl!(oneshot::Cancellation<*const ()>: Sync);
+    assert_impl!(oneshot::Cancellation<PhantomPinned>: Unpin);
+
+    assert_impl!(oneshot::Receiver<()>: Send);
+    assert_not_impl!(oneshot::Receiver<*const ()>: Send);
+    assert_impl!(oneshot::Receiver<()>: Sync);
+    assert_not_impl!(oneshot::Receiver<*const ()>: Sync);
+    assert_impl!(oneshot::Receiver<PhantomPinned>: Unpin);
+
+    assert_impl!(oneshot::Sender<()>: Send);
+    assert_not_impl!(oneshot::Sender<*const ()>: Send);
+    assert_impl!(oneshot::Sender<()>: Sync);
+    assert_not_impl!(oneshot::Sender<*const ()>: Sync);
+    assert_impl!(oneshot::Sender<PhantomPinned>: Unpin);
+}
+
+/// Assert Send/Sync/Unpin for all public types in `futures::compat`.
+pub mod compat {
+    use super::*;
+    use futures::compat::*;
+
+    assert_impl!(Compat<()>: Send);
+    assert_not_impl!(Compat<*const ()>: Send);
+    assert_impl!(Compat<()>: Sync);
+    assert_not_impl!(Compat<*const ()>: Sync);
+    assert_impl!(Compat<()>: Unpin);
+    assert_not_impl!(Compat<PhantomPinned>: Unpin);
+
+    assert_impl!(Compat01As03<()>: Send);
+    assert_not_impl!(Compat01As03<*const ()>: Send);
+    assert_not_impl!(Compat01As03<()>: Sync);
+    assert_impl!(Compat01As03<PhantomPinned>: Unpin);
+
+    assert_impl!(Compat01As03Sink<(), ()>: Send);
+    assert_not_impl!(Compat01As03Sink<(), *const ()>: Send);
+    assert_not_impl!(Compat01As03Sink<*const (), ()>: Send);
+    assert_not_impl!(Compat01As03Sink<(), ()>: Sync);
+    assert_impl!(Compat01As03Sink<PhantomPinned, PhantomPinned>: Unpin);
+
+    assert_impl!(CompatSink<(), *const ()>: Send);
+    assert_not_impl!(CompatSink<*const (), ()>: Send);
+    assert_impl!(CompatSink<(), *const ()>: Sync);
+    assert_not_impl!(CompatSink<*const (), ()>: Sync);
+    assert_impl!(CompatSink<(), PhantomPinned>: Unpin);
+    assert_not_impl!(CompatSink<PhantomPinned, ()>: Unpin);
+
+    assert_impl!(Executor01As03<()>: Send);
+    assert_not_impl!(Executor01As03<*const ()>: Send);
+    assert_impl!(Executor01As03<()>: Sync);
+    assert_not_impl!(Executor01As03<*const ()>: Sync);
+    assert_impl!(Executor01As03<()>: Unpin);
+    assert_not_impl!(Executor01As03<PhantomPinned>: Unpin);
+
+    assert_impl!(Executor01Future: Send);
+    assert_not_impl!(Executor01Future: Sync);
+    assert_impl!(Executor01Future: Unpin);
+}
+
+/// Assert Send/Sync/Unpin for all public types in `futures::executor`.
+pub mod executor {
+    use super::*;
+    use futures::executor::*;
+
+    assert_impl!(BlockingStream<SendStream>: Send);
+    assert_not_impl!(BlockingStream<LocalStream>: Send);
+    assert_impl!(BlockingStream<SyncStream>: Sync);
+    assert_not_impl!(BlockingStream<LocalStream>: Sync);
+    assert_impl!(BlockingStream<UnpinStream>: Unpin);
+    // BlockingStream requires `S: Unpin`
+    // assert_not_impl!(BlockingStream<PinnedStream>: Unpin);
+
+    assert_impl!(Enter: Send);
+    assert_impl!(Enter: Sync);
+    assert_impl!(Enter: Unpin);
+
+    assert_impl!(EnterError: Send);
+    assert_impl!(EnterError: Sync);
+    assert_impl!(EnterError: Unpin);
+
+    assert_not_impl!(LocalPool: Send);
+    assert_not_impl!(LocalPool: Sync);
+    assert_impl!(LocalPool: Unpin);
+
+    assert_not_impl!(LocalSpawner: Send);
+    assert_not_impl!(LocalSpawner: Sync);
+    assert_impl!(LocalSpawner: Unpin);
+
+    assert_impl!(ThreadPool: Send);
+    assert_impl!(ThreadPool: Sync);
+    assert_impl!(ThreadPool: Unpin);
+
+    assert_impl!(ThreadPoolBuilder: Send);
+    assert_impl!(ThreadPoolBuilder: Sync);
+    assert_impl!(ThreadPoolBuilder: Unpin);
+}
+
+/// Assert Send/Sync/Unpin for all public types in `futures::future`.
+pub mod future {
+    use super::*;
+    use futures::future::*;
+
+    assert_impl!(AbortHandle: Send);
+    assert_impl!(AbortHandle: Sync);
+    assert_impl!(AbortHandle: Unpin);
+
+    assert_impl!(AbortRegistration: Send);
+    assert_impl!(AbortRegistration: Sync);
+    assert_impl!(AbortRegistration: Unpin);
+
+    assert_impl!(Abortable<SendFuture>: Send);
+    assert_not_impl!(Abortable<LocalFuture>: Send);
+    assert_impl!(Abortable<SyncFuture>: Sync);
+    assert_not_impl!(Abortable<LocalFuture>: Sync);
+    assert_impl!(Abortable<UnpinFuture>: Unpin);
+    assert_not_impl!(Abortable<PinnedFuture>: Unpin);
+
+    assert_impl!(Aborted: Send);
+    assert_impl!(Aborted: Sync);
+    assert_impl!(Aborted: Unpin);
+
+    assert_impl!(AndThen<SendFuture, SendFuture, ()>: Send);
+    assert_not_impl!(AndThen<SendFuture, LocalFuture, ()>: Send);
+    assert_not_impl!(AndThen<LocalFuture, SendFuture, ()>: Send);
+    assert_not_impl!(AndThen<SendFuture, SendFuture, *const ()>: Send);
+    assert_impl!(AndThen<SyncFuture, SyncFuture, ()>: Sync);
+    assert_not_impl!(AndThen<SyncFuture, LocalFuture, ()>: Sync);
+    assert_not_impl!(AndThen<LocalFuture, SyncFuture, ()>: Sync);
+    assert_not_impl!(AndThen<SyncFuture, SyncFuture, *const ()>: Sync);
+    assert_impl!(AndThen<UnpinFuture, UnpinFuture, PhantomPinned>: Unpin);
+    assert_not_impl!(AndThen<PinnedFuture, UnpinFuture, PhantomPinned>: Unpin);
+    assert_not_impl!(AndThen<UnpinFuture, PinnedFuture, PhantomPinned>: Unpin);
+
+    assert_impl!(CatchUnwind<SendFuture>: Send);
+    assert_not_impl!(CatchUnwind<LocalFuture>: Send);
+    assert_impl!(CatchUnwind<SyncFuture>: Sync);
+    assert_not_impl!(CatchUnwind<LocalFuture>: Sync);
+    assert_impl!(CatchUnwind<UnpinFuture>: Unpin);
+    assert_not_impl!(CatchUnwind<PinnedFuture>: Unpin);
+
+    assert_impl!(ErrInto<SendTryFuture, *const ()>: Send);
+    assert_not_impl!(ErrInto<LocalTryFuture, ()>: Send);
+    assert_impl!(ErrInto<SyncTryFuture, *const ()>: Sync);
+    assert_not_impl!(ErrInto<LocalTryFuture, ()>: Sync);
+    assert_impl!(ErrInto<UnpinTryFuture, PhantomPinned>: Unpin);
+    assert_not_impl!(ErrInto<PinnedTryFuture, PhantomPinned>: Unpin);
+
+    assert_impl!(Flatten<SendFuture<()>>: Send);
+    assert_not_impl!(Flatten<LocalFuture>: Send);
+    assert_not_impl!(Flatten<SendFuture>: Send);
+    assert_impl!(Flatten<SyncFuture<()>>: Sync);
+    assert_not_impl!(Flatten<LocalFuture>: Sync);
+    assert_not_impl!(Flatten<SyncFuture>: Sync);
+    assert_impl!(Flatten<UnpinFuture<()>>: Unpin);
+    assert_not_impl!(Flatten<PinnedFuture>: Unpin);
+    assert_not_impl!(Flatten<UnpinFuture>: Unpin);
+
+    assert_impl!(FlattenSink<SendFuture, ()>: Send);
+    assert_not_impl!(FlattenSink<SendFuture, *const ()>: Send);
+    assert_not_impl!(FlattenSink<LocalFuture, ()>: Send);
+    assert_impl!(FlattenSink<SyncFuture, ()>: Sync);
+    assert_not_impl!(FlattenSink<SyncFuture, *const ()>: Sync);
+    assert_not_impl!(FlattenSink<LocalFuture, ()>: Sync);
+    assert_impl!(FlattenSink<UnpinFuture, ()>: Unpin);
+    assert_not_impl!(FlattenSink<UnpinFuture, PhantomPinned>: Unpin);
+    assert_not_impl!(FlattenSink<PinnedFuture, ()>: Unpin);
+
+    assert_impl!(FlattenStream<SendFuture<()>>: Send);
+    assert_not_impl!(FlattenStream<LocalFuture>: Send);
+    assert_not_impl!(FlattenStream<SendFuture>: Send);
+    assert_impl!(FlattenStream<SyncFuture<()>>: Sync);
+    assert_not_impl!(FlattenStream<LocalFuture>: Sync);
+    assert_not_impl!(FlattenStream<SyncFuture>: Sync);
+    assert_impl!(FlattenStream<UnpinFuture<()>>: Unpin);
+    assert_not_impl!(FlattenStream<PinnedFuture>: Unpin);
+    assert_not_impl!(FlattenStream<UnpinFuture>: Unpin);
+
+    assert_impl!(Fuse<SendFuture>: Send);
+    assert_not_impl!(Fuse<LocalFuture>: Send);
+    assert_impl!(Fuse<SyncFuture>: Sync);
+    assert_not_impl!(Fuse<LocalFuture>: Sync);
+    assert_impl!(Fuse<UnpinFuture>: Unpin);
+    assert_not_impl!(Fuse<PinnedFuture>: Unpin);
+
+    assert_impl!(FutureObj<*const ()>: Send);
+    assert_not_impl!(FutureObj<()>: Sync);
+    assert_impl!(FutureObj<PhantomPinned>: Unpin);
+
+    assert_impl!(Inspect<SendFuture, ()>: Send);
+    assert_not_impl!(Inspect<SendFuture, *const ()>: Send);
+    assert_not_impl!(Inspect<LocalFuture, ()>: Send);
+    assert_impl!(Inspect<SyncFuture, ()>: Sync);
+    assert_not_impl!(Inspect<SyncFuture, *const ()>: Sync);
+    assert_not_impl!(Inspect<LocalFuture, ()>: Sync);
+    assert_impl!(Inspect<UnpinFuture, PhantomPinned>: Unpin);
+    assert_not_impl!(Inspect<PhantomPinned, PhantomPinned>: Unpin);
+
+    assert_impl!(InspectErr<SendFuture, ()>: Send);
+    assert_not_impl!(InspectErr<SendFuture, *const ()>: Send);
+    assert_not_impl!(InspectErr<LocalFuture, ()>: Send);
+    assert_impl!(InspectErr<SyncFuture, ()>: Sync);
+    assert_not_impl!(InspectErr<SyncFuture, *const ()>: Sync);
+    assert_not_impl!(InspectErr<LocalFuture, ()>: Sync);
+    assert_impl!(InspectErr<UnpinFuture, PhantomPinned>: Unpin);
+    assert_not_impl!(InspectErr<PhantomPinned, PhantomPinned>: Unpin);
+
+    assert_impl!(InspectOk<SendFuture, ()>: Send);
+    assert_not_impl!(InspectOk<SendFuture, *const ()>: Send);
+    assert_not_impl!(InspectOk<LocalFuture, ()>: Send);
+    assert_impl!(InspectOk<SyncFuture, ()>: Sync);
+    assert_not_impl!(InspectOk<SyncFuture, *const ()>: Sync);
+    assert_not_impl!(InspectOk<LocalFuture, ()>: Sync);
+    assert_impl!(InspectOk<UnpinFuture, PhantomPinned>: Unpin);
+    assert_not_impl!(InspectOk<PhantomPinned, PhantomPinned>: Unpin);
+
+    assert_impl!(IntoFuture<SendFuture>: Send);
+    assert_not_impl!(IntoFuture<LocalFuture>: Send);
+    assert_impl!(IntoFuture<SyncFuture>: Sync);
+    assert_not_impl!(IntoFuture<LocalFuture>: Sync);
+    assert_impl!(IntoFuture<UnpinFuture>: Unpin);
+    assert_not_impl!(IntoFuture<PinnedFuture>: Unpin);
+
+    assert_impl!(IntoStream<SendFuture>: Send);
+    assert_not_impl!(IntoStream<LocalFuture>: Send);
+    assert_impl!(IntoStream<SyncFuture>: Sync);
+    assert_not_impl!(IntoStream<LocalFuture>: Sync);
+    assert_impl!(IntoStream<UnpinFuture>: Unpin);
+    assert_not_impl!(IntoStream<PinnedFuture>: Unpin);
+
+    assert_impl!(Join<SendFuture<()>, SendFuture<()>>: Send);
+    assert_not_impl!(Join<SendFuture<()>, SendFuture>: Send);
+    assert_not_impl!(Join<SendFuture, SendFuture<()>>: Send);
+    assert_not_impl!(Join<SendFuture, LocalFuture>: Send);
+    assert_not_impl!(Join<LocalFuture, SendFuture>: Send);
+    assert_impl!(Join<SyncFuture<()>, SyncFuture<()>>: Sync);
+    assert_not_impl!(Join<SyncFuture<()>, SyncFuture>: Sync);
+    assert_not_impl!(Join<SyncFuture, SyncFuture<()>>: Sync);
+    assert_not_impl!(Join<SyncFuture, LocalFuture>: Sync);
+    assert_not_impl!(Join<LocalFuture, SyncFuture>: Sync);
+    assert_impl!(Join<UnpinFuture, UnpinFuture>: Unpin);
+    assert_not_impl!(Join<PinnedFuture, UnpinFuture>: Unpin);
+    assert_not_impl!(Join<UnpinFuture, PinnedFuture>: Unpin);
+
+    // Join3, Join4, Join5 are the same as Join
+
+    assert_impl!(JoinAll<SendFuture<()>>: Send);
+    assert_not_impl!(JoinAll<LocalFuture>: Send);
+    assert_not_impl!(JoinAll<SendFuture>: Send);
+    assert_impl!(JoinAll<SyncFuture<()>>: Sync);
+    assert_not_impl!(JoinAll<LocalFuture>: Sync);
+    assert_not_impl!(JoinAll<SyncFuture>: Sync);
+    assert_impl!(JoinAll<PinnedFuture>: Unpin);
+
+    assert_impl!(Lazy<()>: Send);
+    assert_not_impl!(Lazy<*const ()>: Send);
+    assert_impl!(Lazy<()>: Sync);
+    assert_not_impl!(Lazy<*const ()>: Sync);
+    assert_impl!(Lazy<PhantomPinned>: Unpin);
+
+    assert_not_impl!(LocalFutureObj<()>: Send);
+    assert_not_impl!(LocalFutureObj<()>: Sync);
+    assert_impl!(LocalFutureObj<PhantomPinned>: Unpin);
+
+    assert_impl!(Map<SendFuture, ()>: Send);
+    assert_not_impl!(Map<SendFuture, *const ()>: Send);
+    assert_not_impl!(Map<LocalFuture, ()>: Send);
+    assert_impl!(Map<SyncFuture, ()>: Sync);
+    assert_not_impl!(Map<SyncFuture, *const ()>: Sync);
+    assert_not_impl!(Map<LocalFuture, ()>: Sync);
+    assert_impl!(Map<UnpinFuture, PhantomPinned>: Unpin);
+    assert_not_impl!(Map<PhantomPinned, ()>: Unpin);
+
+    assert_impl!(MapErr<SendFuture, ()>: Send);
+    assert_not_impl!(MapErr<SendFuture, *const ()>: Send);
+    assert_not_impl!(MapErr<LocalFuture, ()>: Send);
+    assert_impl!(MapErr<SyncFuture, ()>: Sync);
+    assert_not_impl!(MapErr<SyncFuture, *const ()>: Sync);
+    assert_not_impl!(MapErr<LocalFuture, ()>: Sync);
+    assert_impl!(MapErr<UnpinFuture, PhantomPinned>: Unpin);
+    assert_not_impl!(MapErr<PhantomPinned, ()>: Unpin);
+
+    assert_impl!(MapInto<SendFuture, *const ()>: Send);
+    assert_not_impl!(MapInto<LocalFuture, ()>: Send);
+    assert_impl!(MapInto<SyncFuture, *const ()>: Sync);
+    assert_not_impl!(MapInto<LocalFuture, ()>: Sync);
+    assert_impl!(MapInto<UnpinFuture, PhantomPinned>: Unpin);
+    assert_not_impl!(MapInto<PhantomPinned, ()>: Unpin);
+
+    assert_impl!(MapOk<SendFuture, ()>: Send);
+    assert_not_impl!(MapOk<SendFuture, *const ()>: Send);
+    assert_not_impl!(MapOk<LocalFuture, ()>: Send);
+    assert_impl!(MapOk<SyncFuture, ()>: Sync);
+    assert_not_impl!(MapOk<SyncFuture, *const ()>: Sync);
+    assert_not_impl!(MapOk<LocalFuture, ()>: Sync);
+    assert_impl!(MapOk<UnpinFuture, PhantomPinned>: Unpin);
+    assert_not_impl!(MapOk<PhantomPinned, ()>: Unpin);
+
+    assert_impl!(MapOkOrElse<SendFuture, (), ()>: Send);
+    assert_not_impl!(MapOkOrElse<SendFuture, (), *const ()>: Send);
+    assert_not_impl!(MapOkOrElse<SendFuture, *const (), ()>: Send);
+    assert_not_impl!(MapOkOrElse<LocalFuture, (), ()>: Send);
+    assert_impl!(MapOkOrElse<SyncFuture, (), ()>: Sync);
+    assert_not_impl!(MapOkOrElse<SyncFuture, (), *const ()>: Sync);
+    assert_not_impl!(MapOkOrElse<SyncFuture, *const (), ()>: Sync);
+    assert_not_impl!(MapOkOrElse<LocalFuture, (), ()>: Sync);
+    assert_impl!(MapOkOrElse<UnpinFuture, PhantomPinned, PhantomPinned>: Unpin);
+    assert_not_impl!(MapOkOrElse<PhantomPinned, (), ()>: Unpin);
+
+    assert_impl!(NeverError<SendFuture>: Send);
+    assert_not_impl!(NeverError<LocalFuture>: Send);
+    assert_impl!(NeverError<SyncFuture>: Sync);
+    assert_not_impl!(NeverError<LocalFuture>: Sync);
+    assert_impl!(NeverError<UnpinFuture>: Unpin);
+    assert_not_impl!(NeverError<PinnedFuture>: Unpin);
+
+    assert_impl!(OkInto<SendFuture, *const ()>: Send);
+    assert_not_impl!(OkInto<LocalFuture, ()>: Send);
+    assert_impl!(OkInto<SyncFuture, *const ()>: Sync);
+    assert_not_impl!(OkInto<LocalFuture, ()>: Sync);
+    assert_impl!(OkInto<UnpinFuture, PhantomPinned>: Unpin);
+    assert_not_impl!(OkInto<PhantomPinned, ()>: Unpin);
+
+    assert_impl!(OptionFuture<SendFuture>: Send);
+    assert_not_impl!(OptionFuture<LocalFuture>: Send);
+    assert_impl!(OptionFuture<SyncFuture>: Sync);
+    assert_not_impl!(OptionFuture<LocalFuture>: Sync);
+    assert_impl!(OptionFuture<UnpinFuture>: Unpin);
+    assert_not_impl!(OptionFuture<PinnedFuture>: Unpin);
+
+    assert_impl!(OrElse<SendFuture, SendFuture, ()>: Send);
+    assert_not_impl!(OrElse<SendFuture, LocalFuture, ()>: Send);
+    assert_not_impl!(OrElse<LocalFuture, SendFuture, ()>: Send);
+    assert_not_impl!(OrElse<SendFuture, SendFuture, *const ()>: Send);
+    assert_impl!(OrElse<SyncFuture, SyncFuture, ()>: Sync);
+    assert_not_impl!(OrElse<SyncFuture, LocalFuture, ()>: Sync);
+    assert_not_impl!(OrElse<LocalFuture, SyncFuture, ()>: Sync);
+    assert_not_impl!(OrElse<SyncFuture, SyncFuture, *const ()>: Sync);
+    assert_impl!(OrElse<UnpinFuture, UnpinFuture, PhantomPinned>: Unpin);
+    assert_not_impl!(OrElse<PinnedFuture, UnpinFuture, PhantomPinned>: Unpin);
+    assert_not_impl!(OrElse<UnpinFuture, PinnedFuture, PhantomPinned>: Unpin);
+
+    assert_impl!(Pending<()>: Send);
+    assert_not_impl!(Pending<*const ()>: Send);
+    assert_impl!(Pending<()>: Sync);
+    assert_not_impl!(Pending<*const ()>: Sync);
+    assert_impl!(Pending<PhantomPinned>: Unpin);
+
+    assert_impl!(PollFn<()>: Send);
+    assert_not_impl!(PollFn<*const ()>: Send);
+    assert_impl!(PollFn<()>: Sync);
+    assert_not_impl!(PollFn<*const ()>: Sync);
+    assert_impl!(PollFn<PhantomPinned>: Unpin);
+
+    assert_impl!(Ready<()>: Send);
+    assert_not_impl!(Ready<*const ()>: Send);
+    assert_impl!(Ready<()>: Sync);
+    assert_not_impl!(Ready<*const ()>: Sync);
+    assert_impl!(Ready<PhantomPinned>: Unpin);
+
+    assert_impl!(Remote<SendFuture<()>>: Send);
+    assert_not_impl!(Remote<LocalFuture>: Send);
+    assert_not_impl!(Remote<SendFuture>: Send);
+    assert_impl!(Remote<SyncFuture<()>>: Sync);
+    assert_not_impl!(Remote<LocalFuture>: Sync);
+    assert_not_impl!(Remote<SyncFuture>: Sync);
+    assert_impl!(Remote<UnpinFuture>: Unpin);
+    assert_not_impl!(Remote<PinnedFuture>: Unpin);
+
+    assert_impl!(RemoteHandle<()>: Send);
+    assert_not_impl!(RemoteHandle<*const ()>: Send);
+    assert_impl!(RemoteHandle<()>: Sync);
+    assert_not_impl!(RemoteHandle<*const ()>: Sync);
+    assert_impl!(RemoteHandle<PhantomPinned>: Unpin);
+
+    assert_impl!(Select<SendFuture, SendFuture>: Send);
+    assert_not_impl!(Select<SendFuture, LocalFuture>: Send);
+    assert_not_impl!(Select<LocalFuture, SendFuture>: Send);
+    assert_impl!(Select<SyncFuture, SyncFuture>: Sync);
+    assert_not_impl!(Select<SyncFuture, LocalFuture>: Sync);
+    assert_not_impl!(Select<LocalFuture, SyncFuture>: Sync);
+    assert_impl!(Select<UnpinFuture, UnpinFuture>: Unpin);
+    assert_not_impl!(Select<PinnedFuture, UnpinFuture>: Unpin);
+    assert_not_impl!(Select<UnpinFuture, PinnedFuture>: Unpin);
+
+    assert_impl!(SelectAll<SendFuture>: Send);
+    assert_not_impl!(SelectAll<LocalFuture>: Send);
+    assert_impl!(SelectAll<SyncFuture>: Sync);
+    assert_not_impl!(SelectAll<LocalFuture>: Sync);
+    assert_impl!(SelectAll<UnpinFuture>: Unpin);
+    assert_not_impl!(SelectAll<PinnedFuture>: Unpin);
+
+    assert_impl!(SelectOk<SendFuture>: Send);
+    assert_not_impl!(SelectOk<LocalFuture>: Send);
+    assert_impl!(SelectOk<SyncFuture>: Sync);
+    assert_not_impl!(SelectOk<LocalFuture>: Sync);
+    assert_impl!(SelectOk<UnpinFuture>: Unpin);
+    assert_not_impl!(SelectOk<PinnedFuture>: Unpin);
+
+    assert_impl!(Shared<SendFuture<()>>: Send);
+    assert_not_impl!(Shared<SendFuture>: Send);
+    assert_not_impl!(Shared<LocalFuture>: Send);
+    assert_not_impl!(Shared<SyncFuture<()>>: Sync);
+    assert_impl!(Shared<PinnedFuture>: Unpin);
+
+    assert_impl!(Then<SendFuture, SendFuture, ()>: Send);
+    assert_not_impl!(Then<SendFuture, SendFuture, *const ()>: Send);
+    assert_not_impl!(Then<SendFuture, LocalFuture, ()>: Send);
+    assert_not_impl!(Then<LocalFuture, SendFuture, ()>: Send);
+    assert_impl!(Then<SyncFuture, SyncFuture, ()>: Sync);
+    assert_not_impl!(Then<SyncFuture, SyncFuture, *const ()>: Sync);
+    assert_not_impl!(Then<SyncFuture, LocalFuture, ()>: Sync);
+    assert_not_impl!(Then<LocalFuture, SyncFuture, ()>: Sync);
+    assert_impl!(Then<UnpinFuture, UnpinFuture, PhantomPinned>: Unpin);
+    assert_not_impl!(Then<PinnedFuture, UnpinFuture, ()>: Unpin);
+    assert_not_impl!(Then<UnpinFuture, PinnedFuture, ()>: Unpin);
+
+    assert_impl!(TryFlatten<SendTryFuture<()>, ()>: Send);
+    assert_not_impl!(TryFlatten<LocalTryFuture, ()>: Send);
+    assert_not_impl!(TryFlatten<SendTryFuture, *const ()>: Send);
+    assert_impl!(TryFlatten<SyncTryFuture<()>, ()>: Sync);
+    assert_not_impl!(TryFlatten<LocalTryFuture, ()>: Sync);
+    assert_not_impl!(TryFlatten<SyncTryFuture, *const ()>: Sync);
+    assert_impl!(TryFlatten<UnpinTryFuture<()>, ()>: Unpin);
+    assert_not_impl!(TryFlatten<PinnedTryFuture, ()>: Unpin);
+    assert_not_impl!(TryFlatten<UnpinTryFuture, PhantomPinned>: Unpin);
+
+    assert_impl!(TryFlattenStream<SendTryFuture<()>>: Send);
+    assert_not_impl!(TryFlattenStream<LocalTryFuture>: Send);
+    assert_not_impl!(TryFlattenStream<SendTryFuture>: Send);
+    assert_impl!(TryFlattenStream<SyncTryFuture<()>>: Sync);
+    assert_not_impl!(TryFlattenStream<LocalTryFuture>: Sync);
+    assert_not_impl!(TryFlattenStream<SyncTryFuture>: Sync);
+    assert_impl!(TryFlattenStream<UnpinTryFuture<()>>: Unpin);
+    assert_not_impl!(TryFlattenStream<PinnedTryFuture>: Unpin);
+    assert_not_impl!(TryFlattenStream<UnpinTryFuture>: Unpin);
+
+    assert_impl!(TryJoin<SendTryFuture<()>, SendTryFuture<()>>: Send);
+    assert_not_impl!(TryJoin<SendTryFuture<()>, SendTryFuture>: Send);
+    assert_not_impl!(TryJoin<SendTryFuture, SendTryFuture<()>>: Send);
+    assert_not_impl!(TryJoin<SendTryFuture, LocalTryFuture>: Send);
+    assert_not_impl!(TryJoin<LocalTryFuture, SendTryFuture>: Send);
+    assert_impl!(TryJoin<SyncTryFuture<()>, SyncTryFuture<()>>: Sync);
+    assert_not_impl!(TryJoin<SyncTryFuture<()>, SyncTryFuture>: Sync);
+    assert_not_impl!(TryJoin<SyncTryFuture, SyncTryFuture<()>>: Sync);
+    assert_not_impl!(TryJoin<SyncTryFuture, LocalTryFuture>: Sync);
+    assert_not_impl!(TryJoin<LocalTryFuture, SyncTryFuture>: Sync);
+    assert_impl!(TryJoin<UnpinTryFuture, UnpinTryFuture>: Unpin);
+    assert_not_impl!(TryJoin<PinnedTryFuture, UnpinTryFuture>: Unpin);
+    assert_not_impl!(TryJoin<UnpinTryFuture, PinnedTryFuture>: Unpin);
+
+    // TryJoin3, TryJoin4, TryJoin5 are the same as TryJoin
+
+    assert_impl!(TryJoinAll<SendTryFuture<()>>: Send);
+    assert_not_impl!(TryJoinAll<LocalTryFuture>: Send);
+    assert_not_impl!(TryJoinAll<SendTryFuture>: Send);
+    assert_impl!(TryJoinAll<SyncTryFuture<()>>: Sync);
+    assert_not_impl!(TryJoinAll<LocalTryFuture>: Sync);
+    assert_not_impl!(TryJoinAll<SyncTryFuture>: Sync);
+    assert_impl!(TryJoinAll<PinnedTryFuture>: Unpin);
+
+    assert_impl!(TrySelect<SendFuture, SendFuture>: Send);
+    assert_not_impl!(TrySelect<SendFuture, LocalFuture>: Send);
+    assert_not_impl!(TrySelect<LocalFuture, SendFuture>: Send);
+    assert_impl!(TrySelect<SyncFuture, SyncFuture>: Sync);
+    assert_not_impl!(TrySelect<SyncFuture, LocalFuture>: Sync);
+    assert_not_impl!(TrySelect<LocalFuture, SyncFuture>: Sync);
+    assert_impl!(TrySelect<UnpinFuture, UnpinFuture>: Unpin);
+    assert_not_impl!(TrySelect<PinnedFuture, UnpinFuture>: Unpin);
+    assert_not_impl!(TrySelect<UnpinFuture, PinnedFuture>: Unpin);
+
+    assert_impl!(UnitError<SendFuture>: Send);
+    assert_not_impl!(UnitError<LocalFuture>: Send);
+    assert_impl!(UnitError<SyncFuture>: Sync);
+    assert_not_impl!(UnitError<LocalFuture>: Sync);
+    assert_impl!(UnitError<UnpinFuture>: Unpin);
+    assert_not_impl!(UnitError<PinnedFuture>: Unpin);
+
+    assert_impl!(UnwrapOrElse<SendFuture, ()>: Send);
+    assert_not_impl!(UnwrapOrElse<SendFuture, *const ()>: Send);
+    assert_not_impl!(UnwrapOrElse<LocalFuture, ()>: Send);
+    assert_impl!(UnwrapOrElse<SyncFuture, ()>: Sync);
+    assert_not_impl!(UnwrapOrElse<SyncFuture, *const ()>: Sync);
+    assert_not_impl!(UnwrapOrElse<LocalFuture, ()>: Sync);
+    assert_impl!(UnwrapOrElse<UnpinFuture, PhantomPinned>: Unpin);
+    assert_not_impl!(UnwrapOrElse<PhantomPinned, ()>: Unpin);
+
+    assert_impl!(WeakShared<SendFuture<()>>: Send);
+    assert_not_impl!(WeakShared<SendFuture>: Send);
+    assert_not_impl!(WeakShared<LocalFuture>: Send);
+    assert_not_impl!(WeakShared<SyncFuture<()>>: Sync);
+    assert_impl!(WeakShared<PinnedFuture>: Unpin);
+
+    assert_impl!(Either<SendFuture, SendFuture>: Send);
+    assert_not_impl!(Either<SendFuture, LocalFuture>: Send);
+    assert_not_impl!(Either<LocalFuture, SendFuture>: Send);
+    assert_impl!(Either<SyncFuture, SyncFuture>: Sync);
+    assert_not_impl!(Either<SyncFuture, LocalFuture>: Sync);
+    assert_not_impl!(Either<LocalFuture, SyncFuture>: Sync);
+    assert_impl!(Either<UnpinFuture, UnpinFuture>: Unpin);
+    assert_not_impl!(Either<UnpinFuture, PinnedFuture>: Unpin);
+    assert_not_impl!(Either<PinnedFuture, UnpinFuture>: Unpin);
+
+    assert_impl!(MaybeDone<SendFuture<()>>: Send);
+    assert_not_impl!(MaybeDone<SendFuture>: Send);
+    assert_not_impl!(MaybeDone<LocalFuture>: Send);
+    assert_impl!(MaybeDone<SyncFuture<()>>: Sync);
+    assert_not_impl!(MaybeDone<SyncFuture>: Sync);
+    assert_not_impl!(MaybeDone<LocalFuture>: Sync);
+    assert_impl!(MaybeDone<UnpinFuture>: Unpin);
+    assert_not_impl!(MaybeDone<PinnedFuture>: Unpin);
+
+    assert_impl!(TryMaybeDone<SendTryFuture<()>>: Send);
+    assert_not_impl!(TryMaybeDone<SendTryFuture>: Send);
+    assert_not_impl!(TryMaybeDone<LocalTryFuture>: Send);
+    assert_impl!(TryMaybeDone<SyncTryFuture<()>>: Sync);
+    assert_not_impl!(TryMaybeDone<SyncTryFuture>: Sync);
+    assert_not_impl!(TryMaybeDone<LocalTryFuture>: Sync);
+    assert_impl!(TryMaybeDone<UnpinTryFuture>: Unpin);
+    assert_not_impl!(TryMaybeDone<PinnedTryFuture>: Unpin);
+}
+
+/// Assert Send/Sync/Unpin for all public types in `futures::io`.
+pub mod io {
+    use super::*;
+    use futures::io::{Sink, *};
+
+    assert_impl!(AllowStdIo<()>: Send);
+    assert_not_impl!(AllowStdIo<*const ()>: Send);
+    assert_impl!(AllowStdIo<()>: Sync);
+    assert_not_impl!(AllowStdIo<*const ()>: Sync);
+    assert_impl!(AllowStdIo<PhantomPinned>: Unpin);
+
+    assert_impl!(BufReader<()>: Send);
+    assert_not_impl!(BufReader<*const ()>: Send);
+    assert_impl!(BufReader<()>: Sync);
+    assert_not_impl!(BufReader<*const ()>: Sync);
+    assert_impl!(BufReader<()>: Unpin);
+    assert_not_impl!(BufReader<PhantomPinned>: Unpin);
+
+    assert_impl!(BufWriter<()>: Send);
+    assert_not_impl!(BufWriter<*const ()>: Send);
+    assert_impl!(BufWriter<()>: Sync);
+    assert_not_impl!(BufWriter<*const ()>: Sync);
+    assert_impl!(BufWriter<()>: Unpin);
+    assert_not_impl!(BufWriter<PhantomPinned>: Unpin);
+
+    assert_impl!(Chain<(), ()>: Send);
+    assert_not_impl!(Chain<(), *const ()>: Send);
+    assert_not_impl!(Chain<*const (), ()>: Send);
+    assert_impl!(Chain<(), ()>: Sync);
+    assert_not_impl!(Chain<(), *const ()>: Sync);
+    assert_not_impl!(Chain<*const (), ()>: Sync);
+    assert_impl!(Chain<(), ()>: Unpin);
+    assert_not_impl!(Chain<(), PhantomPinned>: Unpin);
+    assert_not_impl!(Chain<PhantomPinned, ()>: Unpin);
+
+    assert_impl!(Close<'_, ()>: Send);
+    assert_not_impl!(Close<'_, *const ()>: Send);
+    assert_impl!(Close<'_, ()>: Sync);
+    assert_not_impl!(Close<'_, *const ()>: Sync);
+    assert_impl!(Close<'_, ()>: Unpin);
+    assert_not_impl!(Close<'_, PhantomPinned>: Unpin);
+
+    assert_impl!(Copy<(), ()>: Send);
+    assert_not_impl!(Copy<(), *const ()>: Send);
+    assert_not_impl!(Copy<*const (), ()>: Send);
+    assert_impl!(Copy<(), ()>: Sync);
+    assert_not_impl!(Copy<(), *const ()>: Sync);
+    assert_not_impl!(Copy<*const (), ()>: Sync);
+    assert_impl!(Copy<(), PhantomPinned>: Unpin);
+    assert_not_impl!(Copy<PhantomPinned, ()>: Unpin);
+
+    assert_impl!(CopyBuf<(), ()>: Send);
+    assert_not_impl!(CopyBuf<(), *const ()>: Send);
+    assert_not_impl!(CopyBuf<*const (), ()>: Send);
+    assert_impl!(CopyBuf<(), ()>: Sync);
+    assert_not_impl!(CopyBuf<(), *const ()>: Sync);
+    assert_not_impl!(CopyBuf<*const (), ()>: Sync);
+    assert_impl!(CopyBuf<(), PhantomPinned>: Unpin);
+    assert_not_impl!(CopyBuf<PhantomPinned, ()>: Unpin);
+
+    assert_impl!(Cursor<()>: Send);
+    assert_not_impl!(Cursor<*const ()>: Send);
+    assert_impl!(Cursor<()>: Sync);
+    assert_not_impl!(Cursor<*const ()>: Sync);
+    assert_impl!(Cursor<()>: Unpin);
+    assert_not_impl!(Cursor<PhantomPinned>: Unpin);
+
+    assert_impl!(Empty: Send);
+    assert_impl!(Empty: Sync);
+    assert_impl!(Empty: Unpin);
+
+    assert_impl!(FillBuf<'_, ()>: Send);
+    assert_not_impl!(FillBuf<'_, *const ()>: Send);
+    assert_impl!(FillBuf<'_, ()>: Sync);
+    assert_not_impl!(FillBuf<'_, *const ()>: Sync);
+    assert_impl!(FillBuf<'_, PhantomPinned>: Unpin);
+
+    assert_impl!(Flush<'_, ()>: Send);
+    assert_not_impl!(Flush<'_, *const ()>: Send);
+    assert_impl!(Flush<'_, ()>: Sync);
+    assert_not_impl!(Flush<'_, *const ()>: Sync);
+    assert_impl!(Flush<'_, ()>: Unpin);
+    assert_not_impl!(Flush<'_, PhantomPinned>: Unpin);
+
+    assert_impl!(IntoSink<(), ()>: Send);
+    assert_not_impl!(IntoSink<(), *const ()>: Send);
+    assert_not_impl!(IntoSink<*const (), ()>: Send);
+    assert_impl!(IntoSink<(), ()>: Sync);
+    assert_not_impl!(IntoSink<(), *const ()>: Sync);
+    assert_not_impl!(IntoSink<*const (), ()>: Sync);
+    assert_impl!(IntoSink<(), PhantomPinned>: Unpin);
+    assert_not_impl!(IntoSink<PhantomPinned, ()>: Unpin);
+
+    assert_impl!(Lines<()>: Send);
+    assert_not_impl!(Lines<*const ()>: Send);
+    assert_impl!(Lines<()>: Sync);
+    assert_not_impl!(Lines<*const ()>: Sync);
+    assert_impl!(Lines<()>: Unpin);
+    assert_not_impl!(Lines<PhantomPinned>: Unpin);
+
+    assert_impl!(Read<'_, ()>: Send);
+    assert_not_impl!(Read<'_, *const ()>: Send);
+    assert_impl!(Read<'_, ()>: Sync);
+    assert_not_impl!(Read<'_, *const ()>: Sync);
+    assert_impl!(Read<'_, ()>: Unpin);
+    assert_not_impl!(Read<'_, PhantomPinned>: Unpin);
+
+    assert_impl!(ReadExact<'_, ()>: Send);
+    assert_not_impl!(ReadExact<'_, *const ()>: Send);
+    assert_impl!(ReadExact<'_, ()>: Sync);
+    assert_not_impl!(ReadExact<'_, *const ()>: Sync);
+    assert_impl!(ReadExact<'_, ()>: Unpin);
+    assert_not_impl!(ReadExact<'_, PhantomPinned>: Unpin);
+
+    assert_impl!(ReadHalf<()>: Send);
+    assert_not_impl!(ReadHalf<*const ()>: Send);
+    assert_impl!(ReadHalf<()>: Sync);
+    assert_not_impl!(ReadHalf<*const ()>: Sync);
+    assert_impl!(ReadHalf<PhantomPinned>: Unpin);
+
+    assert_impl!(ReadLine<'_, ()>: Send);
+    assert_not_impl!(ReadLine<'_, *const ()>: Send);
+    assert_impl!(ReadLine<'_, ()>: Sync);
+    assert_not_impl!(ReadLine<'_, *const ()>: Sync);
+    assert_impl!(ReadLine<'_, ()>: Unpin);
+    assert_not_impl!(ReadLine<'_, PhantomPinned>: Unpin);
+
+    assert_impl!(ReadToEnd<'_, ()>: Send);
+    assert_not_impl!(ReadToEnd<'_, *const ()>: Send);
+    assert_impl!(ReadToEnd<'_, ()>: Sync);
+    assert_not_impl!(ReadToEnd<'_, *const ()>: Sync);
+    assert_impl!(ReadToEnd<'_, ()>: Unpin);
+    assert_not_impl!(ReadToEnd<'_, PhantomPinned>: Unpin);
+
+    assert_impl!(ReadToString<'_, ()>: Send);
+    assert_not_impl!(ReadToString<'_, *const ()>: Send);
+    assert_impl!(ReadToString<'_, ()>: Sync);
+    assert_not_impl!(ReadToString<'_, *const ()>: Sync);
+    assert_impl!(ReadToString<'_, ()>: Unpin);
+    assert_not_impl!(ReadToString<'_, PhantomPinned>: Unpin);
+
+    assert_impl!(ReadUntil<'_, ()>: Send);
+    assert_not_impl!(ReadUntil<'_, *const ()>: Send);
+    assert_impl!(ReadUntil<'_, ()>: Sync);
+    assert_not_impl!(ReadUntil<'_, *const ()>: Sync);
+    assert_impl!(ReadUntil<'_, ()>: Unpin);
+    assert_not_impl!(ReadUntil<'_, PhantomPinned>: Unpin);
+
+    assert_impl!(ReadVectored<'_, ()>: Send);
+    assert_not_impl!(ReadVectored<'_, *const ()>: Send);
+    assert_impl!(ReadVectored<'_, ()>: Sync);
+    assert_not_impl!(ReadVectored<'_, *const ()>: Sync);
+    assert_impl!(ReadVectored<'_, ()>: Unpin);
+    assert_not_impl!(ReadVectored<'_, PhantomPinned>: Unpin);
+
+    assert_impl!(Repeat: Send);
+    assert_impl!(Repeat: Sync);
+    assert_impl!(Repeat: Unpin);
+
+    assert_impl!(ReuniteError<()>: Send);
+    assert_not_impl!(ReuniteError<*const ()>: Send);
+    assert_impl!(ReuniteError<()>: Sync);
+    assert_not_impl!(ReuniteError<*const ()>: Sync);
+    assert_impl!(ReuniteError<PhantomPinned>: Unpin);
+
+    assert_impl!(Seek<'_, ()>: Send);
+    assert_not_impl!(Seek<'_, *const ()>: Send);
+    assert_impl!(Seek<'_, ()>: Sync);
+    assert_not_impl!(Seek<'_, *const ()>: Sync);
+    assert_impl!(Seek<'_, ()>: Unpin);
+    assert_not_impl!(Seek<'_, PhantomPinned>: Unpin);
+
+    assert_impl!(Sink: Send);
+    assert_impl!(Sink: Sync);
+    assert_impl!(Sink: Unpin);
+
+    assert_impl!(Take<()>: Send);
+    assert_not_impl!(Take<*const ()>: Send);
+    assert_impl!(Take<()>: Sync);
+    assert_not_impl!(Take<*const ()>: Sync);
+    assert_impl!(Take<()>: Unpin);
+    assert_not_impl!(Take<PhantomPinned>: Unpin);
+
+    assert_impl!(Window<()>: Send);
+    assert_not_impl!(Window<*const ()>: Send);
+    assert_impl!(Window<()>: Sync);
+    assert_not_impl!(Window<*const ()>: Sync);
+    assert_impl!(Window<()>: Unpin);
+    assert_not_impl!(Window<PhantomPinned>: Unpin);
+
+    assert_impl!(Write<'_, ()>: Send);
+    assert_not_impl!(Write<'_, *const ()>: Send);
+    assert_impl!(Write<'_, ()>: Sync);
+    assert_not_impl!(Write<'_, *const ()>: Sync);
+    assert_impl!(Write<'_, ()>: Unpin);
+    assert_not_impl!(Write<'_, PhantomPinned>: Unpin);
+
+    assert_impl!(WriteAll<'_, ()>: Send);
+    assert_not_impl!(WriteAll<'_, *const ()>: Send);
+    assert_impl!(WriteAll<'_, ()>: Sync);
+    assert_not_impl!(WriteAll<'_, *const ()>: Sync);
+    assert_impl!(WriteAll<'_, ()>: Unpin);
+    assert_not_impl!(WriteAll<'_, PhantomPinned>: Unpin);
+
+    #[cfg(feature = "write-all-vectored")]
+    assert_impl!(WriteAllVectored<'_, ()>: Send);
+    #[cfg(feature = "write-all-vectored")]
+    assert_not_impl!(WriteAllVectored<'_, *const ()>: Send);
+    #[cfg(feature = "write-all-vectored")]
+    assert_impl!(WriteAllVectored<'_, ()>: Sync);
+    #[cfg(feature = "write-all-vectored")]
+    assert_not_impl!(WriteAllVectored<'_, *const ()>: Sync);
+    #[cfg(feature = "write-all-vectored")]
+    assert_impl!(WriteAllVectored<'_, ()>: Unpin);
+    // WriteAllVectored requires `W: Unpin`
+    // #[cfg(feature = "write-all-vectored")]
+    // assert_not_impl!(WriteAllVectored<'_, PhantomPinned>: Unpin);
+
+    assert_impl!(WriteHalf<()>: Send);
+    assert_not_impl!(WriteHalf<*const ()>: Send);
+    assert_impl!(WriteHalf<()>: Sync);
+    assert_not_impl!(WriteHalf<*const ()>: Sync);
+    assert_impl!(WriteHalf<PhantomPinned>: Unpin);
+
+    assert_impl!(WriteVectored<'_, ()>: Send);
+    assert_not_impl!(WriteVectored<'_, *const ()>: Send);
+    assert_impl!(WriteVectored<'_, ()>: Sync);
+    assert_not_impl!(WriteVectored<'_, *const ()>: Sync);
+    assert_impl!(WriteVectored<'_, ()>: Unpin);
+    assert_not_impl!(WriteVectored<'_, PhantomPinned>: Unpin);
+}
+
+/// Assert Send/Sync/Unpin for all public types in `futures::lock`.
+pub mod lock {
+    use super::*;
+    use futures::lock::*;
+
+    #[cfg(feature = "bilock")]
+    assert_impl!(BiLock<()>: Send);
+    #[cfg(feature = "bilock")]
+    assert_not_impl!(BiLock<*const ()>: Send);
+    #[cfg(feature = "bilock")]
+    assert_impl!(BiLock<()>: Sync);
+    #[cfg(feature = "bilock")]
+    assert_not_impl!(BiLock<*const ()>: Sync);
+    #[cfg(feature = "bilock")]
+    assert_impl!(BiLock<PhantomPinned>: Unpin);
+
+    #[cfg(feature = "bilock")]
+    assert_impl!(BiLockAcquire<'_, ()>: Send);
+    #[cfg(feature = "bilock")]
+    assert_not_impl!(BiLockAcquire<'_, *const ()>: Send);
+    #[cfg(feature = "bilock")]
+    assert_impl!(BiLockAcquire<'_, ()>: Sync);
+    #[cfg(feature = "bilock")]
+    assert_not_impl!(BiLockAcquire<'_, *const ()>: Sync);
+    #[cfg(feature = "bilock")]
+    assert_impl!(BiLockAcquire<'_, PhantomPinned>: Unpin);
+
+    #[cfg(feature = "bilock")]
+    assert_impl!(BiLockGuard<'_, ()>: Send);
+    #[cfg(feature = "bilock")]
+    assert_not_impl!(BiLockGuard<'_, *const ()>: Send);
+    #[cfg(feature = "bilock")]
+    assert_impl!(BiLockGuard<'_, ()>: Sync);
+    #[cfg(feature = "bilock")]
+    assert_not_impl!(BiLockGuard<'_, *const ()>: Sync);
+    #[cfg(feature = "bilock")]
+    assert_impl!(BiLockGuard<'_, PhantomPinned>: Unpin);
+
+    assert_impl!(MappedMutexGuard<'_, (), ()>: Send);
+    assert_not_impl!(MappedMutexGuard<'_, (), *const ()>: Send);
+    assert_not_impl!(MappedMutexGuard<'_, *const (), ()>: Send);
+    assert_impl!(MappedMutexGuard<'_, (), ()>: Sync);
+    assert_not_impl!(MappedMutexGuard<'_, (), *const ()>: Sync);
+    assert_not_impl!(MappedMutexGuard<'_, *const (), ()>: Sync);
+    assert_impl!(MappedMutexGuard<'_, PhantomPinned, PhantomPinned>: Unpin);
+
+    assert_impl!(Mutex<()>: Send);
+    assert_not_impl!(Mutex<*const ()>: Send);
+    assert_impl!(Mutex<()>: Sync);
+    assert_not_impl!(Mutex<*const ()>: Sync);
+    assert_impl!(Mutex<()>: Unpin);
+    assert_not_impl!(Mutex<PhantomPinned>: Unpin);
+
+    assert_impl!(MutexGuard<'_, ()>: Send);
+    assert_not_impl!(MutexGuard<'_, *const ()>: Send);
+    assert_impl!(MutexGuard<'_, ()>: Sync);
+    assert_not_impl!(MutexGuard<'_, *const ()>: Sync);
+    assert_impl!(MutexGuard<'_, PhantomPinned>: Unpin);
+
+    assert_impl!(MutexLockFuture<'_, ()>: Send);
+    assert_not_impl!(MutexLockFuture<'_, *const ()>: Send);
+    assert_impl!(MutexLockFuture<'_, *const ()>: Sync);
+    assert_impl!(MutexLockFuture<'_, PhantomPinned>: Unpin);
+
+    #[cfg(feature = "bilock")]
+    assert_impl!(ReuniteError<()>: Send);
+    #[cfg(feature = "bilock")]
+    assert_not_impl!(ReuniteError<*const ()>: Send);
+    #[cfg(feature = "bilock")]
+    assert_impl!(ReuniteError<()>: Sync);
+    #[cfg(feature = "bilock")]
+    assert_not_impl!(ReuniteError<*const ()>: Sync);
+    #[cfg(feature = "bilock")]
+    assert_impl!(ReuniteError<PhantomPinned>: Unpin);
+}
+
+/// Assert Send/Sync/Unpin for all public types in `futures::sink`.
+pub mod sink {
+    use super::*;
+    use futures::sink::{self, *};
+    use std::marker::Send;
+
+    assert_impl!(Buffer<(), ()>: Send);
+    assert_not_impl!(Buffer<(), *const ()>: Send);
+    assert_not_impl!(Buffer<*const (), ()>: Send);
+    assert_impl!(Buffer<(), ()>: Sync);
+    assert_not_impl!(Buffer<(), *const ()>: Sync);
+    assert_not_impl!(Buffer<*const (), ()>: Sync);
+    assert_impl!(Buffer<(), PhantomPinned>: Unpin);
+    assert_not_impl!(Buffer<PhantomPinned, ()>: Unpin);
+
+    assert_impl!(Close<'_, (), *const ()>: Send);
+    assert_not_impl!(Close<'_, *const (), ()>: Send);
+    assert_impl!(Close<'_, (), *const ()>: Sync);
+    assert_not_impl!(Close<'_, *const (), ()>: Sync);
+    assert_impl!(Close<'_, (), PhantomPinned>: Unpin);
+    assert_not_impl!(Close<'_, PhantomPinned, ()>: Unpin);
+
+    assert_impl!(Drain<()>: Send);
+    assert_not_impl!(Drain<*const ()>: Send);
+    assert_impl!(Drain<()>: Sync);
+    assert_not_impl!(Drain<*const ()>: Sync);
+    assert_impl!(Drain<PhantomPinned>: Unpin);
+
+    assert_impl!(Fanout<(), ()>: Send);
+    assert_not_impl!(Fanout<(), *const ()>: Send);
+    assert_not_impl!(Fanout<*const (), ()>: Send);
+    assert_impl!(Fanout<(), ()>: Sync);
+    assert_not_impl!(Fanout<(), *const ()>: Sync);
+    assert_not_impl!(Fanout<*const (), ()>: Sync);
+    assert_impl!(Fanout<(), ()>: Unpin);
+    assert_not_impl!(Fanout<(), PhantomPinned>: Unpin);
+    assert_not_impl!(Fanout<PhantomPinned, ()>: Unpin);
+
+    assert_impl!(Feed<'_, (), ()>: Send);
+    assert_not_impl!(Feed<'_, (), *const ()>: Send);
+    assert_not_impl!(Feed<'_, *const (), ()>: Send);
+    assert_impl!(Feed<'_, (), ()>: Sync);
+    assert_not_impl!(Feed<'_, (), *const ()>: Sync);
+    assert_not_impl!(Feed<'_, *const (), ()>: Sync);
+    assert_impl!(Feed<'_, (), PhantomPinned>: Unpin);
+    assert_not_impl!(Feed<'_, PhantomPinned, ()>: Unpin);
+
+    assert_impl!(Flush<'_, (), *const ()>: Send);
+    assert_not_impl!(Flush<'_, *const (), ()>: Send);
+    assert_impl!(Flush<'_, (), *const ()>: Sync);
+    assert_not_impl!(Flush<'_, *const (), ()>: Sync);
+    assert_impl!(Flush<'_, (), PhantomPinned>: Unpin);
+    assert_not_impl!(Flush<'_, PhantomPinned, ()>: Unpin);
+
+    assert_impl!(sink::Send<'_, (), ()>: Send);
+    assert_not_impl!(sink::Send<'_, (), *const ()>: Send);
+    assert_not_impl!(sink::Send<'_, *const (), ()>: Send);
+    assert_impl!(sink::Send<'_, (), ()>: Sync);
+    assert_not_impl!(sink::Send<'_, (), *const ()>: Sync);
+    assert_not_impl!(sink::Send<'_, *const (), ()>: Sync);
+    assert_impl!(sink::Send<'_, (), PhantomPinned>: Unpin);
+    assert_not_impl!(sink::Send<'_, PhantomPinned, ()>: Unpin);
+
+    assert_impl!(SendAll<'_, (), SendTryStream<()>>: Send);
+    assert_not_impl!(SendAll<'_, (), SendTryStream>: Send);
+    assert_not_impl!(SendAll<'_, (), LocalTryStream>: Send);
+    assert_not_impl!(SendAll<'_, *const (), SendTryStream<()>>: Send);
+    assert_impl!(SendAll<'_, (), SyncTryStream<()>>: Sync);
+    assert_not_impl!(SendAll<'_, (), SyncTryStream>: Sync);
+    assert_not_impl!(SendAll<'_, (), LocalTryStream>: Sync);
+    assert_not_impl!(SendAll<'_, *const (), SyncTryStream<()>>: Sync);
+    assert_impl!(SendAll<'_, (), UnpinTryStream>: Unpin);
+    assert_not_impl!(SendAll<'_, PhantomPinned, UnpinTryStream>: Unpin);
+    assert_not_impl!(SendAll<'_, (), PinnedTryStream>: Unpin);
+
+    assert_impl!(SinkErrInto<SendSink, *const (), *const ()>: Send);
+    assert_not_impl!(SinkErrInto<LocalSink<()>, (), ()>: Send);
+    assert_impl!(SinkErrInto<SyncSink, *const (), *const ()>: Sync);
+    assert_not_impl!(SinkErrInto<LocalSink<()>, (), ()>: Sync);
+    assert_impl!(SinkErrInto<UnpinSink, PhantomPinned, PhantomPinned>: Unpin);
+    assert_not_impl!(SinkErrInto<PinnedSink<()>, (), ()>: Unpin);
+
+    assert_impl!(SinkMapErr<SendSink, ()>: Send);
+    assert_not_impl!(SinkMapErr<SendSink, *const ()>: Send);
+    assert_not_impl!(SinkMapErr<LocalSink<()>, ()>: Send);
+    assert_impl!(SinkMapErr<SyncSink, ()>: Sync);
+    assert_not_impl!(SinkMapErr<SyncSink, *const ()>: Sync);
+    assert_not_impl!(SinkMapErr<LocalSink<()>, ()>: Sync);
+    assert_impl!(SinkMapErr<UnpinSink, PhantomPinned>: Unpin);
+    assert_not_impl!(SinkMapErr<PinnedSink<()>, ()>: Unpin);
+
+    assert_impl!(Unfold<(), (), ()>: Send);
+    assert_not_impl!(Unfold<*const (), (), ()>: Send);
+    assert_not_impl!(Unfold<(), *const (), ()>: Send);
+    assert_not_impl!(Unfold<(), (), *const ()>: Send);
+    assert_impl!(Unfold<(), (), ()>: Sync);
+    assert_not_impl!(Unfold<*const (), (), ()>: Sync);
+    assert_not_impl!(Unfold<(), *const (), ()>: Sync);
+    assert_not_impl!(Unfold<(), (), *const ()>: Sync);
+    assert_impl!(Unfold<PhantomPinned, PhantomPinned, ()>: Unpin);
+    assert_not_impl!(Unfold<PinnedSink<()>, (), PhantomPinned>: Unpin);
+
+    assert_impl!(With<(), *const (), *const (), (), ()>: Send);
+    assert_not_impl!(With<*const (), (), (), (), ()>: Send);
+    assert_not_impl!(With<(), (), (), *const (), ()>: Send);
+    assert_not_impl!(With<(), (), (), (), *const ()>: Send);
+    assert_impl!(With<(), *const (), *const (), (), ()>: Sync);
+    assert_not_impl!(With<*const (), (), (), (), ()>: Sync);
+    assert_not_impl!(With<(), (), (), *const (), ()>: Sync);
+    assert_not_impl!(With<(), (), (), (), *const ()>: Sync);
+    assert_impl!(With<(), PhantomPinned, PhantomPinned, (), PhantomPinned>: Unpin);
+    assert_not_impl!(With<PhantomPinned, (), (), (), ()>: Unpin);
+    assert_not_impl!(With<(), (), (), PhantomPinned, ()>: Unpin);
+
+    assert_impl!(WithFlatMap<(), (), *const (), (), ()>: Send);
+    assert_not_impl!(WithFlatMap<*const (), (), (), (), ()>: Send);
+    assert_not_impl!(WithFlatMap<(), *const (), (), (), ()>: Send);
+    assert_not_impl!(WithFlatMap<(), (), (), *const (), ()>: Send);
+    assert_not_impl!(WithFlatMap<(), (), (), (), *const ()>: Send);
+    assert_impl!(WithFlatMap<(), (), *const (), (), ()>: Sync);
+    assert_not_impl!(WithFlatMap<*const (), (), (), (), ()>: Sync);
+    assert_not_impl!(WithFlatMap<(), *const (), (), (), ()>: Sync);
+    assert_not_impl!(WithFlatMap<(), (), (), *const (), ()>: Sync);
+    assert_not_impl!(WithFlatMap<(), (), (), (), *const ()>: Sync);
+    assert_impl!(WithFlatMap<(), PhantomPinned, PhantomPinned, (), PhantomPinned>: Unpin);
+    assert_not_impl!(WithFlatMap<PhantomPinned, (), (), (), ()>: Unpin);
+    assert_not_impl!(WithFlatMap<(), (), (), PhantomPinned, ()>: Unpin);
+}
+
+/// Assert Send/Sync/Unpin for all public types in `futures::stream`.
+pub mod stream {
+    use super::*;
+    use futures::{io, stream::*};
+
+    assert_impl!(AndThen<(), (), ()>: Send);
+    assert_not_impl!(AndThen<*const (), (), ()>: Send);
+    assert_not_impl!(AndThen<(), *const (), ()>: Send);
+    assert_not_impl!(AndThen<(), (), *const ()>: Send);
+    assert_impl!(AndThen<(), (), ()>: Sync);
+    assert_not_impl!(AndThen<*const (), (), ()>: Sync);
+    assert_not_impl!(AndThen<(), *const (), ()>: Sync);
+    assert_not_impl!(AndThen<(), (), *const ()>: Sync);
+    assert_impl!(AndThen<(), (), PhantomPinned>: Unpin);
+    assert_not_impl!(AndThen<PhantomPinned, (), ()>: Unpin);
+    assert_not_impl!(AndThen<(), PhantomPinned, ()>: Unpin);
+
+    assert_impl!(BufferUnordered<SendStream<()>>: Send);
+    assert_not_impl!(BufferUnordered<SendStream>: Send);
+    assert_not_impl!(BufferUnordered<LocalStream>: Send);
+    assert_impl!(BufferUnordered<SyncStream<()>>: Sync);
+    assert_not_impl!(BufferUnordered<SyncStream>: Sync);
+    assert_not_impl!(BufferUnordered<LocalStream>: Sync);
+    assert_impl!(BufferUnordered<UnpinStream>: Unpin);
+    assert_not_impl!(BufferUnordered<PinnedStream>: Unpin);
+
+    assert_impl!(Buffered<SendStream<SendFuture<()>>>: Send);
+    assert_not_impl!(Buffered<SendStream<SendFuture>>: Send);
+    assert_not_impl!(Buffered<SendStream<LocalFuture>>: Send);
+    assert_not_impl!(Buffered<LocalStream<SendFuture<()>>>: Send);
+    assert_impl!(Buffered<SyncStream<SyncFuture<()>>>: Sync);
+    assert_not_impl!(Buffered<SyncStream<SyncFuture>>: Sync);
+    assert_not_impl!(Buffered<SyncStream<LocalFuture>>: Sync);
+    assert_not_impl!(Buffered<LocalStream<SyncFuture<()>>>: Sync);
+    assert_impl!(Buffered<UnpinStream<PinnedFuture>>: Unpin);
+    assert_not_impl!(Buffered<PinnedStream<PinnedFuture>>: Unpin);
+
+    assert_impl!(CatchUnwind<SendStream>: Send);
+    assert_not_impl!(CatchUnwind<LocalStream>: Send);
+    assert_impl!(CatchUnwind<SyncStream>: Sync);
+    assert_not_impl!(CatchUnwind<LocalStream>: Sync);
+    assert_impl!(CatchUnwind<UnpinStream>: Unpin);
+    assert_not_impl!(CatchUnwind<PinnedStream>: Unpin);
+
+    assert_impl!(Chain<(), ()>: Send);
+    assert_not_impl!(Chain<(), *const ()>: Send);
+    assert_not_impl!(Chain<*const (), ()>: Send);
+    assert_impl!(Chain<(), ()>: Sync);
+    assert_not_impl!(Chain<(), *const ()>: Sync);
+    assert_not_impl!(Chain<*const (), ()>: Sync);
+    assert_impl!(Chain<(), ()>: Unpin);
+    assert_not_impl!(Chain<(), PhantomPinned>: Unpin);
+    assert_not_impl!(Chain<PhantomPinned, ()>: Unpin);
+
+    assert_impl!(Chunks<SendStream<()>>: Send);
+    assert_not_impl!(Chunks<SendStream>: Send);
+    assert_not_impl!(Chunks<LocalStream>: Send);
+    assert_impl!(Chunks<SyncStream<()>>: Sync);
+    assert_not_impl!(Chunks<SyncStream>: Sync);
+    assert_not_impl!(Chunks<LocalStream>: Sync);
+    assert_impl!(Chunks<UnpinStream>: Unpin);
+    assert_not_impl!(Chunks<PinnedStream>: Unpin);
+
+    assert_impl!(Collect<(), ()>: Send);
+    assert_not_impl!(Collect<*const (), ()>: Send);
+    assert_not_impl!(Collect<(), *const ()>: Send);
+    assert_impl!(Collect<(), ()>: Sync);
+    assert_not_impl!(Collect<*const (), ()>: Sync);
+    assert_not_impl!(Collect<(), *const ()>: Sync);
+    assert_impl!(Collect<(), PhantomPinned>: Unpin);
+    assert_not_impl!(Collect<PhantomPinned, ()>: Unpin);
+
+    assert_impl!(Concat<SendStream<()>>: Send);
+    assert_not_impl!(Concat<SendStream>: Send);
+    assert_not_impl!(Concat<LocalStream>: Send);
+    assert_impl!(Concat<SyncStream<()>>: Sync);
+    assert_not_impl!(Concat<SyncStream>: Sync);
+    assert_not_impl!(Concat<LocalStream>: Sync);
+    assert_impl!(Concat<UnpinStream>: Unpin);
+    assert_not_impl!(Concat<PinnedStream>: Unpin);
+
+    assert_impl!(Cycle<()>: Send);
+    assert_not_impl!(Cycle<*const ()>: Send);
+    assert_impl!(Cycle<()>: Sync);
+    assert_not_impl!(Cycle<*const ()>: Sync);
+    assert_impl!(Cycle<()>: Unpin);
+    assert_not_impl!(Cycle<PhantomPinned>: Unpin);
+
+    assert_impl!(Empty<()>: Send);
+    assert_not_impl!(Empty<*const ()>: Send);
+    assert_impl!(Empty<()>: Sync);
+    assert_not_impl!(Empty<*const ()>: Sync);
+    assert_impl!(Empty<PhantomPinned>: Unpin);
+
+    assert_impl!(Enumerate<()>: Send);
+    assert_not_impl!(Enumerate<*const ()>: Send);
+    assert_impl!(Enumerate<()>: Sync);
+    assert_not_impl!(Enumerate<*const ()>: Sync);
+    assert_impl!(Enumerate<()>: Unpin);
+    assert_not_impl!(Enumerate<PhantomPinned>: Unpin);
+
+    assert_impl!(ErrInto<(), *const ()>: Send);
+    assert_not_impl!(ErrInto<*const (), ()>: Send);
+    assert_impl!(ErrInto<(), *const ()>: Sync);
+    assert_not_impl!(ErrInto<*const (), ()>: Sync);
+    assert_impl!(ErrInto<(), PhantomPinned>: Unpin);
+    assert_not_impl!(ErrInto<PhantomPinned, ()>: Unpin);
+
+    assert_impl!(Filter<SendStream<()>, (), ()>: Send);
+    assert_not_impl!(Filter<LocalStream<()>, (), ()>: Send);
+    assert_not_impl!(Filter<SendStream, (), ()>: Send);
+    assert_not_impl!(Filter<SendStream<()>, *const (), ()>: Send);
+    assert_not_impl!(Filter<SendStream<()>, (), *const ()>: Send);
+    assert_impl!(Filter<SyncStream<()>, (), ()>: Sync);
+    assert_not_impl!(Filter<LocalStream<()>, (), ()>: Sync);
+    assert_not_impl!(Filter<SyncStream, (), ()>: Sync);
+    assert_not_impl!(Filter<SyncStream<()>, *const (), ()>: Sync);
+    assert_not_impl!(Filter<SyncStream<()>, (), *const ()>: Sync);
+    assert_impl!(Filter<UnpinStream, (), PhantomPinned>: Unpin);
+    assert_not_impl!(Filter<PinnedStream, (), ()>: Unpin);
+    assert_not_impl!(Filter<UnpinStream, PhantomPinned, ()>: Unpin);
+
+    assert_impl!(FilterMap<(), (), ()>: Send);
+    assert_not_impl!(FilterMap<*const (), (), ()>: Send);
+    assert_not_impl!(FilterMap<(), *const (), ()>: Send);
+    assert_not_impl!(FilterMap<(), (), *const ()>: Send);
+    assert_impl!(FilterMap<(), (), ()>: Sync);
+    assert_not_impl!(FilterMap<*const (), (), ()>: Sync);
+    assert_not_impl!(FilterMap<(), *const (), ()>: Sync);
+    assert_not_impl!(FilterMap<(), (), *const ()>: Sync);
+    assert_impl!(FilterMap<(), (), PhantomPinned>: Unpin);
+    assert_not_impl!(FilterMap<PhantomPinned, (), ()>: Unpin);
+    assert_not_impl!(FilterMap<(), PhantomPinned, ()>: Unpin);
+
+    assert_impl!(FlatMap<(), (), ()>: Send);
+    assert_not_impl!(FlatMap<*const (), (), ()>: Send);
+    assert_not_impl!(FlatMap<(), *const (), ()>: Send);
+    assert_not_impl!(FlatMap<(), (), *const ()>: Send);
+    assert_impl!(FlatMap<(), (), ()>: Sync);
+    assert_not_impl!(FlatMap<*const (), (), ()>: Sync);
+    assert_not_impl!(FlatMap<(), *const (), ()>: Sync);
+    assert_not_impl!(FlatMap<(), (), *const ()>: Sync);
+    assert_impl!(FlatMap<(), (), PhantomPinned>: Unpin);
+    assert_not_impl!(FlatMap<PhantomPinned, (), ()>: Unpin);
+    assert_not_impl!(FlatMap<(), PhantomPinned, ()>: Unpin);
+
+    assert_impl!(Flatten<SendStream<()>>: Send);
+    assert_not_impl!(Flatten<SendStream>: Send);
+    assert_not_impl!(Flatten<SendStream>: Send);
+    assert_impl!(Flatten<SyncStream<()>>: Sync);
+    assert_not_impl!(Flatten<LocalStream<()>>: Sync);
+    assert_not_impl!(Flatten<LocalStream<()>>: Sync);
+    assert_impl!(Flatten<UnpinStream<()>>: Unpin);
+    assert_not_impl!(Flatten<UnpinStream>: Unpin);
+    assert_not_impl!(Flatten<PinnedStream>: Unpin);
+
+    assert_impl!(Fold<(), (), (), ()>: Send);
+    assert_not_impl!(Fold<*const (), (), (), ()>: Send);
+    assert_not_impl!(Fold<(), *const (), (), ()>: Send);
+    assert_not_impl!(Fold<(), (), *const (), ()>: Send);
+    assert_not_impl!(Fold<(), (), (), *const ()>: Send);
+    assert_impl!(Fold<(), (), (), ()>: Sync);
+    assert_not_impl!(Fold<*const (), (), (), ()>: Sync);
+    assert_not_impl!(Fold<(), *const (), (), ()>: Sync);
+    assert_not_impl!(Fold<(), (), *const (), ()>: Sync);
+    assert_not_impl!(Fold<(), (), (), *const ()>: Sync);
+    assert_impl!(Fold<(), (), PhantomPinned, PhantomPinned>: Unpin);
+    assert_not_impl!(Fold<PhantomPinned, (), (), ()>: Unpin);
+    assert_not_impl!(Fold<(), PhantomPinned, (), ()>: Unpin);
+
+    assert_impl!(ForEach<(), (), ()>: Send);
+    assert_not_impl!(ForEach<*const (), (), ()>: Send);
+    assert_not_impl!(ForEach<(), *const (), ()>: Send);
+    assert_not_impl!(ForEach<(), (), *const ()>: Send);
+    assert_impl!(ForEach<(), (), ()>: Sync);
+    assert_not_impl!(ForEach<*const (), (), ()>: Sync);
+    assert_not_impl!(ForEach<(), *const (), ()>: Sync);
+    assert_not_impl!(ForEach<(), (), *const ()>: Sync);
+    assert_impl!(ForEach<(), (), PhantomPinned>: Unpin);
+    assert_not_impl!(ForEach<PhantomPinned, (), ()>: Unpin);
+    assert_not_impl!(ForEach<(), PhantomPinned, ()>: Unpin);
+
+    assert_impl!(ForEachConcurrent<(), (), ()>: Send);
+    assert_not_impl!(ForEachConcurrent<*const (), (), ()>: Send);
+    assert_not_impl!(ForEachConcurrent<(), *const (), ()>: Send);
+    assert_not_impl!(ForEachConcurrent<(), (), *const ()>: Send);
+    assert_impl!(ForEachConcurrent<(), (), ()>: Sync);
+    assert_not_impl!(ForEachConcurrent<*const (), (), ()>: Sync);
+    assert_not_impl!(ForEachConcurrent<(), *const (), ()>: Sync);
+    assert_not_impl!(ForEachConcurrent<(), (), *const ()>: Sync);
+    assert_impl!(ForEachConcurrent<(), PhantomPinned, PhantomPinned>: Unpin);
+    assert_not_impl!(ForEachConcurrent<PhantomPinned, (), ()>: Unpin);
+
+    assert_impl!(Forward<SendTryStream<()>, ()>: Send);
+    assert_not_impl!(Forward<SendTryStream, ()>: Send);
+    assert_not_impl!(Forward<SendTryStream<()>, *const ()>: Send);
+    assert_not_impl!(Forward<LocalTryStream, ()>: Send);
+    assert_impl!(Forward<SyncTryStream<()>, ()>: Sync);
+    assert_not_impl!(Forward<SyncTryStream, ()>: Sync);
+    assert_not_impl!(Forward<SyncTryStream<()>, *const ()>: Sync);
+    assert_not_impl!(Forward<LocalTryStream, ()>: Sync);
+    assert_impl!(Forward<UnpinTryStream, ()>: Unpin);
+    assert_not_impl!(Forward<UnpinTryStream, PhantomPinned>: Unpin);
+    assert_not_impl!(Forward<PinnedTryStream, ()>: Unpin);
+
+    assert_impl!(Fuse<()>: Send);
+    assert_not_impl!(Fuse<*const ()>: Send);
+    assert_impl!(Fuse<()>: Sync);
+    assert_not_impl!(Fuse<*const ()>: Sync);
+    assert_impl!(Fuse<()>: Unpin);
+    assert_not_impl!(Fuse<PhantomPinned>: Unpin);
+
+    assert_impl!(FuturesOrdered<SendFuture<()>>: Send);
+    assert_not_impl!(FuturesOrdered<SendFuture>: Send);
+    assert_not_impl!(FuturesOrdered<SendFuture>: Send);
+    assert_impl!(FuturesOrdered<SyncFuture<()>>: Sync);
+    assert_not_impl!(FuturesOrdered<LocalFuture<()>>: Sync);
+    assert_not_impl!(FuturesOrdered<LocalFuture<()>>: Sync);
+    assert_impl!(FuturesOrdered<PinnedFuture>: Unpin);
+
+    assert_impl!(FuturesUnordered<()>: Send);
+    assert_not_impl!(FuturesUnordered<*const ()>: Send);
+    assert_impl!(FuturesUnordered<()>: Sync);
+    assert_not_impl!(FuturesUnordered<*const ()>: Sync);
+    assert_impl!(FuturesUnordered<PhantomPinned>: Unpin);
+
+    assert_impl!(Inspect<(), ()>: Send);
+    assert_not_impl!(Inspect<*const (), ()>: Send);
+    assert_not_impl!(Inspect<(), *const ()>: Send);
+    assert_impl!(Inspect<(), ()>: Sync);
+    assert_not_impl!(Inspect<*const (), ()>: Sync);
+    assert_not_impl!(Inspect<(), *const ()>: Sync);
+    assert_impl!(Inspect<(), PhantomPinned>: Unpin);
+    assert_not_impl!(Inspect<PhantomPinned, ()>: Unpin);
+
+    assert_impl!(InspectErr<(), ()>: Send);
+    assert_not_impl!(InspectErr<*const (), ()>: Send);
+    assert_not_impl!(InspectErr<(), *const ()>: Send);
+    assert_impl!(InspectErr<(), ()>: Sync);
+    assert_not_impl!(InspectErr<*const (), ()>: Sync);
+    assert_not_impl!(InspectErr<(), *const ()>: Sync);
+    assert_impl!(InspectErr<(), PhantomPinned>: Unpin);
+    assert_not_impl!(InspectErr<PhantomPinned, ()>: Unpin);
+
+    assert_impl!(InspectOk<(), ()>: Send);
+    assert_not_impl!(InspectOk<*const (), ()>: Send);
+    assert_not_impl!(InspectOk<(), *const ()>: Send);
+    assert_impl!(InspectOk<(), ()>: Sync);
+    assert_not_impl!(InspectOk<*const (), ()>: Sync);
+    assert_not_impl!(InspectOk<(), *const ()>: Sync);
+    assert_impl!(InspectOk<(), PhantomPinned>: Unpin);
+    assert_not_impl!(InspectOk<PhantomPinned, ()>: Unpin);
+
+    assert_impl!(IntoAsyncRead<SendTryStream<Vec<u8>, io::Error>>: Send);
+    assert_not_impl!(IntoAsyncRead<LocalTryStream<Vec<u8>, io::Error>>: Send);
+    assert_impl!(IntoAsyncRead<SyncTryStream<Vec<u8>, io::Error>>: Sync);
+    assert_not_impl!(IntoAsyncRead<LocalTryStream<Vec<u8>, io::Error>>: Sync);
+    assert_impl!(IntoAsyncRead<UnpinTryStream<Vec<u8>, io::Error>>: Unpin);
+    // IntoAsyncRead requires `St: Unpin`
+    // assert_not_impl!(IntoAsyncRead<PinnedTryStream<Vec<u8>, io::Error>>: Unpin);
+
+    assert_impl!(IntoStream<()>: Send);
+    assert_not_impl!(IntoStream<*const ()>: Send);
+    assert_impl!(IntoStream<()>: Sync);
+    assert_not_impl!(IntoStream<*const ()>: Sync);
+    assert_impl!(IntoStream<()>: Unpin);
+    assert_not_impl!(IntoStream<PhantomPinned>: Unpin);
+
+    assert_impl!(Iter<()>: Send);
+    assert_not_impl!(Iter<*const ()>: Send);
+    assert_impl!(Iter<()>: Sync);
+    assert_not_impl!(Iter<*const ()>: Sync);
+    assert_impl!(Iter<PhantomPinned>: Unpin);
+
+    assert_impl!(Map<(), ()>: Send);
+    assert_not_impl!(Map<*const (), ()>: Send);
+    assert_not_impl!(Map<(), *const ()>: Send);
+    assert_impl!(Map<(), ()>: Sync);
+    assert_not_impl!(Map<*const (), ()>: Sync);
+    assert_not_impl!(Map<(), *const ()>: Sync);
+    assert_impl!(Map<(), PhantomPinned>: Unpin);
+    assert_not_impl!(Map<PhantomPinned, ()>: Unpin);
+
+    assert_impl!(MapErr<(), ()>: Send);
+    assert_not_impl!(MapErr<*const (), ()>: Send);
+    assert_not_impl!(MapErr<(), *const ()>: Send);
+    assert_impl!(MapErr<(), ()>: Sync);
+    assert_not_impl!(MapErr<*const (), ()>: Sync);
+    assert_not_impl!(MapErr<(), *const ()>: Sync);
+    assert_impl!(MapErr<(), PhantomPinned>: Unpin);
+    assert_not_impl!(MapErr<PhantomPinned, ()>: Unpin);
+
+    assert_impl!(MapOk<(), ()>: Send);
+    assert_not_impl!(MapOk<*const (), ()>: Send);
+    assert_not_impl!(MapOk<(), *const ()>: Send);
+    assert_impl!(MapOk<(), ()>: Sync);
+    assert_not_impl!(MapOk<*const (), ()>: Sync);
+    assert_not_impl!(MapOk<(), *const ()>: Sync);
+    assert_impl!(MapOk<(), PhantomPinned>: Unpin);
+    assert_not_impl!(MapOk<PhantomPinned, ()>: Unpin);
+
+    assert_impl!(Next<'_, ()>: Send);
+    assert_not_impl!(Next<'_, *const ()>: Send);
+    assert_impl!(Next<'_, ()>: Sync);
+    assert_not_impl!(Next<'_, *const ()>: Sync);
+    assert_impl!(Next<'_, ()>: Unpin);
+    assert_not_impl!(Next<'_, PhantomPinned>: Unpin);
+
+    assert_impl!(NextIf<'_, SendStream<()>, ()>: Send);
+    assert_not_impl!(NextIf<'_, SendStream<()>, *const ()>: Send);
+    assert_not_impl!(NextIf<'_, SendStream, ()>: Send);
+    assert_not_impl!(NextIf<'_, LocalStream<()>, ()>: Send);
+    assert_impl!(NextIf<'_, SyncStream<()>, ()>: Sync);
+    assert_not_impl!(NextIf<'_, SyncStream<()>, *const ()>: Sync);
+    assert_not_impl!(NextIf<'_, SyncStream, ()>: Sync);
+    assert_not_impl!(NextIf<'_, LocalStream<()>, ()>: Send);
+    assert_impl!(NextIf<'_, PinnedStream, PhantomPinned>: Unpin);
+
+    assert_impl!(NextIfEq<'_, SendStream<()>, ()>: Send);
+    assert_not_impl!(NextIfEq<'_, SendStream<()>, *const ()>: Send);
+    assert_not_impl!(NextIfEq<'_, SendStream, ()>: Send);
+    assert_not_impl!(NextIfEq<'_, LocalStream<()>, ()>: Send);
+    assert_impl!(NextIfEq<'_, SyncStream<()>, ()>: Sync);
+    assert_not_impl!(NextIfEq<'_, SyncStream<()>, *const ()>: Sync);
+    assert_not_impl!(NextIfEq<'_, SyncStream, ()>: Sync);
+    assert_not_impl!(NextIfEq<'_, LocalStream<()>, ()>: Send);
+    assert_impl!(NextIfEq<'_, PinnedStream, PhantomPinned>: Unpin);
+
+    assert_impl!(Once<()>: Send);
+    assert_not_impl!(Once<*const ()>: Send);
+    assert_impl!(Once<()>: Sync);
+    assert_not_impl!(Once<*const ()>: Sync);
+    assert_impl!(Once<()>: Unpin);
+    assert_not_impl!(Once<PhantomPinned>: Unpin);
+
+    assert_impl!(OrElse<(), (), ()>: Send);
+    assert_not_impl!(OrElse<*const (), (), ()>: Send);
+    assert_not_impl!(OrElse<(), *const (), ()>: Send);
+    assert_not_impl!(OrElse<(), (), *const ()>: Send);
+    assert_impl!(OrElse<(), (), ()>: Sync);
+    assert_not_impl!(OrElse<*const (), (), ()>: Sync);
+    assert_not_impl!(OrElse<(), *const (), ()>: Sync);
+    assert_not_impl!(OrElse<(), (), *const ()>: Sync);
+    assert_impl!(OrElse<(), (), PhantomPinned>: Unpin);
+    assert_not_impl!(OrElse<PhantomPinned, (), ()>: Unpin);
+    assert_not_impl!(OrElse<(), PhantomPinned, ()>: Unpin);
+
+    assert_impl!(Peek<'_, SendStream<()>>: Send);
+    assert_not_impl!(Peek<'_, SendStream>: Send);
+    assert_not_impl!(Peek<'_, LocalStream<()>>: Send);
+    assert_impl!(Peek<'_, SyncStream<()>>: Sync);
+    assert_not_impl!(Peek<'_, SyncStream>: Sync);
+    assert_not_impl!(Peek<'_, LocalStream<()>>: Sync);
+    assert_impl!(Peek<'_, PinnedStream>: Unpin);
+
+    assert_impl!(Peekable<SendStream<()>>: Send);
+    assert_not_impl!(Peekable<SendStream>: Send);
+    assert_not_impl!(Peekable<LocalStream>: Send);
+    assert_impl!(Peekable<SyncStream<()>>: Sync);
+    assert_not_impl!(Peekable<SyncStream>: Sync);
+    assert_not_impl!(Peekable<LocalStream>: Sync);
+    assert_impl!(Peekable<UnpinStream>: Unpin);
+    assert_not_impl!(Peekable<PinnedStream>: Unpin);
+
+    assert_impl!(Pending<()>: Send);
+    assert_not_impl!(Pending<*const ()>: Send);
+    assert_impl!(Pending<()>: Sync);
+    assert_not_impl!(Pending<*const ()>: Sync);
+    assert_impl!(Pending<PhantomPinned>: Unpin);
+
+    assert_impl!(PollFn<()>: Send);
+    assert_not_impl!(PollFn<*const ()>: Send);
+    assert_impl!(PollFn<()>: Sync);
+    assert_not_impl!(PollFn<*const ()>: Sync);
+    assert_impl!(PollFn<PhantomPinned>: Unpin);
+
+    assert_impl!(ReadyChunks<SendStream<()>>: Send);
+    assert_not_impl!(ReadyChunks<SendStream>: Send);
+    assert_not_impl!(ReadyChunks<LocalStream>: Send);
+    assert_impl!(ReadyChunks<SyncStream<()>>: Sync);
+    assert_not_impl!(ReadyChunks<SyncStream>: Sync);
+    assert_not_impl!(ReadyChunks<LocalStream>: Sync);
+    assert_impl!(ReadyChunks<UnpinStream>: Unpin);
+    assert_not_impl!(ReadyChunks<PinnedStream>: Unpin);
+
+    assert_impl!(Repeat<()>: Send);
+    assert_not_impl!(Repeat<*const ()>: Send);
+    assert_impl!(Repeat<()>: Sync);
+    assert_not_impl!(Repeat<*const ()>: Sync);
+    assert_impl!(Repeat<PhantomPinned>: Unpin);
+
+    assert_impl!(RepeatWith<()>: Send);
+    assert_not_impl!(RepeatWith<*const ()>: Send);
+    assert_impl!(RepeatWith<()>: Sync);
+    assert_not_impl!(RepeatWith<*const ()>: Sync);
+    // RepeatWith requires `F: FnMut() -> A`
+    assert_impl!(RepeatWith<fn() -> ()>: Unpin);
+    // assert_impl!(RepeatWith<PhantomPinned>: Unpin);
+
+    assert_impl!(ReuniteError<(), ()>: Send);
+    assert_not_impl!(ReuniteError<*const (), ()>: Send);
+    assert_not_impl!(ReuniteError<(), *const ()>: Send);
+    assert_impl!(ReuniteError<(), ()>: Sync);
+    assert_not_impl!(ReuniteError<*const (), ()>: Sync);
+    assert_not_impl!(ReuniteError<(), *const ()>: Sync);
+    assert_impl!(ReuniteError<PhantomPinned, PhantomPinned>: Unpin);
+
+    assert_impl!(Scan<SendStream, (), (), ()>: Send);
+    assert_not_impl!(Scan<LocalStream<()>, (), (), ()>: Send);
+    assert_not_impl!(Scan<SendStream<()>, *const (), (), ()>: Send);
+    assert_not_impl!(Scan<SendStream<()>, (), *const (), ()>: Send);
+    assert_not_impl!(Scan<SendStream<()>, (), (), *const ()>: Send);
+    assert_impl!(Scan<SyncStream, (), (), ()>: Sync);
+    assert_not_impl!(Scan<LocalStream<()>, (), (), ()>: Sync);
+    assert_not_impl!(Scan<SyncStream<()>, *const (), (), ()>: Sync);
+    assert_not_impl!(Scan<SyncStream<()>, (), *const (), ()>: Sync);
+    assert_not_impl!(Scan<SyncStream<()>, (), (), *const ()>: Sync);
+    assert_impl!(Scan<UnpinStream, PhantomPinned, (), PhantomPinned>: Unpin);
+    assert_not_impl!(Scan<PinnedStream, (), (), ()>: Unpin);
+    assert_not_impl!(Scan<UnpinStream, (), PhantomPinned, ()>: Unpin);
+
+    assert_impl!(Select<(), ()>: Send);
+    assert_not_impl!(Select<*const (), ()>: Send);
+    assert_not_impl!(Select<(), *const ()>: Send);
+    assert_impl!(Select<(), ()>: Sync);
+    assert_not_impl!(Select<*const (), ()>: Sync);
+    assert_not_impl!(Select<(), *const ()>: Sync);
+    assert_impl!(Select<(), ()>: Unpin);
+    assert_not_impl!(Select<PhantomPinned, ()>: Unpin);
+    assert_not_impl!(Select<(), PhantomPinned>: Unpin);
+
+    assert_impl!(SelectAll<()>: Send);
+    assert_not_impl!(SelectAll<*const ()>: Send);
+    assert_impl!(SelectAll<()>: Sync);
+    assert_not_impl!(SelectAll<*const ()>: Sync);
+    assert_impl!(SelectAll<PhantomPinned>: Unpin);
+
+    assert_impl!(SelectNextSome<'_, ()>: Send);
+    assert_not_impl!(SelectNextSome<'_, *const ()>: Send);
+    assert_impl!(SelectNextSome<'_, ()>: Sync);
+    assert_not_impl!(SelectNextSome<'_, *const ()>: Sync);
+    assert_impl!(SelectNextSome<'_, PhantomPinned>: Unpin);
+
+    assert_impl!(Skip<()>: Send);
+    assert_not_impl!(Skip<*const ()>: Send);
+    assert_impl!(Skip<()>: Sync);
+    assert_not_impl!(Skip<*const ()>: Sync);
+    assert_impl!(Skip<()>: Unpin);
+    assert_not_impl!(Skip<PhantomPinned>: Unpin);
+
+    assert_impl!(SkipWhile<SendStream<()>, (), ()>: Send);
+    assert_not_impl!(SkipWhile<LocalStream<()>, (), ()>: Send);
+    assert_not_impl!(SkipWhile<SendStream, (), ()>: Send);
+    assert_not_impl!(SkipWhile<SendStream<()>, *const (), ()>: Send);
+    assert_not_impl!(SkipWhile<SendStream<()>, (), *const ()>: Send);
+    assert_impl!(SkipWhile<SyncStream<()>, (), ()>: Sync);
+    assert_not_impl!(SkipWhile<LocalStream<()>, (), ()>: Sync);
+    assert_not_impl!(SkipWhile<SyncStream, (), ()>: Sync);
+    assert_not_impl!(SkipWhile<SyncStream<()>, *const (), ()>: Sync);
+    assert_not_impl!(SkipWhile<SyncStream<()>, (), *const ()>: Sync);
+    assert_impl!(SkipWhile<UnpinStream, (), PhantomPinned>: Unpin);
+    assert_not_impl!(SkipWhile<PinnedStream, (), ()>: Unpin);
+    assert_not_impl!(SkipWhile<UnpinStream, PhantomPinned, ()>: Unpin);
+
+    assert_impl!(SplitSink<(), ()>: Send);
+    assert_not_impl!(SplitSink<*const (), ()>: Send);
+    assert_not_impl!(SplitSink<(), *const ()>: Send);
+    assert_impl!(SplitSink<(), ()>: Sync);
+    assert_not_impl!(SplitSink<*const (), ()>: Sync);
+    assert_not_impl!(SplitSink<(), *const ()>: Sync);
+    assert_impl!(SplitSink<PhantomPinned, PhantomPinned>: Unpin);
+
+    assert_impl!(SplitStream<()>: Send);
+    assert_not_impl!(SplitStream<*const ()>: Send);
+    assert_impl!(SplitStream<()>: Sync);
+    assert_not_impl!(SplitStream<*const ()>: Sync);
+    assert_impl!(SplitStream<PhantomPinned>: Unpin);
+
+    assert_impl!(StreamFuture<()>: Send);
+    assert_not_impl!(StreamFuture<*const ()>: Send);
+    assert_impl!(StreamFuture<()>: Sync);
+    assert_not_impl!(StreamFuture<*const ()>: Sync);
+    assert_impl!(StreamFuture<()>: Unpin);
+    assert_not_impl!(StreamFuture<PhantomPinned>: Unpin);
+
+    assert_impl!(Take<()>: Send);
+    assert_not_impl!(Take<*const ()>: Send);
+    assert_impl!(Take<()>: Sync);
+    assert_not_impl!(Take<*const ()>: Sync);
+    assert_impl!(Take<()>: Unpin);
+    assert_not_impl!(Take<PhantomPinned>: Unpin);
+
+    assert_impl!(TakeUntil<SendStream, SendFuture<()>>: Send);
+    assert_not_impl!(TakeUntil<SendStream, SendFuture>: Send);
+    assert_not_impl!(TakeUntil<SendStream, LocalFuture<()>>: Send);
+    assert_not_impl!(TakeUntil<LocalStream, SendFuture<()>>: Send);
+    assert_impl!(TakeUntil<SyncStream, SyncFuture<()>>: Sync);
+    assert_not_impl!(TakeUntil<SyncStream, SyncFuture>: Sync);
+    assert_not_impl!(TakeUntil<SyncStream, LocalFuture<()>>: Sync);
+    assert_not_impl!(TakeUntil<LocalStream, SyncFuture<()>>: Sync);
+    assert_impl!(TakeUntil<UnpinStream, UnpinFuture>: Unpin);
+    assert_not_impl!(TakeUntil<PinnedStream, UnpinFuture>: Unpin);
+    assert_not_impl!(TakeUntil<UnpinStream, PinnedFuture>: Unpin);
+
+    assert_impl!(TakeWhile<SendStream<()>, (), ()>: Send);
+    assert_not_impl!(TakeWhile<LocalStream<()>, (), ()>: Send);
+    assert_not_impl!(TakeWhile<SendStream, (), ()>: Send);
+    assert_not_impl!(TakeWhile<SendStream<()>, *const (), ()>: Send);
+    assert_not_impl!(TakeWhile<SendStream<()>, (), *const ()>: Send);
+    assert_impl!(TakeWhile<SyncStream<()>, (), ()>: Sync);
+    assert_not_impl!(TakeWhile<LocalStream<()>, (), ()>: Sync);
+    assert_not_impl!(TakeWhile<SyncStream, (), ()>: Sync);
+    assert_not_impl!(TakeWhile<SyncStream<()>, *const (), ()>: Sync);
+    assert_not_impl!(TakeWhile<SyncStream<()>, (), *const ()>: Sync);
+    assert_impl!(TakeWhile<UnpinStream, (), PhantomPinned>: Unpin);
+    assert_not_impl!(TakeWhile<PinnedStream, (), ()>: Unpin);
+    assert_not_impl!(TakeWhile<UnpinStream, PhantomPinned, ()>: Unpin);
+
+    assert_impl!(Then<SendStream, (), ()>: Send);
+    assert_not_impl!(Then<LocalStream<()>, (), ()>: Send);
+    assert_not_impl!(Then<SendStream<()>, *const (), ()>: Send);
+    assert_not_impl!(Then<SendStream<()>, (), *const ()>: Send);
+    assert_impl!(Then<SyncStream, (), ()>: Sync);
+    assert_not_impl!(Then<LocalStream<()>, (), ()>: Sync);
+    assert_not_impl!(Then<SyncStream<()>, *const (), ()>: Sync);
+    assert_not_impl!(Then<SyncStream<()>, (), *const ()>: Sync);
+    assert_impl!(Then<UnpinStream, (), PhantomPinned>: Unpin);
+    assert_not_impl!(Then<PinnedStream, (), ()>: Unpin);
+    assert_not_impl!(Then<UnpinStream, PhantomPinned, ()>: Unpin);
+
+    assert_impl!(TryBufferUnordered<SendTryStream<()>>: Send);
+    assert_not_impl!(TryBufferUnordered<SendTryStream>: Send);
+    assert_not_impl!(TryBufferUnordered<LocalTryStream>: Send);
+    assert_impl!(TryBufferUnordered<SyncTryStream<()>>: Sync);
+    assert_not_impl!(TryBufferUnordered<SyncTryStream>: Sync);
+    assert_not_impl!(TryBufferUnordered<LocalTryStream>: Sync);
+    assert_impl!(TryBufferUnordered<UnpinTryStream>: Unpin);
+    assert_not_impl!(TryBufferUnordered<PinnedTryStream>: Unpin);
+
+    assert_impl!(TryBuffered<SendTryStream<SendTryFuture<(), ()>>>: Send);
+    assert_not_impl!(TryBuffered<SendTryStream<SendTryFuture<*const (), ()>>>: Send);
+    assert_not_impl!(TryBuffered<SendTryStream<SendTryFuture<(), *const ()>>>: Send);
+    assert_not_impl!(TryBuffered<SendTryStream<LocalTryFuture<(), ()>>>: Send);
+    assert_not_impl!(TryBuffered<LocalTryStream<SendTryFuture<(), ()>>>: Send);
+    assert_impl!(TryBuffered<SyncTryStream<SyncTryFuture<(), ()>>>: Sync);
+    assert_not_impl!(TryBuffered<SyncTryStream<SyncTryFuture<*const (), ()>>>: Sync);
+    assert_not_impl!(TryBuffered<SyncTryStream<SyncTryFuture<(), *const ()>>>: Sync);
+    assert_not_impl!(TryBuffered<SyncTryStream<LocalTryFuture<(), ()>>>: Sync);
+    assert_not_impl!(TryBuffered<LocalTryStream<SyncTryFuture<(), ()>>>: Sync);
+    assert_impl!(TryBuffered<UnpinTryStream<PinnedTryFuture>>: Unpin);
+    assert_not_impl!(TryBuffered<PinnedTryStream<UnpinTryFuture>>: Unpin);
+
+    assert_impl!(TryCollect<(), ()>: Send);
+    assert_not_impl!(TryCollect<*const (), ()>: Send);
+    assert_not_impl!(TryCollect<(), *const ()>: Send);
+    assert_impl!(TryCollect<(), ()>: Sync);
+    assert_not_impl!(TryCollect<*const (), ()>: Sync);
+    assert_not_impl!(TryCollect<(), *const ()>: Sync);
+    assert_impl!(TryCollect<(), PhantomPinned>: Unpin);
+    assert_not_impl!(TryCollect<PhantomPinned, ()>: Unpin);
+
+    assert_impl!(TryConcat<SendTryStream<()>>: Send);
+    assert_not_impl!(TryConcat<SendTryStream>: Send);
+    assert_not_impl!(TryConcat<LocalTryStream>: Send);
+    assert_impl!(TryConcat<SyncTryStream<()>>: Sync);
+    assert_not_impl!(TryConcat<SyncTryStream>: Sync);
+    assert_not_impl!(TryConcat<LocalTryStream>: Sync);
+    assert_impl!(TryConcat<UnpinTryStream>: Unpin);
+    assert_not_impl!(TryConcat<PinnedTryStream>: Unpin);
+
+    assert_impl!(TryFilter<SendTryStream<()>, (), ()>: Send);
+    assert_not_impl!(TryFilter<LocalTryStream<()>, (), ()>: Send);
+    assert_not_impl!(TryFilter<SendTryStream, (), ()>: Send);
+    assert_not_impl!(TryFilter<SendTryStream<()>, *const (), ()>: Send);
+    assert_not_impl!(TryFilter<SendTryStream<()>, (), *const ()>: Send);
+    assert_impl!(TryFilter<SyncTryStream<()>, (), ()>: Sync);
+    assert_not_impl!(TryFilter<LocalTryStream<()>, (), ()>: Sync);
+    assert_not_impl!(TryFilter<SyncTryStream, (), ()>: Sync);
+    assert_not_impl!(TryFilter<SyncTryStream<()>, *const (), ()>: Sync);
+    assert_not_impl!(TryFilter<SyncTryStream<()>, (), *const ()>: Sync);
+    assert_impl!(TryFilter<UnpinTryStream, (), PhantomPinned>: Unpin);
+    assert_not_impl!(TryFilter<PinnedTryStream, (), ()>: Unpin);
+    assert_not_impl!(TryFilter<UnpinTryStream, PhantomPinned, ()>: Unpin);
+
+    assert_impl!(TryFilterMap<(), (), ()>: Send);
+    assert_not_impl!(TryFilterMap<*const (), (), ()>: Send);
+    assert_not_impl!(TryFilterMap<(), *const (), ()>: Send);
+    assert_not_impl!(TryFilterMap<(), (), *const ()>: Send);
+    assert_impl!(TryFilterMap<(), (), ()>: Sync);
+    assert_not_impl!(TryFilterMap<*const (), (), ()>: Sync);
+    assert_not_impl!(TryFilterMap<(), *const (), ()>: Sync);
+    assert_not_impl!(TryFilterMap<(), (), *const ()>: Sync);
+    assert_impl!(TryFilterMap<(), (), PhantomPinned>: Unpin);
+    assert_not_impl!(TryFilterMap<PhantomPinned, (), ()>: Unpin);
+    assert_not_impl!(TryFilterMap<(), PhantomPinned, ()>: Unpin);
+
+    assert_impl!(TryFlatten<SendTryStream<()>>: Send);
+    assert_not_impl!(TryFlatten<SendTryStream>: Send);
+    assert_not_impl!(TryFlatten<SendTryStream>: Send);
+    assert_impl!(TryFlatten<SyncTryStream<()>>: Sync);
+    assert_not_impl!(TryFlatten<LocalTryStream<()>>: Sync);
+    assert_not_impl!(TryFlatten<LocalTryStream<()>>: Sync);
+    assert_impl!(TryFlatten<UnpinTryStream<()>>: Unpin);
+    assert_not_impl!(TryFlatten<UnpinTryStream>: Unpin);
+    assert_not_impl!(TryFlatten<PinnedTryStream>: Unpin);
+
+    assert_impl!(TryFold<(), (), (), ()>: Send);
+    assert_not_impl!(TryFold<*const (), (), (), ()>: Send);
+    assert_not_impl!(TryFold<(), *const (), (), ()>: Send);
+    assert_not_impl!(TryFold<(), (), *const (), ()>: Send);
+    assert_not_impl!(TryFold<(), (), (), *const ()>: Send);
+    assert_impl!(TryFold<(), (), (), ()>: Sync);
+    assert_not_impl!(TryFold<*const (), (), (), ()>: Sync);
+    assert_not_impl!(TryFold<(), *const (), (), ()>: Sync);
+    assert_not_impl!(TryFold<(), (), *const (), ()>: Sync);
+    assert_not_impl!(TryFold<(), (), (), *const ()>: Sync);
+    assert_impl!(TryFold<(), (), PhantomPinned, PhantomPinned>: Unpin);
+    assert_not_impl!(TryFold<PhantomPinned, (), (), ()>: Unpin);
+    assert_not_impl!(TryFold<(), PhantomPinned, (), ()>: Unpin);
+
+    assert_impl!(TryForEach<(), (), ()>: Send);
+    assert_not_impl!(TryForEach<*const (), (), ()>: Send);
+    assert_not_impl!(TryForEach<(), *const (), ()>: Send);
+    assert_not_impl!(TryForEach<(), (), *const ()>: Send);
+    assert_impl!(TryForEach<(), (), ()>: Sync);
+    assert_not_impl!(TryForEach<*const (), (), ()>: Sync);
+    assert_not_impl!(TryForEach<(), *const (), ()>: Sync);
+    assert_not_impl!(TryForEach<(), (), *const ()>: Sync);
+    assert_impl!(TryForEach<(), (), PhantomPinned>: Unpin);
+    assert_not_impl!(TryForEach<PhantomPinned, (), ()>: Unpin);
+    assert_not_impl!(TryForEach<(), PhantomPinned, ()>: Unpin);
+
+    assert_impl!(TryForEachConcurrent<(), (), ()>: Send);
+    assert_not_impl!(TryForEachConcurrent<*const (), (), ()>: Send);
+    assert_not_impl!(TryForEachConcurrent<(), *const (), ()>: Send);
+    assert_not_impl!(TryForEachConcurrent<(), (), *const ()>: Send);
+    assert_impl!(TryForEachConcurrent<(), (), ()>: Sync);
+    assert_not_impl!(TryForEachConcurrent<*const (), (), ()>: Sync);
+    assert_not_impl!(TryForEachConcurrent<(), *const (), ()>: Sync);
+    assert_not_impl!(TryForEachConcurrent<(), (), *const ()>: Sync);
+    assert_impl!(TryForEachConcurrent<(), PhantomPinned, PhantomPinned>: Unpin);
+    assert_not_impl!(TryForEachConcurrent<PhantomPinned, (), ()>: Unpin);
+
+    assert_impl!(TryNext<'_, ()>: Send);
+    assert_not_impl!(TryNext<'_, *const ()>: Send);
+    assert_impl!(TryNext<'_, ()>: Sync);
+    assert_not_impl!(TryNext<'_, *const ()>: Sync);
+    assert_impl!(TryNext<'_, ()>: Unpin);
+    assert_not_impl!(TryNext<'_, PhantomPinned>: Unpin);
+
+    assert_impl!(TrySkipWhile<SendTryStream<()>, (), ()>: Send);
+    assert_not_impl!(TrySkipWhile<LocalTryStream<()>, (), ()>: Send);
+    assert_not_impl!(TrySkipWhile<SendTryStream, (), ()>: Send);
+    assert_not_impl!(TrySkipWhile<SendTryStream<()>, *const (), ()>: Send);
+    assert_not_impl!(TrySkipWhile<SendTryStream<()>, (), *const ()>: Send);
+    assert_impl!(TrySkipWhile<SyncTryStream<()>, (), ()>: Sync);
+    assert_not_impl!(TrySkipWhile<LocalTryStream<()>, (), ()>: Sync);
+    assert_not_impl!(TrySkipWhile<SyncTryStream, (), ()>: Sync);
+    assert_not_impl!(TrySkipWhile<SyncTryStream<()>, *const (), ()>: Sync);
+    assert_not_impl!(TrySkipWhile<SyncTryStream<()>, (), *const ()>: Sync);
+    assert_impl!(TrySkipWhile<UnpinTryStream, (), PhantomPinned>: Unpin);
+    assert_not_impl!(TrySkipWhile<PinnedTryStream, (), ()>: Unpin);
+    assert_not_impl!(TrySkipWhile<UnpinTryStream, PhantomPinned, ()>: Unpin);
+
+    assert_impl!(TryTakeWhile<SendTryStream<()>, (), ()>: Send);
+    assert_not_impl!(TryTakeWhile<LocalTryStream<()>, (), ()>: Send);
+    assert_not_impl!(TryTakeWhile<SendTryStream, (), ()>: Send);
+    assert_not_impl!(TryTakeWhile<SendTryStream<()>, *const (), ()>: Send);
+    assert_not_impl!(TryTakeWhile<SendTryStream<()>, (), *const ()>: Send);
+    assert_impl!(TryTakeWhile<SyncTryStream<()>, (), ()>: Sync);
+    assert_not_impl!(TryTakeWhile<LocalTryStream<()>, (), ()>: Sync);
+    assert_not_impl!(TryTakeWhile<SyncTryStream, (), ()>: Sync);
+    assert_not_impl!(TryTakeWhile<SyncTryStream<()>, *const (), ()>: Sync);
+    assert_not_impl!(TryTakeWhile<SyncTryStream<()>, (), *const ()>: Sync);
+    assert_impl!(TryTakeWhile<UnpinTryStream, (), PhantomPinned>: Unpin);
+    assert_not_impl!(TryTakeWhile<PinnedTryStream, (), ()>: Unpin);
+    assert_not_impl!(TryTakeWhile<UnpinTryStream, PhantomPinned, ()>: Unpin);
+
+    assert_impl!(TryUnfold<(), (), ()>: Send);
+    assert_not_impl!(TryUnfold<*const (), (), ()>: Send);
+    assert_not_impl!(TryUnfold<(), *const (), ()>: Send);
+    assert_not_impl!(TryUnfold<(), (), *const ()>: Send);
+    assert_impl!(TryUnfold<(), (), ()>: Sync);
+    assert_not_impl!(TryUnfold<*const (), (), ()>: Sync);
+    assert_not_impl!(TryUnfold<(), *const (), ()>: Sync);
+    assert_not_impl!(TryUnfold<(), (), *const ()>: Sync);
+    assert_impl!(TryUnfold<PhantomPinned, PhantomPinned, ()>: Unpin);
+    assert_not_impl!(TryUnfold<(), (), PhantomPinned>: Unpin);
+
+    assert_impl!(Unfold<(), (), ()>: Send);
+    assert_not_impl!(Unfold<*const (), (), ()>: Send);
+    assert_not_impl!(Unfold<(), *const (), ()>: Send);
+    assert_not_impl!(Unfold<(), (), *const ()>: Send);
+    assert_impl!(Unfold<(), (), ()>: Sync);
+    assert_not_impl!(Unfold<*const (), (), ()>: Sync);
+    assert_not_impl!(Unfold<(), *const (), ()>: Sync);
+    assert_not_impl!(Unfold<(), (), *const ()>: Sync);
+    assert_impl!(Unfold<PhantomPinned, PhantomPinned, ()>: Unpin);
+    assert_not_impl!(Unfold<(), (), PhantomPinned>: Unpin);
+
+    assert_impl!(Unzip<(), (), ()>: Send);
+    assert_not_impl!(Unzip<*const (), (), ()>: Send);
+    assert_not_impl!(Unzip<(), *const (), ()>: Send);
+    assert_not_impl!(Unzip<(), (), *const ()>: Send);
+    assert_impl!(Unzip<(), (), ()>: Sync);
+    assert_not_impl!(Unzip<*const (), (), ()>: Sync);
+    assert_not_impl!(Unzip<(), *const (), ()>: Sync);
+    assert_not_impl!(Unzip<(), (), *const ()>: Sync);
+    assert_impl!(Unzip<(), PhantomPinned, PhantomPinned>: Unpin);
+    assert_not_impl!(Unzip<PhantomPinned, (), ()>: Unpin);
+
+    assert_impl!(Zip<SendStream<()>, SendStream<()>>: Send);
+    assert_not_impl!(Zip<SendStream, SendStream<()>>: Send);
+    assert_not_impl!(Zip<SendStream<()>, SendStream>: Send);
+    assert_not_impl!(Zip<LocalStream, SendStream<()>>: Send);
+    assert_not_impl!(Zip<SendStream<()>, LocalStream>: Send);
+    assert_impl!(Zip<SyncStream<()>, SyncStream<()>>: Sync);
+    assert_not_impl!(Zip<SyncStream, SyncStream<()>>: Sync);
+    assert_not_impl!(Zip<SyncStream<()>, SyncStream>: Sync);
+    assert_not_impl!(Zip<LocalStream, SyncStream<()>>: Sync);
+    assert_not_impl!(Zip<SyncStream<()>, LocalStream>: Sync);
+    assert_impl!(Zip<UnpinStream, UnpinStream>: Unpin);
+    assert_not_impl!(Zip<UnpinStream, PinnedStream>: Unpin);
+    assert_not_impl!(Zip<PinnedStream, UnpinStream>: Unpin);
+
+    assert_impl!(futures_unordered::Iter<()>: Send);
+    assert_not_impl!(futures_unordered::Iter<*const ()>: Send);
+    assert_impl!(futures_unordered::Iter<()>: Sync);
+    assert_not_impl!(futures_unordered::Iter<*const ()>: Sync);
+    assert_impl!(futures_unordered::Iter<()>: Unpin);
+    // The definition of futures_unordered::Iter has `Fut: Unpin` bounds.
+    // assert_not_impl!(futures_unordered::Iter<PhantomPinned>: Unpin);
+
+    assert_impl!(futures_unordered::IterMut<()>: Send);
+    assert_not_impl!(futures_unordered::IterMut<*const ()>: Send);
+    assert_impl!(futures_unordered::IterMut<()>: Sync);
+    assert_not_impl!(futures_unordered::IterMut<*const ()>: Sync);
+    assert_impl!(futures_unordered::IterMut<()>: Unpin);
+    // The definition of futures_unordered::IterMut has `Fut: Unpin` bounds.
+    // assert_not_impl!(futures_unordered::IterMut<PhantomPinned>: Unpin);
+
+    assert_impl!(futures_unordered::IterPinMut<()>: Send);
+    assert_not_impl!(futures_unordered::IterPinMut<*const ()>: Send);
+    assert_impl!(futures_unordered::IterPinMut<()>: Sync);
+    assert_not_impl!(futures_unordered::IterPinMut<*const ()>: Sync);
+    assert_impl!(futures_unordered::IterPinMut<PhantomPinned>: Unpin);
+
+    assert_impl!(futures_unordered::IterPinRef<()>: Send);
+    assert_not_impl!(futures_unordered::IterPinRef<*const ()>: Send);
+    assert_impl!(futures_unordered::IterPinRef<()>: Sync);
+    assert_not_impl!(futures_unordered::IterPinRef<*const ()>: Sync);
+    assert_impl!(futures_unordered::IterPinRef<PhantomPinned>: Unpin);
+
+    assert_impl!(futures_unordered::IntoIter<()>: Send);
+    assert_not_impl!(futures_unordered::IntoIter<*const ()>: Send);
+    assert_impl!(futures_unordered::IntoIter<()>: Sync);
+    assert_not_impl!(futures_unordered::IntoIter<*const ()>: Sync);
+    // The definition of futures_unordered::IntoIter has `Fut: Unpin` bounds.
+    // assert_not_impl!(futures_unordered::IntoIter<PhantomPinned>: Unpin);
+}
+
+/// Assert Send/Sync/Unpin for all public types in `futures::task`.
+pub mod task {
+    use super::*;
+    use futures::task::*;
+
+    assert_impl!(AtomicWaker: Send);
+    assert_impl!(AtomicWaker: Sync);
+    assert_impl!(AtomicWaker: Unpin);
+
+    assert_impl!(FutureObj<*const ()>: Send);
+    assert_not_impl!(FutureObj<()>: Sync);
+    assert_impl!(FutureObj<PhantomPinned>: Unpin);
+
+    assert_not_impl!(LocalFutureObj<()>: Send);
+    assert_not_impl!(LocalFutureObj<()>: Sync);
+    assert_impl!(LocalFutureObj<PhantomPinned>: Unpin);
+
+    assert_impl!(SpawnError: Send);
+    assert_impl!(SpawnError: Sync);
+    assert_impl!(SpawnError: Unpin);
+
+    assert_impl!(WakerRef<'_>: Send);
+    assert_impl!(WakerRef<'_>: Sync);
+    assert_impl!(WakerRef<'_>: Unpin);
+}
diff --git a/third_party/rust/futures/tests/compat.rs b/third_party/rust/futures/tests/compat.rs
index ba4c897bd67698c06c2ea63609b977418d4a0981..c4125d895b3339f37bce495786d954aba56df97a 100644
--- a/third_party/rust/futures/tests/compat.rs
+++ b/third_party/rust/futures/tests/compat.rs
@@ -1,14 +1,14 @@
-use tokio::timer::Delay;
-use tokio::runtime::Runtime;
-use std::time::Instant;
-use futures::prelude::*;
+#![cfg(feature = "compat")]
+
 use futures::compat::Future01CompatExt;
+use futures::prelude::*;
+use std::time::Instant;
+use tokio::runtime::Runtime;
+use tokio::timer::Delay;
 
 #[test]
 fn can_use_01_futures_in_a_03_future_running_on_a_01_executor() {
-    let f = async {
-        Delay::new(Instant::now()).compat().await
-    };
+    let f = async { Delay::new(Instant::now()).compat().await };
 
     let mut runtime = Runtime::new().unwrap();
     runtime.block_on(f.boxed().compat()).unwrap();
diff --git a/third_party/rust/futures/tests/eager_drop.rs b/third_party/rust/futures/tests/eager_drop.rs
index 11edb1b6de7dcf60396e9cc848c92ae257f08bd0..992507774c57932daaad329508e25fa28f8947d9 100644
--- a/third_party/rust/futures/tests/eager_drop.rs
+++ b/third_party/rust/futures/tests/eager_drop.rs
@@ -1,16 +1,23 @@
+use futures::channel::oneshot;
+use futures::future::{self, Future, FutureExt, TryFutureExt};
+use futures::task::{Context, Poll};
+use futures_test::future::FutureTestExt;
+use pin_project::pin_project;
+use std::pin::Pin;
+use std::sync::mpsc;
+
 #[test]
 fn map_ok() {
-    use futures::future::{self, FutureExt, TryFutureExt};
-    use futures_test::future::FutureTestExt;
-    use std::sync::mpsc;
-
     // The closure given to `map_ok` should have been dropped by the time `map`
     // runs.
     let (tx1, rx1) = mpsc::channel::<()>();
     let (tx2, rx2) = mpsc::channel::<()>();
 
     future::ready::<Result<i32, i32>>(Err(1))
-        .map_ok(move |_| { let _tx1 = tx1; panic!("should not run"); })
+        .map_ok(move |_| {
+            let _tx1 = tx1;
+            panic!("should not run");
+        })
         .map(move |_| {
             assert!(rx1.recv().is_err());
             tx2.send(()).unwrap()
@@ -22,17 +29,16 @@ fn map_ok() {
 
 #[test]
 fn map_err() {
-    use futures::future::{self, FutureExt, TryFutureExt};
-    use futures_test::future::FutureTestExt;
-    use std::sync::mpsc;
-
     // The closure given to `map_err` should have been dropped by the time `map`
     // runs.
     let (tx1, rx1) = mpsc::channel::<()>();
     let (tx2, rx2) = mpsc::channel::<()>();
 
     future::ready::<Result<i32, i32>>(Ok(1))
-        .map_err(move |_| { let _tx1 = tx1; panic!("should not run"); })
+        .map_err(move |_| {
+            let _tx1 = tx1;
+            panic!("should not run");
+        })
         .map(move |_| {
             assert!(rx1.recv().is_err());
             tx2.send(()).unwrap()
@@ -42,96 +48,74 @@ fn map_err() {
     rx2.recv().unwrap();
 }
 
-mod channelled {
-    use futures::future::Future;
-    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,
-    }
+#[pin_project]
+struct FutureData<F, T> {
+    _data: T,
+    #[pin]
+    future: F,
+}
 
-    impl<F: Future, T: Send + 'static> Future for FutureData<F, T> {
-        type Output = F::Output;
+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.project().future.poll(cx)
-        }
+    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<F::Output> {
+        self.project().future.poll(cx)
     }
+}
 
-    #[test]
-    fn then_drops_eagerly() {
-        use futures::channel::oneshot;
-        use futures::future::{self, FutureExt, TryFutureExt};
-        use futures_test::future::FutureTestExt;
-        use std::sync::mpsc;
-
-        let (tx0, rx0) = oneshot::channel::<()>();
-        let (tx1, rx1) = mpsc::channel::<()>();
-        let (tx2, rx2) = mpsc::channel::<()>();
-
-        FutureData { _data: tx1, future: rx0.unwrap_or_else(|_| { panic!() }) }
-            .then(move |_| {
-                assert!(rx1.recv().is_err()); // tx1 should have been dropped
-                tx2.send(()).unwrap();
-                future::ready(())
-            })
-            .run_in_background();
-
-        assert_eq!(Err(mpsc::TryRecvError::Empty), rx2.try_recv());
-        tx0.send(()).unwrap();
-        rx2.recv().unwrap();
-    }
+#[test]
+fn then_drops_eagerly() {
+    let (tx0, rx0) = oneshot::channel::<()>();
+    let (tx1, rx1) = mpsc::channel::<()>();
+    let (tx2, rx2) = mpsc::channel::<()>();
 
-    #[test]
-    fn and_then_drops_eagerly() {
-        use futures::channel::oneshot;
-        use futures::future::{self, TryFutureExt};
-        use futures_test::future::FutureTestExt;
-        use std::sync::mpsc;
-
-        let (tx0, rx0) = oneshot::channel::<Result<(), ()>>();
-        let (tx1, rx1) = mpsc::channel::<()>();
-        let (tx2, rx2) = mpsc::channel::<()>();
-
-        FutureData { _data: tx1, future: rx0.unwrap_or_else(|_| { panic!() }) }
-            .and_then(move |_| {
-                assert!(rx1.recv().is_err()); // tx1 should have been dropped
-                tx2.send(()).unwrap();
-                future::ready(Ok(()))
-            })
-            .run_in_background();
-
-        assert_eq!(Err(mpsc::TryRecvError::Empty), rx2.try_recv());
-        tx0.send(Ok(())).unwrap();
-        rx2.recv().unwrap();
-    }
+    FutureData { _data: tx1, future: rx0.unwrap_or_else(|_| panic!()) }
+        .then(move |_| {
+            assert!(rx1.recv().is_err()); // tx1 should have been dropped
+            tx2.send(()).unwrap();
+            future::ready(())
+        })
+        .run_in_background();
 
-    #[test]
-    fn or_else_drops_eagerly() {
-        use futures::channel::oneshot;
-        use futures::future::{self, TryFutureExt};
-        use futures_test::future::FutureTestExt;
-        use std::sync::mpsc;
-
-        let (tx0, rx0) = oneshot::channel::<Result<(), ()>>();
-        let (tx1, rx1) = mpsc::channel::<()>();
-        let (tx2, rx2) = mpsc::channel::<()>();
-
-        FutureData { _data: tx1, future: rx0.unwrap_or_else(|_| { panic!() }) }
-            .or_else(move |_| {
-                assert!(rx1.recv().is_err()); // tx1 should have been dropped
-                tx2.send(()).unwrap();
-                future::ready::<Result<(), ()>>(Ok(()))
-            })
-            .run_in_background();
-
-        assert_eq!(Err(mpsc::TryRecvError::Empty), rx2.try_recv());
-        tx0.send(Err(())).unwrap();
-        rx2.recv().unwrap();
-    }
+    assert_eq!(Err(mpsc::TryRecvError::Empty), rx2.try_recv());
+    tx0.send(()).unwrap();
+    rx2.recv().unwrap();
+}
+
+#[test]
+fn and_then_drops_eagerly() {
+    let (tx0, rx0) = oneshot::channel::<Result<(), ()>>();
+    let (tx1, rx1) = mpsc::channel::<()>();
+    let (tx2, rx2) = mpsc::channel::<()>();
+
+    FutureData { _data: tx1, future: rx0.unwrap_or_else(|_| panic!()) }
+        .and_then(move |_| {
+            assert!(rx1.recv().is_err()); // tx1 should have been dropped
+            tx2.send(()).unwrap();
+            future::ready(Ok(()))
+        })
+        .run_in_background();
+
+    assert_eq!(Err(mpsc::TryRecvError::Empty), rx2.try_recv());
+    tx0.send(Ok(())).unwrap();
+    rx2.recv().unwrap();
+}
+
+#[test]
+fn or_else_drops_eagerly() {
+    let (tx0, rx0) = oneshot::channel::<Result<(), ()>>();
+    let (tx1, rx1) = mpsc::channel::<()>();
+    let (tx2, rx2) = mpsc::channel::<()>();
+
+    FutureData { _data: tx1, future: rx0.unwrap_or_else(|_| panic!()) }
+        .or_else(move |_| {
+            assert!(rx1.recv().is_err()); // tx1 should have been dropped
+            tx2.send(()).unwrap();
+            future::ready::<Result<(), ()>>(Ok(()))
+        })
+        .run_in_background();
+
+    assert_eq!(Err(mpsc::TryRecvError::Empty), rx2.try_recv());
+    tx0.send(Err(())).unwrap();
+    rx2.recv().unwrap();
 }
diff --git a/third_party/rust/futures/tests/abortable.rs b/third_party/rust/futures/tests/future_abortable.rs
similarity index 69%
rename from third_party/rust/futures/tests/abortable.rs
rename to third_party/rust/futures/tests/future_abortable.rs
index 6b5a25c365c49ce484919b3b061a39e03014a05d..e119f0b719900d99ada3ce9ac64552714f9d5bf7 100644
--- a/third_party/rust/futures/tests/abortable.rs
+++ b/third_party/rust/futures/tests/future_abortable.rs
@@ -1,45 +1,44 @@
+use futures::channel::oneshot;
+use futures::executor::block_on;
+use futures::future::{abortable, Aborted, FutureExt};
+use futures::task::{Context, Poll};
+use futures_test::task::new_count_waker;
+
 #[test]
 fn abortable_works() {
-    use futures::channel::oneshot;
-    use futures::future::{abortable, Aborted};
-    use futures::executor::block_on;
-
     let (_tx, a_rx) = oneshot::channel::<()>();
     let (abortable_rx, abort_handle) = abortable(a_rx);
 
     abort_handle.abort();
+    assert!(abortable_rx.is_aborted());
     assert_eq!(Err(Aborted), block_on(abortable_rx));
 }
 
 #[test]
 fn abortable_awakens() {
-    use futures::channel::oneshot;
-    use futures::future::{abortable, Aborted, FutureExt};
-    use futures::task::{Context, Poll};
-    use futures_test::task::new_count_waker;
-
     let (_tx, a_rx) = oneshot::channel::<()>();
     let (mut abortable_rx, abort_handle) = abortable(a_rx);
 
     let (waker, counter) = new_count_waker();
     let mut cx = Context::from_waker(&waker);
+
     assert_eq!(counter, 0);
     assert_eq!(Poll::Pending, abortable_rx.poll_unpin(&mut cx));
     assert_eq!(counter, 0);
+
     abort_handle.abort();
     assert_eq!(counter, 1);
+    assert!(abortable_rx.is_aborted());
     assert_eq!(Poll::Ready(Err(Aborted)), abortable_rx.poll_unpin(&mut cx));
 }
 
 #[test]
 fn abortable_resolves() {
-    use futures::channel::oneshot;
-    use futures::future::abortable;
-    use futures::executor::block_on;
     let (tx, a_rx) = oneshot::channel::<()>();
     let (abortable_rx, _abort_handle) = abortable(a_rx);
 
     tx.send(()).unwrap();
 
+    assert!(!abortable_rx.is_aborted());
     assert_eq!(Ok(Ok(())), block_on(abortable_rx));
 }
diff --git a/third_party/rust/futures/tests/basic_combinators.rs b/third_party/rust/futures/tests/future_basic_combinators.rs
similarity index 92%
rename from third_party/rust/futures/tests/basic_combinators.rs
rename to third_party/rust/futures/tests/future_basic_combinators.rs
index fa65b6f5f1a1c35e87ff79b25015c156a87f052c..372ab48b7976e4ee4715321d26dbf1a731b60d70 100644
--- a/third_party/rust/futures/tests/basic_combinators.rs
+++ b/third_party/rust/futures/tests/future_basic_combinators.rs
@@ -13,17 +13,21 @@ fn basic_future_combinators() {
             tx1.send(x).unwrap(); // Send 1
             tx1.send(2).unwrap(); // Send 2
             future::ready(3)
-        }).map(move |x| {
+        })
+        .map(move |x| {
             tx2.send(x).unwrap(); // Send 3
             tx2.send(4).unwrap(); // Send 4
             5
-        }).map(move |x| {
+        })
+        .map(move |x| {
             tx3.send(x).unwrap(); // Send 5
         });
 
     assert!(rx.try_recv().is_err()); // Not started yet
     fut.run_in_background(); // Start it
-    for i in 1..=5 { assert_eq!(rx.recv(), Ok(i)); } // Check it
+    for i in 1..=5 {
+        assert_eq!(rx.recv(), Ok(i));
+    } // Check it
     assert!(rx.recv().is_err()); // Should be done
 }
 
@@ -93,6 +97,8 @@ fn basic_try_future_combinators() {
 
     assert!(rx.try_recv().is_err()); // Not started yet
     fut.run_in_background(); // Start it
-    for i in 1..=12 { assert_eq!(rx.recv(), Ok(i)); } // Check it
+    for i in 1..=12 {
+        assert_eq!(rx.recv(), Ok(i));
+    } // Check it
     assert!(rx.recv().is_err()); // Should be done
 }
diff --git a/third_party/rust/futures/tests/fuse.rs b/third_party/rust/futures/tests/future_fuse.rs
similarity index 100%
rename from third_party/rust/futures/tests/fuse.rs
rename to third_party/rust/futures/tests/future_fuse.rs
diff --git a/third_party/rust/futures/tests/future_inspect.rs b/third_party/rust/futures/tests/future_inspect.rs
new file mode 100644
index 0000000000000000000000000000000000000000..eacd1f78a25d929b93c89b9fe4e289a05ca9f894
--- /dev/null
+++ b/third_party/rust/futures/tests/future_inspect.rs
@@ -0,0 +1,16 @@
+use futures::executor::block_on;
+use futures::future::{self, FutureExt};
+
+#[test]
+fn smoke() {
+    let mut counter = 0;
+
+    {
+        let work = future::ready::<i32>(40).inspect(|val| {
+            counter += *val;
+        });
+        assert_eq!(block_on(work), 40);
+    }
+
+    assert_eq!(counter, 40);
+}
diff --git a/third_party/rust/futures/tests/future_join_all.rs b/third_party/rust/futures/tests/future_join_all.rs
new file mode 100644
index 0000000000000000000000000000000000000000..ae05a21b7ca61d76cb5199b9cd537eff4493c2de
--- /dev/null
+++ b/third_party/rust/futures/tests/future_join_all.rs
@@ -0,0 +1,42 @@
+use futures::executor::block_on;
+use futures::future::{join_all, ready, Future, JoinAll};
+use std::fmt::Debug;
+
+fn assert_done<T, F>(actual_fut: F, expected: T)
+where
+    T: PartialEq + Debug,
+    F: FnOnce() -> Box<dyn Future<Output = T> + Unpin>,
+{
+    let output = block_on(actual_fut());
+    assert_eq!(output, expected);
+}
+
+#[test]
+fn collect_collects() {
+    assert_done(|| Box::new(join_all(vec![ready(1), ready(2)])), vec![1, 2]);
+    assert_done(|| Box::new(join_all(vec![ready(1)])), vec![1]);
+    // REVIEW: should this be implemented?
+    // assert_done(|| Box::new(join_all(Vec::<i32>::new())), vec![]);
+
+    // TODO: needs more tests
+}
+
+#[test]
+fn join_all_iter_lifetime() {
+    // In futures-rs version 0.1, this function would fail to typecheck due to an overly
+    // conservative type parameterization of `JoinAll`.
+    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))
+    }
+
+    assert_done(|| sizes(vec![&[1, 2, 3], &[], &[0]]), vec![3_usize, 0, 1]);
+}
+
+#[test]
+fn join_all_from_iter() {
+    assert_done(
+        || Box::new(vec![ready(1), ready(2)].into_iter().collect::<JoinAll<_>>()),
+        vec![1, 2],
+    )
+}
diff --git a/third_party/rust/futures/tests/future_obj.rs b/third_party/rust/futures/tests/future_obj.rs
index c6b18fc85c8eae05a62a7350c28860c0dfcfea51..0e5253464e59743e94ff8b1599e2395f50b3bffe 100644
--- a/third_party/rust/futures/tests/future_obj.rs
+++ b/third_party/rust/futures/tests/future_obj.rs
@@ -1,6 +1,6 @@
-use futures::future::{Future, FutureObj, FutureExt};
-use std::pin::Pin;
+use futures::future::{Future, FutureExt, FutureObj};
 use futures::task::{Context, Poll};
+use std::pin::Pin;
 
 #[test]
 fn dropping_does_not_segfault() {
diff --git a/third_party/rust/futures/tests/select_all.rs b/third_party/rust/futures/tests/future_select_all.rs
similarity index 69%
rename from third_party/rust/futures/tests/select_all.rs
rename to third_party/rust/futures/tests/future_select_all.rs
index 540db2c410731aec57a71a3bfc2a63ffc829af3b..299b4790442376aa4aa3f434dfe09b60c51d5cfa 100644
--- a/third_party/rust/futures/tests/select_all.rs
+++ b/third_party/rust/futures/tests/future_select_all.rs
@@ -1,14 +1,10 @@
+use futures::executor::block_on;
+use futures::future::{ready, select_all};
+use std::collections::HashSet;
+
 #[test]
 fn smoke() {
-    use futures::executor::block_on;
-    use futures::future::{ready, select_all};
-    use std::collections::HashSet;
-
-    let v = vec![
-        ready(1),
-        ready(2),
-        ready(3),
-    ];
+    let v = vec![ready(1), ready(2), ready(3)];
 
     let mut c = vec![1, 2, 3].into_iter().collect::<HashSet<_>>();
 
diff --git a/third_party/rust/futures/tests/select_ok.rs b/third_party/rust/futures/tests/future_select_ok.rs
similarity index 57%
rename from third_party/rust/futures/tests/select_ok.rs
rename to third_party/rust/futures/tests/future_select_ok.rs
index 81cadb7baec2172c483e6e124dc2cea36688c290..8aec00362d834bd325322ee748d905214e8da5ef 100644
--- a/third_party/rust/futures/tests/select_ok.rs
+++ b/third_party/rust/futures/tests/future_select_ok.rs
@@ -1,14 +1,9 @@
+use futures::executor::block_on;
+use futures::future::{err, ok, select_ok};
+
 #[test]
 fn ignore_err() {
-    use futures::executor::block_on;
-    use futures::future::{err, ok, select_ok};
-
-    let v = vec![
-        err(1),
-        err(2),
-        ok(3),
-        ok(4),
-    ];
+    let v = vec![err(1), err(2), ok(3), ok(4)];
 
     let (i, v) = block_on(select_ok(v)).ok().unwrap();
     assert_eq!(i, 3);
@@ -23,14 +18,7 @@ fn ignore_err() {
 
 #[test]
 fn last_err() {
-    use futures::executor::block_on;
-    use futures::future::{err, ok, select_ok};
-
-    let v = vec![
-        ok(1),
-        err(2),
-        err(3),
-    ];
+    let v = vec![ok(1), err(2), err(3)];
 
     let (i, v) = block_on(select_ok(v)).ok().unwrap();
     assert_eq!(i, 1);
diff --git a/third_party/rust/futures/tests/shared.rs b/third_party/rust/futures/tests/future_shared.rs
similarity index 73%
rename from third_party/rust/futures/tests/shared.rs
rename to third_party/rust/futures/tests/future_shared.rs
index cc0c6a20cff5d7094f6b60f7082acd65f00b3a4f..718d6c41b01ca360d80d40f0d8769a2301b75279 100644
--- a/third_party/rust/futures/tests/shared.rs
+++ b/third_party/rust/futures/tests/future_shared.rs
@@ -1,22 +1,22 @@
-mod count_clone {
-    use std::cell::Cell;
-    use std::rc::Rc;
-
-    pub struct CountClone(pub Rc<Cell<i32>>);
-
-    impl Clone for CountClone {
-        fn clone(&self) -> Self {
-            self.0.set(self.0.get() + 1);
-            Self(self.0.clone())
-        }
+use futures::channel::oneshot;
+use futures::executor::{block_on, LocalPool};
+use futures::future::{self, FutureExt, LocalFutureObj, TryFutureExt};
+use futures::task::LocalSpawn;
+use std::cell::{Cell, RefCell};
+use std::rc::Rc;
+use std::task::Poll;
+use std::thread;
+
+struct CountClone(Rc<Cell<i32>>);
+
+impl Clone for CountClone {
+    fn clone(&self) -> Self {
+        self.0.set(self.0.get() + 1);
+        Self(self.0.clone())
     }
 }
 
 fn send_shared_oneshot_and_wait_on_multiple_threads(threads_number: u32) {
-    use futures::channel::oneshot;
-    use futures::executor::block_on;
-    use futures::future::FutureExt;
-    use std::thread;
     let (tx, rx) = oneshot::channel::<i32>();
     let f = rx.shared();
     let join_handles = (0..threads_number)
@@ -53,11 +53,6 @@ fn many_threads() {
 
 #[test]
 fn drop_on_one_task_ok() {
-    use futures::channel::oneshot;
-    use futures::executor::block_on;
-    use futures::future::{self, FutureExt, TryFutureExt};
-    use std::thread;
-
     let (tx, rx) = oneshot::channel::<u32>();
     let f1 = rx.shared();
     let f2 = f1.clone();
@@ -86,11 +81,6 @@ fn drop_on_one_task_ok() {
 
 #[test]
 fn drop_in_poll() {
-    use futures::executor::block_on;
-    use futures::future::{self, FutureExt, LocalFutureObj};
-    use std::cell::RefCell;
-    use std::rc::Rc;
-
     let slot1 = Rc::new(RefCell::new(None));
     let slot2 = slot1.clone();
 
@@ -108,11 +98,6 @@ fn drop_in_poll() {
 
 #[test]
 fn peek() {
-    use futures::channel::oneshot;
-    use futures::executor::LocalPool;
-    use futures::future::{FutureExt, LocalFutureObj};
-    use futures::task::LocalSpawn;
-
     let mut local_pool = LocalPool::new();
     let spawn = &mut local_pool.spawner();
 
@@ -134,9 +119,7 @@ fn peek() {
     }
 
     // Once the Shared has been polled, the value is peekable on the clone.
-    spawn
-        .spawn_local_obj(LocalFutureObj::new(Box::new(f1.map(|_| ()))))
-        .unwrap();
+    spawn.spawn_local_obj(LocalFutureObj::new(Box::new(f1.map(|_| ())))).unwrap();
     local_pool.run();
     for _ in 0..2 {
         assert_eq!(*f2.peek().unwrap(), Ok(42));
@@ -145,10 +128,6 @@ fn peek() {
 
 #[test]
 fn downgrade() {
-    use futures::channel::oneshot;
-    use futures::executor::block_on;
-    use futures::future::FutureExt;
-
     let (tx, rx) = oneshot::channel::<i32>();
     let shared = rx.shared();
     // Since there are outstanding `Shared`s, we can get a `WeakShared`.
@@ -173,14 +152,6 @@ fn downgrade() {
 
 #[test]
 fn dont_clone_in_single_owner_shared_future() {
-    use futures::channel::oneshot;
-    use futures::executor::block_on;
-    use futures::future::FutureExt;
-    use std::cell::Cell;
-    use std::rc::Rc;
-
-    use count_clone::CountClone;
-
     let counter = CountClone(Rc::new(Cell::new(0)));
     let (tx, rx) = oneshot::channel();
 
@@ -193,14 +164,6 @@ fn dont_clone_in_single_owner_shared_future() {
 
 #[test]
 fn dont_do_unnecessary_clones_on_output() {
-    use futures::channel::oneshot;
-    use futures::executor::block_on;
-    use futures::future::FutureExt;
-    use std::cell::Cell;
-    use std::rc::Rc;
-
-    use count_clone::CountClone;
-
     let counter = CountClone(Rc::new(Cell::new(0)));
     let (tx, rx) = oneshot::channel();
 
@@ -215,11 +178,6 @@ fn dont_do_unnecessary_clones_on_output() {
 
 #[test]
 fn shared_future_that_wakes_itself_until_pending_is_returned() {
-    use futures::executor::block_on;
-    use futures::future::FutureExt;
-    use std::cell::Cell;
-    use std::task::Poll;
-
     let proceed = Cell::new(false);
     let fut = futures::future::poll_fn(|cx| {
         if proceed.get() {
@@ -233,8 +191,5 @@ fn shared_future_that_wakes_itself_until_pending_is_returned() {
 
     // The join future can only complete if the second future gets a chance to run after the first
     // has returned pending
-    assert_eq!(
-        block_on(futures::future::join(fut, async { proceed.set(true) })),
-        ((), ())
-    );
+    assert_eq!(block_on(futures::future::join(fut, async { proceed.set(true) })), ((), ()));
 }
diff --git a/third_party/rust/futures/tests/future_try_flatten_stream.rs b/third_party/rust/futures/tests/future_try_flatten_stream.rs
index 4a614f9c1446041db0f0bfe14469981d6a9c1166..82ae1baf2caeead7e142dfcd807410275f951654 100644
--- a/third_party/rust/futures/tests/future_try_flatten_stream.rs
+++ b/third_party/rust/futures/tests/future_try_flatten_stream.rs
@@ -1,9 +1,14 @@
+use futures::executor::block_on_stream;
+use futures::future::{err, ok, TryFutureExt};
+use futures::sink::Sink;
+use futures::stream::Stream;
+use futures::stream::{self, StreamExt};
+use futures::task::{Context, Poll};
+use std::marker::PhantomData;
+use std::pin::Pin;
+
 #[test]
 fn successful_future() {
-    use futures::executor::block_on_stream;
-    use futures::future::{ok, TryFutureExt};
-    use futures::stream::{self, StreamExt};
-
     let stream_items = vec![17, 19];
     let future_of_a_stream = ok::<_, bool>(stream::iter(stream_items).map(Ok));
 
@@ -17,15 +22,8 @@ fn successful_future() {
 
 #[test]
 fn failed_future() {
-    use core::marker::PhantomData;
-    use core::pin::Pin;
-    use futures::executor::block_on_stream;
-    use futures::future::{err, TryFutureExt};
-    use futures::stream::Stream;
-    use futures::task::{Context, Poll};
-
     struct PanickingStream<T, E> {
-        _marker: PhantomData<(T, E)>
+        _marker: PhantomData<(T, E)>,
     }
 
     impl<T, E> Stream for PanickingStream<T, E> {
@@ -45,13 +43,6 @@ fn failed_future() {
 
 #[test]
 fn assert_impls() {
-    use core::marker::PhantomData;
-    use core::pin::Pin;
-    use futures::sink::Sink;
-    use futures::stream::Stream;
-    use futures::task::{Context, Poll};
-    use futures::future::{ok, TryFutureExt};
-
     struct StreamSink<T, E, Item>(PhantomData<(T, E, Item)>);
 
     impl<T, E, Item> Stream for StreamSink<T, E, Item> {
diff --git a/third_party/rust/futures/tests/try_join_all.rs b/third_party/rust/futures/tests/future_try_join_all.rs
similarity index 59%
rename from third_party/rust/futures/tests/try_join_all.rs
rename to third_party/rust/futures/tests/future_try_join_all.rs
index 8e579a2800444329eda454a346edfd540c2de4d5..a4b3bb76a9af1469705fba17a9a87740a1d94a64 100644
--- a/third_party/rust/futures/tests/try_join_all.rs
+++ b/third_party/rust/futures/tests/future_try_join_all.rs
@@ -1,24 +1,19 @@
-mod util {
-    use std::future::Future;
-    use futures::executor::block_on;
-    use std::fmt::Debug;
-
-    pub fn assert_done<T, F>(actual_fut: F, expected: T)
-    where
-        T: PartialEq + Debug,
-        F: FnOnce() -> Box<dyn Future<Output = T> + Unpin>,
-    {
-        let output = block_on(actual_fut());
-        assert_eq!(output, expected);
-    }
+use futures::executor::block_on;
+use futures_util::future::{err, ok, try_join_all, TryJoinAll};
+use std::fmt::Debug;
+use std::future::Future;
+
+fn assert_done<T, F>(actual_fut: F, expected: T)
+where
+    T: PartialEq + Debug,
+    F: FnOnce() -> Box<dyn Future<Output = T> + Unpin>,
+{
+    let output = block_on(actual_fut());
+    assert_eq!(output, expected);
 }
 
 #[test]
 fn collect_collects() {
-    use futures_util::future::{err, ok, try_join_all};
-
-    use util::assert_done;
-
     assert_done(|| Box::new(try_join_all(vec![ok(1), ok(2)])), Ok::<_, usize>(vec![1, 2]));
     assert_done(|| Box::new(try_join_all(vec![ok(1), err(2)])), Err(2));
     assert_done(|| Box::new(try_join_all(vec![ok(1)])), Ok::<_, usize>(vec![1]));
@@ -30,11 +25,6 @@ fn collect_collects() {
 
 #[test]
 fn try_join_all_iter_lifetime() {
-    use futures_util::future::{ok, try_join_all};
-    use std::future::Future;
-
-    use util::assert_done;
-
     // In futures-rs version 0.1, this function would fail to typecheck due to an overly
     // conservative type parameterization of `TryJoinAll`.
     fn sizes(bufs: Vec<&[u8]>) -> Box<dyn Future<Output = Result<Vec<usize>, ()>> + Unpin> {
@@ -42,15 +32,11 @@ fn try_join_all_iter_lifetime() {
         Box::new(try_join_all(iter))
     }
 
-    assert_done(|| sizes(vec![&[1,2,3], &[], &[0]]), Ok(vec![3_usize, 0, 1]));
+    assert_done(|| sizes(vec![&[1, 2, 3], &[], &[0]]), Ok(vec![3_usize, 0, 1]));
 }
 
 #[test]
 fn try_join_all_from_iter() {
-    use futures_util::future::{ok, TryJoinAll};
-
-    use util::assert_done;
-
     assert_done(
         || Box::new(vec![ok(1), ok(2)].into_iter().collect::<TryJoinAll<_>>()),
         Ok::<_, usize>(vec![1, 2]),
diff --git a/third_party/rust/futures/tests/inspect.rs b/third_party/rust/futures/tests/inspect.rs
deleted file mode 100644
index 375778b63d000da71f8db9de6485695fa47c17d7..0000000000000000000000000000000000000000
--- a/third_party/rust/futures/tests/inspect.rs
+++ /dev/null
@@ -1,14 +0,0 @@
-#[test]
-fn smoke() {
-    use futures::executor::block_on;
-    use futures::future::{self, FutureExt};
-
-    let mut counter = 0;
-
-    {
-        let work = future::ready::<i32>(40).inspect(|val| { counter += *val; });
-        assert_eq!(block_on(work), 40);
-    }
-
-    assert_eq!(counter, 40);
-}
diff --git a/third_party/rust/futures/tests/io_buf_reader.rs b/third_party/rust/futures/tests/io_buf_reader.rs
index f8f9d140e3539d4a39966c626ec15ba07f82f4e4..d60df879c21087c28b6c543d599f9c61ebf63da3 100644
--- a/third_party/rust/futures/tests/io_buf_reader.rs
+++ b/third_party/rust/futures/tests/io_buf_reader.rs
@@ -1,9 +1,17 @@
+use futures::executor::block_on;
+use futures::future::{Future, FutureExt};
+use futures::io::{
+    AllowStdIo, AsyncBufRead, AsyncBufReadExt, AsyncRead, AsyncReadExt, AsyncSeek, AsyncSeekExt,
+    BufReader, Cursor, SeekFrom,
+};
+use futures::task::{Context, Poll};
+use futures_test::task::noop_context;
+use std::cmp;
+use std::io;
+use std::pin::Pin;
+
 macro_rules! run_fill_buf {
     ($reader:expr) => {{
-        use futures_test::task::noop_context;
-        use futures::task::Poll;
-        use std::pin::Pin;
-
         let mut cx = noop_context();
         loop {
             if let Poll::Ready(x) = Pin::new(&mut $reader).poll_fill_buf(&mut cx) {
@@ -13,80 +21,65 @@ macro_rules! run_fill_buf {
     }};
 }
 
-mod util {
-    use futures::future::Future;
-    pub fn run<F: Future + Unpin>(mut f: F) -> F::Output {
-        use futures_test::task::noop_context;
-        use futures::task::Poll;
-        use futures::future::FutureExt;
-
-        let mut cx = noop_context();
-        loop {
-            if let Poll::Ready(x) = f.poll_unpin(&mut cx) {
-                return x;
-            }
+fn run<F: Future + Unpin>(mut f: F) -> F::Output {
+    let mut cx = noop_context();
+    loop {
+        if let Poll::Ready(x) = f.poll_unpin(&mut cx) {
+            return x;
         }
     }
 }
 
-mod maybe_pending {
-    use futures::task::{Context,Poll};
-    use std::{cmp,io};
-    use std::pin::Pin;
-    use futures::io::{AsyncRead,AsyncBufRead};
+struct MaybePending<'a> {
+    inner: &'a [u8],
+    ready_read: bool,
+    ready_fill_buf: bool,
+}
 
-    pub struct MaybePending<'a> {
-        inner: &'a [u8],
-        ready_read: bool,
-        ready_fill_buf: bool,
+impl<'a> MaybePending<'a> {
+    fn new(inner: &'a [u8]) -> Self {
+        Self { inner, ready_read: false, ready_fill_buf: false }
     }
+}
 
-    impl<'a> MaybePending<'a> {
-        pub fn new(inner: &'a [u8]) -> Self {
-            Self { inner, ready_read: false, ready_fill_buf: false }
+impl AsyncRead for MaybePending<'_> {
+    fn poll_read(
+        mut self: Pin<&mut Self>,
+        cx: &mut Context<'_>,
+        buf: &mut [u8],
+    ) -> Poll<io::Result<usize>> {
+        if self.ready_read {
+            self.ready_read = false;
+            Pin::new(&mut self.inner).poll_read(cx, buf)
+        } else {
+            self.ready_read = true;
+            Poll::Pending
         }
     }
+}
 
-    impl AsyncRead for MaybePending<'_> {
-        fn poll_read(mut self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &mut [u8])
-            -> Poll<io::Result<usize>>
-        {
-            if self.ready_read {
-                self.ready_read = false;
-                Pin::new(&mut self.inner).poll_read(cx, buf)
-            } else {
-                self.ready_read = true;
-                Poll::Pending
+impl AsyncBufRead for MaybePending<'_> {
+    fn poll_fill_buf(mut self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<io::Result<&[u8]>> {
+        if self.ready_fill_buf {
+            self.ready_fill_buf = false;
+            if self.inner.is_empty() {
+                return Poll::Ready(Ok(&[]));
             }
+            let len = cmp::min(2, self.inner.len());
+            Poll::Ready(Ok(&self.inner[0..len]))
+        } else {
+            self.ready_fill_buf = true;
+            Poll::Pending
         }
     }
 
-    impl AsyncBufRead for MaybePending<'_> {
-        fn poll_fill_buf(mut self: Pin<&mut Self>, _: &mut Context<'_>)
-            -> Poll<io::Result<&[u8]>>
-        {
-            if self.ready_fill_buf {
-                self.ready_fill_buf = false;
-                if self.inner.is_empty() { return Poll::Ready(Ok(&[])) }
-                let len = cmp::min(2, self.inner.len());
-                Poll::Ready(Ok(&self.inner[0..len]))
-            } else {
-                self.ready_fill_buf = true;
-                Poll::Pending
-            }
-        }
-
-        fn consume(mut self: Pin<&mut Self>, amt: usize) {
-            self.inner = &self.inner[amt..];
-        }
+    fn consume(mut self: Pin<&mut Self>, amt: usize) {
+        self.inner = &self.inner[amt..];
     }
 }
 
 #[test]
 fn test_buffered_reader() {
-    use futures::executor::block_on;
-    use futures::io::{AsyncReadExt, BufReader};
-
     let inner: &[u8] = &[5, 6, 7, 0, 1, 2, 3, 4];
     let mut reader = BufReader::with_capacity(2, inner);
 
@@ -124,11 +117,6 @@ fn test_buffered_reader() {
 
 #[test]
 fn test_buffered_reader_seek() {
-    use futures::executor::block_on;
-    use futures::io::{AsyncSeekExt, AsyncBufRead, BufReader, Cursor, SeekFrom};
-    use std::pin::Pin;
-    use util::run;
-
     let inner: &[u8] = &[5, 6, 7, 0, 1, 2, 3, 4];
     let mut reader = BufReader::with_capacity(2, Cursor::new(inner));
 
@@ -144,13 +132,9 @@ fn test_buffered_reader_seek() {
 
 #[test]
 fn test_buffered_reader_seek_underflow() {
-    use futures::executor::block_on;
-    use futures::io::{AsyncSeekExt, AsyncBufRead, AllowStdIo, BufReader, SeekFrom};
-    use std::io;
-
     // gimmick reader that yields its position modulo 256 for each byte
     struct PositionReader {
-        pos: u64
+        pos: u64,
     }
     impl io::Read for PositionReader {
         fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
@@ -181,7 +165,7 @@ fn test_buffered_reader_seek_underflow() {
 
     let mut reader = BufReader::with_capacity(5, AllowStdIo::new(PositionReader { pos: 0 }));
     assert_eq!(run_fill_buf!(reader).ok(), Some(&[0, 1, 2, 3, 4][..]));
-    assert_eq!(block_on(reader.seek(SeekFrom::End(-5))).ok(), Some(u64::max_value()-5));
+    assert_eq!(block_on(reader.seek(SeekFrom::End(-5))).ok(), Some(u64::max_value() - 5));
     assert_eq!(run_fill_buf!(reader).ok().map(|s| s.len()), Some(5));
     // the following seek will require two underlying seeks
     let expected = 9_223_372_036_854_775_802;
@@ -194,10 +178,6 @@ fn test_buffered_reader_seek_underflow() {
 
 #[test]
 fn test_short_reads() {
-    use futures::executor::block_on;
-    use futures::io::{AsyncReadExt, AllowStdIo, BufReader};
-    use std::io;
-
     /// A dummy reader intended at testing short-reads propagation.
     struct ShortReader {
         lengths: Vec<usize>,
@@ -227,10 +207,6 @@ fn test_short_reads() {
 
 #[test]
 fn maybe_pending() {
-    use futures::io::{AsyncReadExt, BufReader};
-    use util::run;
-    use maybe_pending::MaybePending;
-
     let inner: &[u8] = &[5, 6, 7, 0, 1, 2, 3, 4];
     let mut reader = BufReader::with_capacity(2, MaybePending::new(inner));
 
@@ -268,10 +244,6 @@ fn maybe_pending() {
 
 #[test]
 fn maybe_pending_buf_read() {
-    use futures::io::{AsyncBufReadExt, BufReader};
-    use util::run;
-    use maybe_pending::MaybePending;
-
     let inner = MaybePending::new(&[0, 1, 2, 3, 1, 0]);
     let mut reader = BufReader::with_capacity(2, inner);
     let mut v = Vec::new();
@@ -291,36 +263,32 @@ fn maybe_pending_buf_read() {
 // https://github.com/rust-lang/futures-rs/pull/1573#discussion_r281162309
 #[test]
 fn maybe_pending_seek() {
-    use futures::io::{AsyncBufRead, AsyncSeek, AsyncSeekExt, AsyncRead, BufReader,
-        Cursor, SeekFrom
-    };
-    use futures::task::{Context,Poll};
-    use std::io;
-    use std::pin::Pin;
-    use util::run;
-    pub struct MaybePendingSeek<'a> {
+    struct MaybePendingSeek<'a> {
         inner: Cursor<&'a [u8]>,
         ready: bool,
     }
 
     impl<'a> MaybePendingSeek<'a> {
-        pub fn new(inner: &'a [u8]) -> Self {
+        fn new(inner: &'a [u8]) -> Self {
             Self { inner: Cursor::new(inner), ready: true }
         }
     }
 
     impl AsyncRead for MaybePendingSeek<'_> {
-        fn poll_read(mut self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &mut [u8])
-            -> Poll<io::Result<usize>>
-        {
+        fn poll_read(
+            mut self: Pin<&mut Self>,
+            cx: &mut Context<'_>,
+            buf: &mut [u8],
+        ) -> Poll<io::Result<usize>> {
             Pin::new(&mut self.inner).poll_read(cx, buf)
         }
     }
 
     impl AsyncBufRead for MaybePendingSeek<'_> {
-        fn poll_fill_buf(mut self: Pin<&mut Self>, cx: &mut Context<'_>)
-            -> Poll<io::Result<&[u8]>>
-        {
+        fn poll_fill_buf(
+            mut self: Pin<&mut Self>,
+            cx: &mut Context<'_>,
+        ) -> Poll<io::Result<&[u8]>> {
             let this: *mut Self = &mut *self as *mut _;
             Pin::new(&mut unsafe { &mut *this }.inner).poll_fill_buf(cx)
         }
@@ -331,9 +299,11 @@ fn maybe_pending_seek() {
     }
 
     impl AsyncSeek for MaybePendingSeek<'_> {
-        fn poll_seek(mut self: Pin<&mut Self>, cx: &mut Context<'_>, pos: SeekFrom)
-            -> Poll<io::Result<u64>>
-        {
+        fn poll_seek(
+            mut self: Pin<&mut Self>,
+            cx: &mut Context<'_>,
+            pos: SeekFrom,
+        ) -> Poll<io::Result<u64>> {
             if self.ready {
                 self.ready = false;
                 Pin::new(&mut self.inner).poll_seek(cx, pos)
diff --git a/third_party/rust/futures/tests/io_buf_writer.rs b/third_party/rust/futures/tests/io_buf_writer.rs
index d58a6d801f61c57fc89f566a0d30c089064174bf..b264cd54c2c03fd6e57cefdd2dd0a0c353413d8e 100644
--- a/third_party/rust/futures/tests/io_buf_writer.rs
+++ b/third_party/rust/futures/tests/io_buf_writer.rs
@@ -1,67 +1,59 @@
-mod maybe_pending {
-    use futures::io::AsyncWrite;
-    use futures::task::{Context, Poll};
-    use std::io;
-    use std::pin::Pin;
-
-    pub struct MaybePending {
-        pub inner: Vec<u8>,
-        ready: bool,
-    }
+use futures::executor::block_on;
+use futures::future::{Future, FutureExt};
+use futures::io::{
+    AsyncSeek, AsyncSeekExt, AsyncWrite, AsyncWriteExt, BufWriter, Cursor, SeekFrom,
+};
+use futures::task::{Context, Poll};
+use futures_test::task::noop_context;
+use std::io;
+use std::pin::Pin;
+
+struct MaybePending {
+    inner: Vec<u8>,
+    ready: bool,
+}
 
-    impl MaybePending {
-        pub fn new(inner: Vec<u8>) -> Self {
-            Self { inner, ready: false }
-        }
+impl MaybePending {
+    fn new(inner: Vec<u8>) -> Self {
+        Self { inner, ready: false }
     }
+}
 
-    impl AsyncWrite for MaybePending {
-        fn poll_write(
-            mut self: Pin<&mut Self>,
-            cx: &mut Context<'_>,
-            buf: &[u8],
-        ) -> Poll<io::Result<usize>> {
-            if self.ready {
-                self.ready = false;
-                Pin::new(&mut self.inner).poll_write(cx, buf)
-            } else {
-                self.ready = true;
-                Poll::Pending
-            }
+impl AsyncWrite for MaybePending {
+    fn poll_write(
+        mut self: Pin<&mut Self>,
+        cx: &mut Context<'_>,
+        buf: &[u8],
+    ) -> Poll<io::Result<usize>> {
+        if self.ready {
+            self.ready = false;
+            Pin::new(&mut self.inner).poll_write(cx, buf)
+        } else {
+            self.ready = true;
+            Poll::Pending
         }
+    }
 
-        fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
-            Pin::new(&mut self.inner).poll_flush(cx)
-        }
+    fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
+        Pin::new(&mut self.inner).poll_flush(cx)
+    }
 
-        fn poll_close(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
-            Pin::new(&mut self.inner).poll_close(cx)
-        }
+    fn poll_close(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
+        Pin::new(&mut self.inner).poll_close(cx)
     }
 }
 
-mod util {
-    use futures::future::Future;
-
-    pub fn run<F: Future + Unpin>(mut f: F) -> F::Output {
-        use futures::future::FutureExt;
-        use futures::task::Poll;
-        use futures_test::task::noop_context;
-
-        let mut cx = noop_context();
-        loop {
-            if let Poll::Ready(x) = f.poll_unpin(&mut cx) {
-                return x;
-            }
+fn run<F: Future + Unpin>(mut f: F) -> F::Output {
+    let mut cx = noop_context();
+    loop {
+        if let Poll::Ready(x) = f.poll_unpin(&mut cx) {
+            return x;
         }
     }
 }
 
 #[test]
 fn buf_writer() {
-    use futures::executor::block_on;
-    use futures::io::{AsyncWriteExt, BufWriter};
-
     let mut writer = BufWriter::with_capacity(2, Vec::new());
 
     block_on(writer.write(&[0, 1])).unwrap();
@@ -104,9 +96,6 @@ fn buf_writer() {
 
 #[test]
 fn buf_writer_inner_flushes() {
-    use futures::executor::block_on;
-    use futures::io::{AsyncWriteExt, BufWriter};
-
     let mut w = BufWriter::with_capacity(3, Vec::new());
     block_on(w.write(&[0, 1])).unwrap();
     assert_eq!(*w.get_ref(), []);
@@ -117,9 +106,6 @@ fn buf_writer_inner_flushes() {
 
 #[test]
 fn buf_writer_seek() {
-    use futures::executor::block_on;
-    use futures::io::{AsyncSeekExt, AsyncWriteExt, BufWriter, Cursor, SeekFrom};
-
     // FIXME: when https://github.com/rust-lang/futures-rs/issues/1510 fixed,
     // use `Vec::new` instead of `vec![0; 8]`.
     let mut w = BufWriter::with_capacity(3, Cursor::new(vec![0; 8]));
@@ -135,11 +121,6 @@ fn buf_writer_seek() {
 
 #[test]
 fn maybe_pending_buf_writer() {
-    use futures::io::{AsyncWriteExt, BufWriter};
-
-    use maybe_pending::MaybePending;
-    use util::run;
-
     let mut writer = BufWriter::with_capacity(2, MaybePending::new(Vec::new()));
 
     run(writer.write(&[0, 1])).unwrap();
@@ -182,11 +163,6 @@ fn maybe_pending_buf_writer() {
 
 #[test]
 fn maybe_pending_buf_writer_inner_flushes() {
-    use futures::io::{AsyncWriteExt, BufWriter};
-
-    use maybe_pending::MaybePending;
-    use util::run;
-
     let mut w = BufWriter::with_capacity(3, MaybePending::new(Vec::new()));
     run(w.write(&[0, 1])).unwrap();
     assert_eq!(&w.get_ref().inner, &[]);
@@ -197,13 +173,6 @@ fn maybe_pending_buf_writer_inner_flushes() {
 
 #[test]
 fn maybe_pending_buf_writer_seek() {
-    use futures::io::{AsyncSeek, AsyncSeekExt, AsyncWrite, AsyncWriteExt, BufWriter, Cursor, SeekFrom};
-    use futures::task::{Context, Poll};
-    use std::io;
-    use std::pin::Pin;
-
-    use util::run;
-
     struct MaybePendingSeek {
         inner: Cursor<Vec<u8>>,
         ready_write: bool,
@@ -241,9 +210,11 @@ fn maybe_pending_buf_writer_seek() {
     }
 
     impl AsyncSeek for MaybePendingSeek {
-        fn poll_seek(mut self: Pin<&mut Self>, cx: &mut Context<'_>, pos: SeekFrom)
-            -> Poll<io::Result<u64>>
-        {
+        fn poll_seek(
+            mut self: Pin<&mut Self>,
+            cx: &mut Context<'_>,
+            pos: SeekFrom,
+        ) -> Poll<io::Result<u64>> {
             if self.ready_seek {
                 self.ready_seek = false;
                 Pin::new(&mut self.inner).poll_seek(cx, pos)
diff --git a/third_party/rust/futures/tests/io_cursor.rs b/third_party/rust/futures/tests/io_cursor.rs
index 4ba6342525cbf3227b0496d374b3d8b460e9bb19..435ea5a1559374f10af6b4312726863626937c7d 100644
--- a/third_party/rust/futures/tests/io_cursor.rs
+++ b/third_party/rust/futures/tests/io_cursor.rs
@@ -1,13 +1,14 @@
+use assert_matches::assert_matches;
+use futures::executor::block_on;
+use futures::future::lazy;
+use futures::io::{AsyncWrite, Cursor};
+use futures::task::Poll;
+use std::pin::Pin;
+
 #[test]
 fn cursor_asyncwrite_vec() {
-    use assert_matches::assert_matches;
-    use futures::future::lazy;
-    use futures::io::{AsyncWrite, Cursor};
-    use futures::task::Poll;
-    use std::pin::Pin;
-
     let mut cursor = Cursor::new(vec![0; 5]);
-    futures::executor::block_on(lazy(|cx| {
+    block_on(lazy(|cx| {
         assert_matches!(Pin::new(&mut cursor).poll_write(cx, &[1, 2]), Poll::Ready(Ok(2)));
         assert_matches!(Pin::new(&mut cursor).poll_write(cx, &[3, 4]), Poll::Ready(Ok(2)));
         assert_matches!(Pin::new(&mut cursor).poll_write(cx, &[5, 6]), Poll::Ready(Ok(2)));
@@ -18,14 +19,8 @@ fn cursor_asyncwrite_vec() {
 
 #[test]
 fn cursor_asyncwrite_box() {
-    use assert_matches::assert_matches;
-    use futures::future::lazy;
-    use futures::io::{AsyncWrite, Cursor};
-    use futures::task::Poll;
-    use std::pin::Pin;
-
     let mut cursor = Cursor::new(vec![0; 5].into_boxed_slice());
-    futures::executor::block_on(lazy(|cx| {
+    block_on(lazy(|cx| {
         assert_matches!(Pin::new(&mut cursor).poll_write(cx, &[1, 2]), Poll::Ready(Ok(2)));
         assert_matches!(Pin::new(&mut cursor).poll_write(cx, &[3, 4]), Poll::Ready(Ok(2)));
         assert_matches!(Pin::new(&mut cursor).poll_write(cx, &[5, 6]), Poll::Ready(Ok(1)));
diff --git a/third_party/rust/futures/tests/io_lines.rs b/third_party/rust/futures/tests/io_lines.rs
index 2552c7c40ad432dad6f889cf6c1932235dd81a75..5ce01a6945316eac057b25d4627e9efc63e623e3 100644
--- a/third_party/rust/futures/tests/io_lines.rs
+++ b/third_party/rust/futures/tests/io_lines.rs
@@ -1,32 +1,34 @@
-mod util {
-    use futures::future::Future;
-
-    pub fn run<F: Future + Unpin>(mut f: F) -> F::Output {
-        use futures_test::task::noop_context;
-        use futures::task::Poll;
-        use futures::future::FutureExt;
-
-        let mut cx = noop_context();
-        loop {
-            if let Poll::Ready(x) = f.poll_unpin(&mut cx) {
-                return x;
-            }
+use futures::executor::block_on;
+use futures::future::{Future, FutureExt};
+use futures::io::{AsyncBufReadExt, Cursor};
+use futures::stream::{self, StreamExt, TryStreamExt};
+use futures::task::Poll;
+use futures_test::io::AsyncReadTestExt;
+use futures_test::task::noop_context;
+
+fn run<F: Future + Unpin>(mut f: F) -> F::Output {
+    let mut cx = noop_context();
+    loop {
+        if let Poll::Ready(x) = f.poll_unpin(&mut cx) {
+            return x;
         }
     }
 }
 
-#[test]
-fn lines() {
-    use futures::executor::block_on;
-    use futures::stream::StreamExt;
-    use futures::io::{AsyncBufReadExt, Cursor};
+macro_rules! block_on_next {
+    ($expr:expr) => {
+        block_on($expr.next()).unwrap().unwrap()
+    };
+}
 
-    macro_rules! block_on_next {
-        ($expr:expr) => {
-            block_on($expr.next()).unwrap().unwrap()
-        };
-    }
+macro_rules! run_next {
+    ($expr:expr) => {
+        run($expr.next()).unwrap().unwrap()
+    };
+}
 
+#[test]
+fn lines() {
     let buf = Cursor::new(&b"12\r"[..]);
     let mut s = buf.lines();
     assert_eq!(block_on_next!(s), "12\r".to_string());
@@ -41,22 +43,8 @@ fn lines() {
 
 #[test]
 fn maybe_pending() {
-    use futures::stream::{self, StreamExt, TryStreamExt};
-    use futures::io::AsyncBufReadExt;
-    use futures_test::io::AsyncReadTestExt;
-
-    use util::run;
-
-    macro_rules! run_next {
-        ($expr:expr) => {
-            run($expr.next()).unwrap().unwrap()
-        };
-    }
-
-    let buf = stream::iter(vec![&b"12"[..], &b"\r"[..]])
-        .map(Ok)
-        .into_async_read()
-        .interleave_pending();
+    let buf =
+        stream::iter(vec![&b"12"[..], &b"\r"[..]]).map(Ok).into_async_read().interleave_pending();
     let mut s = buf.lines();
     assert_eq!(run_next!(s), "12\r".to_string());
     assert!(run(s.next()).is_none());
diff --git a/third_party/rust/futures/tests/io_read.rs b/third_party/rust/futures/tests/io_read.rs
index 5902ad0ed9d779421feacd7bba439d1c168ac58d..d39a6ea7903f054447566ebd04b53b8963e90dbc 100644
--- a/third_party/rust/futures/tests/io_read.rs
+++ b/third_party/rust/futures/tests/io_read.rs
@@ -1,27 +1,26 @@
-mod mock_reader {
-    use futures::io::AsyncRead;
-    use std::io;
-    use std::pin::Pin;
-    use std::task::{Context, Poll};
+use futures::io::AsyncRead;
+use futures_test::task::panic_context;
+use std::io;
+use std::pin::Pin;
+use std::task::{Context, Poll};
 
-    pub struct MockReader {
-        fun: Box<dyn FnMut(&mut [u8]) -> Poll<io::Result<usize>>>,
-    }
+struct MockReader {
+    fun: Box<dyn FnMut(&mut [u8]) -> Poll<io::Result<usize>>>,
+}
 
-    impl MockReader {
-        pub fn new(fun: impl FnMut(&mut [u8]) -> Poll<io::Result<usize>> + 'static) -> Self {
-            Self { fun: Box::new(fun) }
-        }
+impl MockReader {
+    fn new(fun: impl FnMut(&mut [u8]) -> Poll<io::Result<usize>> + 'static) -> Self {
+        Self { fun: Box::new(fun) }
     }
+}
 
-    impl AsyncRead for MockReader {
-        fn poll_read(
-            self: Pin<&mut Self>,
-            _cx: &mut Context<'_>,
-            buf: &mut [u8]
-        ) -> Poll<io::Result<usize>> {
-            (self.get_mut().fun)(buf)
-        }
+impl AsyncRead for MockReader {
+    fn poll_read(
+        self: Pin<&mut Self>,
+        _cx: &mut Context<'_>,
+        buf: &mut [u8],
+    ) -> Poll<io::Result<usize>> {
+        (self.get_mut().fun)(buf)
     }
 }
 
@@ -29,14 +28,6 @@ mod mock_reader {
 /// calls `poll_read` with an empty slice if no buffers are provided.
 #[test]
 fn read_vectored_no_buffers() {
-    use futures::io::AsyncRead;
-    use futures_test::task::panic_context;
-    use std::io;
-    use std::pin::Pin;
-    use std::task::Poll;
-
-    use mock_reader::MockReader;
-
     let mut reader = MockReader::new(|buf| {
         assert_eq!(buf, b"");
         Err(io::ErrorKind::BrokenPipe.into()).into()
@@ -53,14 +44,6 @@ fn read_vectored_no_buffers() {
 /// calls `poll_read` with the first non-empty buffer.
 #[test]
 fn read_vectored_first_non_empty() {
-    use futures::io::AsyncRead;
-    use futures_test::task::panic_context;
-    use std::io;
-    use std::pin::Pin;
-    use std::task::Poll;
-
-    use mock_reader::MockReader;
-
     let mut reader = MockReader::new(|buf| {
         assert_eq!(buf.len(), 4);
         buf.copy_from_slice(b"four");
diff --git a/third_party/rust/futures/tests/io_read_exact.rs b/third_party/rust/futures/tests/io_read_exact.rs
index bd4b36deaf1c3ca0da4d13cf468379c8c800ef39..6582e50b80aaf4e3c750592272eaac6be93cf1fd 100644
--- a/third_party/rust/futures/tests/io_read_exact.rs
+++ b/third_party/rust/futures/tests/io_read_exact.rs
@@ -1,14 +1,14 @@
+use futures::executor::block_on;
+use futures::io::AsyncReadExt;
+
 #[test]
 fn read_exact() {
-    use futures::executor::block_on;
-    use futures::io::AsyncReadExt;
-
     let mut reader: &[u8] = &[1, 2, 3, 4, 5];
     let mut out = [0u8; 3];
 
     let res = block_on(reader.read_exact(&mut out)); // read 3 bytes out
     assert!(res.is_ok());
-    assert_eq!(out, [1,2,3]);
+    assert_eq!(out, [1, 2, 3]);
     assert_eq!(reader.len(), 2);
 
     let res = block_on(reader.read_exact(&mut out)); // read another 3 bytes, but only 2 bytes left
diff --git a/third_party/rust/futures/tests/io_read_line.rs b/third_party/rust/futures/tests/io_read_line.rs
index 51e8126ada074de1e69691b1f3d03cfb6f9bf729..88a877928a68390b722af0e36f5878756b7a03d8 100644
--- a/third_party/rust/futures/tests/io_read_line.rs
+++ b/third_party/rust/futures/tests/io_read_line.rs
@@ -1,8 +1,22 @@
+use futures::executor::block_on;
+use futures::future::{Future, FutureExt};
+use futures::io::{AsyncBufReadExt, Cursor};
+use futures::stream::{self, StreamExt, TryStreamExt};
+use futures::task::Poll;
+use futures_test::io::AsyncReadTestExt;
+use futures_test::task::noop_context;
+
+fn run<F: Future + Unpin>(mut f: F) -> F::Output {
+    let mut cx = noop_context();
+    loop {
+        if let Poll::Ready(x) = f.poll_unpin(&mut cx) {
+            return x;
+        }
+    }
+}
+
 #[test]
 fn read_line() {
-    use futures::executor::block_on;
-    use futures::io::{AsyncBufReadExt, Cursor};
-
     let mut buf = Cursor::new(b"12");
     let mut v = String::new();
     assert_eq!(block_on(buf.read_line(&mut v)).unwrap(), 2);
@@ -22,34 +36,13 @@ fn read_line() {
 
 #[test]
 fn maybe_pending() {
-    use futures::future::Future;
-
-    fn run<F: Future + Unpin>(mut f: F) -> F::Output {
-        use futures::future::FutureExt;
-        use futures::task::Poll;
-        use futures_test::task::noop_context;
-
-        let mut cx = noop_context();
-        loop {
-            if let Poll::Ready(x) = f.poll_unpin(&mut cx) {
-                return x;
-            }
-        }
-    }
-
-    use futures::stream::{self, StreamExt, TryStreamExt};
-    use futures::io::AsyncBufReadExt;
-    use futures_test::io::AsyncReadTestExt;
-
     let mut buf = b"12".interleave_pending();
     let mut v = String::new();
     assert_eq!(run(buf.read_line(&mut v)).unwrap(), 2);
     assert_eq!(v, "12");
 
-    let mut buf = stream::iter(vec![&b"12"[..], &b"\n\n"[..]])
-        .map(Ok)
-        .into_async_read()
-        .interleave_pending();
+    let mut buf =
+        stream::iter(vec![&b"12"[..], &b"\n\n"[..]]).map(Ok).into_async_read().interleave_pending();
     let mut v = String::new();
     assert_eq!(run(buf.read_line(&mut v)).unwrap(), 3);
     assert_eq!(v, "12\n");
diff --git a/third_party/rust/futures/tests/io_read_to_end.rs b/third_party/rust/futures/tests/io_read_to_end.rs
index 892d463c2dd1bc7a25f609088762d3f4b77fdcf6..7122511fcb2cddfafb8ce95f9a8a9c325609d029 100644
--- a/third_party/rust/futures/tests/io_read_to_end.rs
+++ b/third_party/rust/futures/tests/io_read_to_end.rs
@@ -1,4 +1,5 @@
 use futures::{
+    executor::block_on,
     io::{self, AsyncRead, AsyncReadExt},
     task::{Context, Poll},
 };
@@ -12,7 +13,7 @@ fn issue2310() {
     }
 
     impl MyRead {
-        pub fn new() -> Self {
+        fn new() -> Self {
             MyRead { first: false }
         }
     }
@@ -39,7 +40,7 @@ fn issue2310() {
     }
 
     impl VecWrapper {
-        pub fn new() -> Self {
+        fn new() -> Self {
             VecWrapper { inner: Vec::new() }
         }
     }
@@ -55,7 +56,7 @@ fn issue2310() {
         }
     }
 
-    futures::executor::block_on(async {
+    block_on(async {
         let mut vec = VecWrapper::new();
         let mut read = MyRead::new();
 
diff --git a/third_party/rust/futures/tests/io_read_to_string.rs b/third_party/rust/futures/tests/io_read_to_string.rs
index 2e9c00a138e17e5d06ac2c08f493eaa47023e5ee..ae6aaa21d8281bfe6acd387818de6c612fd89c49 100644
--- a/third_party/rust/futures/tests/io_read_to_string.rs
+++ b/third_party/rust/futures/tests/io_read_to_string.rs
@@ -1,8 +1,13 @@
+use futures::executor::block_on;
+use futures::future::{Future, FutureExt};
+use futures::io::{AsyncReadExt, Cursor};
+use futures::stream::{self, StreamExt, TryStreamExt};
+use futures::task::Poll;
+use futures_test::io::AsyncReadTestExt;
+use futures_test::task::noop_context;
+
 #[test]
 fn read_to_string() {
-    use futures::executor::block_on;
-    use futures::io::{AsyncReadExt, Cursor};
-
     let mut c = Cursor::new(&b""[..]);
     let mut v = String::new();
     assert_eq!(block_on(c.read_to_string(&mut v)).unwrap(), 0);
@@ -20,16 +25,7 @@ fn read_to_string() {
 
 #[test]
 fn interleave_pending() {
-    use futures::future::Future;
-    use futures::stream::{self, StreamExt, TryStreamExt};
-    use futures::io::AsyncReadExt;
-    use futures_test::io::AsyncReadTestExt;
-
     fn run<F: Future + Unpin>(mut f: F) -> F::Output {
-        use futures::future::FutureExt;
-        use futures_test::task::noop_context;
-        use futures::task::Poll;
-
         let mut cx = noop_context();
         loop {
             if let Poll::Ready(x) = f.poll_unpin(&mut cx) {
diff --git a/third_party/rust/futures/tests/io_read_until.rs b/third_party/rust/futures/tests/io_read_until.rs
index 6fa22eee656b8833493edb2e82b19bb4a4d3294a..71f857f4b0018ad8617bf3e9c4d5244c890f8ea4 100644
--- a/third_party/rust/futures/tests/io_read_until.rs
+++ b/third_party/rust/futures/tests/io_read_until.rs
@@ -1,8 +1,22 @@
+use futures::executor::block_on;
+use futures::future::{Future, FutureExt};
+use futures::io::{AsyncBufReadExt, Cursor};
+use futures::stream::{self, StreamExt, TryStreamExt};
+use futures::task::Poll;
+use futures_test::io::AsyncReadTestExt;
+use futures_test::task::noop_context;
+
+fn run<F: Future + Unpin>(mut f: F) -> F::Output {
+    let mut cx = noop_context();
+    loop {
+        if let Poll::Ready(x) = f.poll_unpin(&mut cx) {
+            return x;
+        }
+    }
+}
+
 #[test]
 fn read_until() {
-    use futures::executor::block_on;
-    use futures::io::{AsyncBufReadExt, Cursor};
-
     let mut buf = Cursor::new(b"12");
     let mut v = Vec::new();
     assert_eq!(block_on(buf.read_until(b'3', &mut v)).unwrap(), 2);
@@ -22,25 +36,6 @@ fn read_until() {
 
 #[test]
 fn maybe_pending() {
-    use futures::future::Future;
-
-    fn run<F: Future + Unpin>(mut f: F) -> F::Output {
-        use futures::future::FutureExt;
-        use futures_test::task::noop_context;
-        use futures::task::Poll;
-
-        let mut cx = noop_context();
-        loop {
-            if let Poll::Ready(x) = f.poll_unpin(&mut cx) {
-                return x;
-            }
-        }
-    }
-
-    use futures::stream::{self, StreamExt, TryStreamExt};
-    use futures::io::AsyncBufReadExt;
-    use futures_test::io::AsyncReadTestExt;
-
     let mut buf = b"12".interleave_pending();
     let mut v = Vec::new();
     assert_eq!(run(buf.read_until(b'3', &mut v)).unwrap(), 2);
diff --git a/third_party/rust/futures/tests/io_write.rs b/third_party/rust/futures/tests/io_write.rs
index 363f32b1a60e79409654fb41bc89b19812af37e2..6af27553cb7f1313c4e04bfd8f363bfb16443b75 100644
--- a/third_party/rust/futures/tests/io_write.rs
+++ b/third_party/rust/futures/tests/io_write.rs
@@ -1,35 +1,34 @@
-mod mock_writer {
-    use futures::io::AsyncWrite;
-    use std::io;
-    use std::pin::Pin;
-    use std::task::{Context, Poll};
+use futures::io::AsyncWrite;
+use futures_test::task::panic_context;
+use std::io;
+use std::pin::Pin;
+use std::task::{Context, Poll};
 
-    pub struct MockWriter {
-        fun: Box<dyn FnMut(&[u8]) -> Poll<io::Result<usize>>>,
-    }
+struct MockWriter {
+    fun: Box<dyn FnMut(&[u8]) -> Poll<io::Result<usize>>>,
+}
 
-    impl MockWriter {
-        pub fn new(fun: impl FnMut(&[u8]) -> Poll<io::Result<usize>> + 'static) -> Self {
-            Self { fun: Box::new(fun) }
-        }
+impl MockWriter {
+    fn new(fun: impl FnMut(&[u8]) -> Poll<io::Result<usize>> + 'static) -> Self {
+        Self { fun: Box::new(fun) }
     }
+}
 
-    impl AsyncWrite for MockWriter {
-        fn poll_write(
-            self: Pin<&mut Self>,
-            _cx: &mut Context<'_>,
-            buf: &[u8],
-        ) -> Poll<io::Result<usize>> {
-            (self.get_mut().fun)(buf)
-        }
+impl AsyncWrite for MockWriter {
+    fn poll_write(
+        self: Pin<&mut Self>,
+        _cx: &mut Context<'_>,
+        buf: &[u8],
+    ) -> Poll<io::Result<usize>> {
+        (self.get_mut().fun)(buf)
+    }
 
-        fn poll_flush(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<io::Result<()>> {
-            panic!()
-        }
+    fn poll_flush(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<io::Result<()>> {
+        panic!()
+    }
 
-        fn poll_close(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<io::Result<()>> {
-            panic!()
-        }
+    fn poll_close(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<io::Result<()>> {
+        panic!()
     }
 }
 
@@ -37,14 +36,6 @@ mod mock_writer {
 /// calls `poll_write` with an empty slice if no buffers are provided.
 #[test]
 fn write_vectored_no_buffers() {
-    use futures::io::AsyncWrite;
-    use futures_test::task::panic_context;
-    use std::io;
-    use std::pin::Pin;
-    use std::task::Poll;
-
-    use mock_writer::MockWriter;
-
     let mut writer = MockWriter::new(|buf| {
         assert_eq!(buf, b"");
         Err(io::ErrorKind::BrokenPipe.into()).into()
@@ -61,24 +52,12 @@ fn write_vectored_no_buffers() {
 /// calls `poll_write` with the first non-empty buffer.
 #[test]
 fn write_vectored_first_non_empty() {
-    use futures::io::AsyncWrite;
-    use futures_test::task::panic_context;
-    use std::io;
-    use std::pin::Pin;
-    use std::task::Poll;
-
-    use mock_writer::MockWriter;
-
     let mut writer = MockWriter::new(|buf| {
         assert_eq!(buf, b"four");
         Poll::Ready(Ok(4))
     });
     let cx = &mut panic_context();
-    let bufs = &mut [
-        io::IoSlice::new(&[]),
-        io::IoSlice::new(&[]),
-        io::IoSlice::new(b"four")
-    ];
+    let bufs = &mut [io::IoSlice::new(&[]), io::IoSlice::new(&[]), io::IoSlice::new(b"four")];
 
     let res = Pin::new(&mut writer).poll_write_vectored(cx, bufs);
     let res = res.map_err(|e| e.kind());
diff --git a/third_party/rust/futures/tests/join_all.rs b/third_party/rust/futures/tests/join_all.rs
deleted file mode 100644
index c322e58a13882b7b1207b1d2586dce5922de4453..0000000000000000000000000000000000000000
--- a/third_party/rust/futures/tests/join_all.rs
+++ /dev/null
@@ -1,51 +0,0 @@
-mod util {
-    use std::future::Future;
-    use std::fmt::Debug;
-
-    pub fn assert_done<T, F>(actual_fut: F, expected: T)
-    where
-        T: PartialEq + Debug,
-        F: FnOnce() -> Box<dyn Future<Output = T> + Unpin>,
-    {
-        use futures::executor::block_on;
-
-        let output = block_on(actual_fut());
-        assert_eq!(output, expected);
-    }
-}
-
-#[test]
-fn collect_collects() {
-    use futures_util::future::{join_all,ready};
-
-    util::assert_done(|| Box::new(join_all(vec![ready(1), ready(2)])), vec![1, 2]);
-    util::assert_done(|| Box::new(join_all(vec![ready(1)])), vec![1]);
-    // REVIEW: should this be implemented?
-    // assert_done(|| Box::new(join_all(Vec::<i32>::new())), vec![]);
-
-    // TODO: needs more tests
-}
-
-#[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(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))
-    }
-
-    util::assert_done(|| sizes(vec![&[1,2,3], &[], &[0]]), vec![3_usize, 0, 1]);
-}
-
-#[test]
-fn join_all_from_iter() {
-    use futures_util::future::{JoinAll,ready};
-
-    util::assert_done(
-        || Box::new(vec![ready(1), ready(2)].into_iter().collect::<JoinAll<_>>()),
-        vec![1, 2],
-    )
-}
diff --git a/third_party/rust/futures/tests/mutex.rs b/third_party/rust/futures/tests/lock_mutex.rs
similarity index 67%
rename from third_party/rust/futures/tests/mutex.rs
rename to third_party/rust/futures/tests/lock_mutex.rs
index 68e030142672e1d990bf00d172b1278c5268d786..7c33864c7691d3e74f7028afd2b59e2987f31388 100644
--- a/third_party/rust/futures/tests/mutex.rs
+++ b/third_party/rust/futures/tests/lock_mutex.rs
@@ -1,9 +1,15 @@
+use futures::channel::mpsc;
+use futures::executor::{block_on, ThreadPool};
+use futures::future::{ready, FutureExt};
+use futures::lock::Mutex;
+use futures::stream::StreamExt;
+use futures::task::{Context, SpawnExt};
+use futures_test::future::FutureTestExt;
+use futures_test::task::{new_count_waker, panic_context};
+use std::sync::Arc;
+
 #[test]
 fn mutex_acquire_uncontested() {
-    use futures::future::FutureExt;
-    use futures::lock::Mutex;
-    use futures_test::task::panic_context;
-
     let mutex = Mutex::new(());
     for _ in 0..10 {
         assert!(mutex.lock().poll_unpin(&mut panic_context()).is_ready());
@@ -12,11 +18,6 @@ fn mutex_acquire_uncontested() {
 
 #[test]
 fn mutex_wakes_waiters() {
-    use futures::future::FutureExt;
-    use futures::lock::Mutex;
-    use futures::task::Context;
-    use futures_test::task::{new_count_waker, panic_context};
-
     let mutex = Mutex::new(());
     let (waker, counter) = new_count_waker();
     let lock = mutex.lock().poll_unpin(&mut panic_context());
@@ -35,20 +36,8 @@ fn mutex_wakes_waiters() {
 
 #[test]
 fn mutex_contested() {
-    use futures::channel::mpsc;
-    use futures::executor::block_on;
-    use futures::future::ready;
-    use futures::lock::Mutex;
-    use futures::stream::StreamExt;
-    use futures::task::SpawnExt;
-    use futures_test::future::FutureTestExt;
-    use std::sync::Arc;
-
     let (tx, mut rx) = mpsc::unbounded();
-    let pool = futures::executor::ThreadPool::builder()
-        .pool_size(16)
-        .create()
-        .unwrap();
+    let pool = ThreadPool::builder().pool_size(16).create().unwrap();
 
     let tx = Arc::new(tx);
     let mutex = Arc::new(Mutex::new(0));
diff --git a/third_party/rust/futures/tests/macro_comma_support.rs b/third_party/rust/futures/tests/macro_comma_support.rs
index ca131639dd090877e022d829b00822d79fa9a819..85871e98be8befea010f49b2a618112acaca6327 100644
--- a/third_party/rust/futures/tests/macro_comma_support.rs
+++ b/third_party/rust/futures/tests/macro_comma_support.rs
@@ -1,12 +1,13 @@
+use futures::{
+    executor::block_on,
+    future::{self, FutureExt},
+    join, ready,
+    task::Poll,
+    try_join,
+};
+
 #[test]
 fn ready() {
-    use futures::{
-        executor::block_on,
-        future,
-        task::Poll,
-        ready,
-    };
-
     block_on(future::poll_fn(|_| {
         ready!(Poll::Ready(()),);
         Poll::Ready(())
@@ -15,11 +16,7 @@ fn ready() {
 
 #[test]
 fn poll() {
-    use futures::{
-        executor::block_on,
-        future::FutureExt,
-        poll,
-    };
+    use futures::poll;
 
     block_on(async {
         let _ = poll!(async {}.boxed(),);
@@ -28,11 +25,6 @@ fn poll() {
 
 #[test]
 fn join() {
-    use futures::{
-        executor::block_on,
-        join
-    };
-
     block_on(async {
         let future1 = async { 1 };
         let future2 = async { 2 };
@@ -42,12 +34,6 @@ fn join() {
 
 #[test]
 fn try_join() {
-    use futures::{
-        executor::block_on,
-        future::FutureExt,
-        try_join,
-    };
-
     block_on(async {
         let future1 = async { 1 }.never_error();
         let future2 = async { 2 }.never_error();
diff --git a/third_party/rust/futures/tests/oneshot.rs b/third_party/rust/futures/tests/oneshot.rs
index 2494306faddab04de2fd3c3802d7d8d4589673a3..34b78a33fbbc272c9e183fccbe91e3a24fe07b03 100644
--- a/third_party/rust/futures/tests/oneshot.rs
+++ b/third_party/rust/futures/tests/oneshot.rs
@@ -1,11 +1,11 @@
+use futures::channel::oneshot;
+use futures::future::{FutureExt, TryFutureExt};
+use futures_test::future::FutureTestExt;
+use std::sync::mpsc;
+use std::thread;
+
 #[test]
 fn oneshot_send1() {
-    use futures::channel::oneshot;
-    use futures::future::TryFutureExt;
-    use futures_test::future::FutureTestExt;
-    use std::sync::mpsc;
-    use std::thread;
-
     let (tx1, rx1) = oneshot::channel::<i32>();
     let (tx2, rx2) = mpsc::channel();
 
@@ -17,12 +17,6 @@ fn oneshot_send1() {
 
 #[test]
 fn oneshot_send2() {
-    use futures::channel::oneshot;
-    use futures::future::TryFutureExt;
-    use futures_test::future::FutureTestExt;
-    use std::sync::mpsc;
-    use std::thread;
-
     let (tx1, rx1) = oneshot::channel::<i32>();
     let (tx2, rx2) = mpsc::channel();
 
@@ -33,12 +27,6 @@ fn oneshot_send2() {
 
 #[test]
 fn oneshot_send3() {
-    use futures::channel::oneshot;
-    use futures::future::TryFutureExt;
-    use futures_test::future::FutureTestExt;
-    use std::sync::mpsc;
-    use std::thread;
-
     let (tx1, rx1) = oneshot::channel::<i32>();
     let (tx2, rx2) = mpsc::channel();
 
@@ -49,11 +37,6 @@ fn oneshot_send3() {
 
 #[test]
 fn oneshot_drop_tx1() {
-    use futures::channel::oneshot;
-    use futures::future::FutureExt;
-    use futures_test::future::FutureTestExt;
-    use std::sync::mpsc;
-
     let (tx1, rx1) = oneshot::channel::<i32>();
     let (tx2, rx2) = mpsc::channel();
 
@@ -65,12 +48,6 @@ fn oneshot_drop_tx1() {
 
 #[test]
 fn oneshot_drop_tx2() {
-    use futures::channel::oneshot;
-    use futures::future::FutureExt;
-    use futures_test::future::FutureTestExt;
-    use std::sync::mpsc;
-    use std::thread;
-
     let (tx1, rx1) = oneshot::channel::<i32>();
     let (tx2, rx2) = mpsc::channel();
 
@@ -83,9 +60,19 @@ fn oneshot_drop_tx2() {
 
 #[test]
 fn oneshot_drop_rx() {
-    use futures::channel::oneshot;
-
     let (tx, rx) = oneshot::channel::<i32>();
     drop(rx);
     assert_eq!(Err(2), tx.send(2));
 }
+
+#[test]
+fn oneshot_debug() {
+    let (tx, rx) = oneshot::channel::<i32>();
+    assert_eq!(format!("{:?}", tx), "Sender { complete: false }");
+    assert_eq!(format!("{:?}", rx), "Receiver { complete: false }");
+    drop(rx);
+    assert_eq!(format!("{:?}", tx), "Sender { complete: true }");
+    let (tx, rx) = oneshot::channel::<i32>();
+    drop(tx);
+    assert_eq!(format!("{:?}", rx), "Receiver { complete: true }");
+}
diff --git a/third_party/rust/futures/tests/ready_queue.rs b/third_party/rust/futures/tests/ready_queue.rs
index 9aa36362d0bec44cda75836b01e205d644879c8c..82901327fb38c75c125233cb92406aa4c4ea68e4 100644
--- a/third_party/rust/futures/tests/ready_queue.rs
+++ b/third_party/rust/futures/tests/ready_queue.rs
@@ -1,18 +1,15 @@
-mod assert_send_sync {
-    use futures::stream::FuturesUnordered;
-
-    pub trait AssertSendSync: Send + Sync {}
-    impl AssertSendSync for FuturesUnordered<()> {}
-}
+use futures::channel::oneshot;
+use futures::executor::{block_on, block_on_stream};
+use futures::future;
+use futures::stream::{FuturesUnordered, StreamExt};
+use futures::task::Poll;
+use futures_test::task::noop_context;
+use std::panic::{self, AssertUnwindSafe};
+use std::sync::{Arc, Barrier};
+use std::thread;
 
 #[test]
 fn basic_usage() {
-    use futures::channel::oneshot;
-    use futures::executor::block_on;
-    use futures::future;
-    use futures::stream::{FuturesUnordered, StreamExt};
-    use futures::task::Poll;
-
     block_on(future::lazy(move |cx| {
         let mut queue = FuturesUnordered::new();
         let (tx1, rx1) = oneshot::channel();
@@ -41,12 +38,6 @@ fn basic_usage() {
 
 #[test]
 fn resolving_errors() {
-    use futures::channel::oneshot;
-    use futures::executor::block_on;
-    use futures::future;
-    use futures::stream::{FuturesUnordered, StreamExt};
-    use futures::task::Poll;
-
     block_on(future::lazy(move |cx| {
         let mut queue = FuturesUnordered::new();
         let (tx1, rx1) = oneshot::channel();
@@ -75,12 +66,6 @@ fn resolving_errors() {
 
 #[test]
 fn dropping_ready_queue() {
-    use futures::channel::oneshot;
-    use futures::executor::block_on;
-    use futures::future;
-    use futures::stream::FuturesUnordered;
-    use futures_test::task::noop_context;
-
     block_on(future::lazy(move |_| {
         let queue = FuturesUnordered::new();
         let (mut tx1, rx1) = oneshot::channel::<()>();
@@ -108,12 +93,6 @@ fn dropping_ready_queue() {
 
 #[test]
 fn stress() {
-    use futures::channel::oneshot;
-    use futures::executor::block_on_stream;
-    use futures::stream::FuturesUnordered;
-    use std::sync::{Arc, Barrier};
-    use std::thread;
-
     const ITER: usize = 300;
 
     for i in 0..ITER {
@@ -157,12 +136,6 @@ fn stress() {
 
 #[test]
 fn panicking_future_dropped() {
-    use futures::executor::block_on;
-    use futures::future;
-    use futures::stream::{FuturesUnordered, StreamExt};
-    use futures::task::Poll;
-    use std::panic::{self, AssertUnwindSafe};
-
     block_on(future::lazy(move |cx| {
         let mut queue = FuturesUnordered::new();
         queue.push(future::poll_fn(|_| -> Poll<Result<i32, i32>> { panic!() }));
diff --git a/third_party/rust/futures/tests/recurse.rs b/third_party/rust/futures/tests/recurse.rs
index a151f1b1d425006437c2ec2962626b65c442c2c4..d81753c9d7083cb4ab7c56de35caea4b2edc96a1 100644
--- a/third_party/rust/futures/tests/recurse.rs
+++ b/third_party/rust/futures/tests/recurse.rs
@@ -1,10 +1,10 @@
+use futures::executor::block_on;
+use futures::future::{self, BoxFuture, FutureExt};
+use std::sync::mpsc;
+use std::thread;
+
 #[test]
 fn lots() {
-    use futures::executor::block_on;
-    use futures::future::{self, FutureExt, BoxFuture};
-    use std::sync::mpsc;
-    use std::thread;
-
     #[cfg(not(futures_sanitizer))]
     const N: i32 = 1_000;
     #[cfg(futures_sanitizer)] // If N is many, asan reports stack-overflow: https://gist.github.com/taiki-e/099446d21cbec69d4acbacf7a9646136
@@ -20,8 +20,6 @@ fn lots() {
     }
 
     let (tx, rx) = mpsc::channel();
-    thread::spawn(|| {
-        block_on(do_it((N, 0)).map(move |x| tx.send(x).unwrap()))
-    });
+    thread::spawn(|| block_on(do_it((N, 0)).map(move |x| tx.send(x).unwrap())));
     assert_eq!((0..=N).sum::<i32>(), rx.recv().unwrap());
 }
diff --git a/third_party/rust/futures/tests/sink.rs b/third_party/rust/futures/tests/sink.rs
index 597ed34c7a92809f747eefc87d5c525086cefc8f..f3cf11b931d904d692d00e2699cd1ca35e0fcff7 100644
--- a/third_party/rust/futures/tests/sink.rs
+++ b/third_party/rust/futures/tests/sink.rs
@@ -1,264 +1,221 @@
-mod sassert_next {
-    use futures::stream::{Stream, StreamExt};
-    use futures::task::Poll;
-    use futures_test::task::panic_context;
-    use std::fmt;
-
-    pub fn sassert_next<S>(s: &mut S, item: S::Item)
-    where
-        S: Stream + Unpin,
-        S::Item: Eq + fmt::Debug,
-    {
-        match s.poll_next_unpin(&mut panic_context()) {
-            Poll::Ready(None) => panic!("stream is at its end"),
-            Poll::Ready(Some(e)) => assert_eq!(e, item),
-            Poll::Pending => panic!("stream wasn't ready"),
-        }
+use futures::channel::{mpsc, oneshot};
+use futures::executor::block_on;
+use futures::future::{self, poll_fn, Future, FutureExt, TryFutureExt};
+use futures::never::Never;
+use futures::ready;
+use futures::sink::{self, Sink, SinkErrInto, SinkExt};
+use futures::stream::{self, Stream, StreamExt};
+use futures::task::{self, ArcWake, Context, Poll, Waker};
+use futures_test::task::panic_context;
+use std::cell::{Cell, RefCell};
+use std::collections::VecDeque;
+use std::fmt;
+use std::mem;
+use std::pin::Pin;
+use std::rc::Rc;
+use std::sync::atomic::{AtomicBool, Ordering};
+use std::sync::Arc;
+
+fn sassert_next<S>(s: &mut S, item: S::Item)
+where
+    S: Stream + Unpin,
+    S::Item: Eq + fmt::Debug,
+{
+    match s.poll_next_unpin(&mut panic_context()) {
+        Poll::Ready(None) => panic!("stream is at its end"),
+        Poll::Ready(Some(e)) => assert_eq!(e, item),
+        Poll::Pending => panic!("stream wasn't ready"),
     }
 }
 
-mod unwrap {
-    use futures::task::Poll;
-    use std::fmt;
-
-    pub fn unwrap<T, E: fmt::Debug>(x: Poll<Result<T, E>>) -> T {
-        match x {
-            Poll::Ready(Ok(x)) => x,
-            Poll::Ready(Err(_)) => panic!("Poll::Ready(Err(_))"),
-            Poll::Pending => panic!("Poll::Pending"),
-        }
+fn unwrap<T, E: fmt::Debug>(x: Poll<Result<T, E>>) -> T {
+    match x {
+        Poll::Ready(Ok(x)) => x,
+        Poll::Ready(Err(_)) => panic!("Poll::Ready(Err(_))"),
+        Poll::Pending => panic!("Poll::Pending"),
     }
 }
 
-mod flag_cx {
-    use futures::task::{self, ArcWake, Context};
-    use std::sync::Arc;
-    use std::sync::atomic::{AtomicBool, Ordering};
-
-    // An Unpark struct that records unpark events for inspection
-    pub struct Flag(AtomicBool);
+// An Unpark struct that records unpark events for inspection
+struct Flag(AtomicBool);
 
-    impl Flag {
-        pub fn new() -> Arc<Self> {
-            Arc::new(Self(AtomicBool::new(false)))
-        }
-
-        pub fn take(&self) -> bool {
-            self.0.swap(false, Ordering::SeqCst)
-        }
+impl Flag {
+    fn new() -> Arc<Self> {
+        Arc::new(Self(AtomicBool::new(false)))
+    }
 
-        pub fn set(&self, v: bool) {
-            self.0.store(v, Ordering::SeqCst)
-        }
+    fn take(&self) -> bool {
+        self.0.swap(false, Ordering::SeqCst)
     }
 
-    impl ArcWake for Flag {
-        fn wake_by_ref(arc_self: &Arc<Self>) {
-            arc_self.set(true)
-        }
+    fn set(&self, v: bool) {
+        self.0.store(v, Ordering::SeqCst)
     }
+}
 
-    pub fn flag_cx<F, R>(f: F) -> R
-    where
-        F: FnOnce(Arc<Flag>, &mut Context<'_>) -> R,
-    {
-        let flag = Flag::new();
-        let waker = task::waker_ref(&flag);
-        let cx = &mut Context::from_waker(&waker);
-        f(flag.clone(), cx)
+impl ArcWake for Flag {
+    fn wake_by_ref(arc_self: &Arc<Self>) {
+        arc_self.set(true)
     }
 }
 
-mod start_send_fut {
-    use futures::future::Future;
-    use futures::ready;
-    use futures::sink::Sink;
-    use futures::task::{Context, Poll};
-    use std::pin::Pin;
+fn flag_cx<F, R>(f: F) -> R
+where
+    F: FnOnce(Arc<Flag>, &mut Context<'_>) -> R,
+{
+    let flag = Flag::new();
+    let waker = task::waker_ref(&flag);
+    let cx = &mut Context::from_waker(&waker);
+    f(flag.clone(), cx)
+}
 
-    // Sends a value on an i32 channel sink
-    pub struct StartSendFut<S: Sink<Item> + Unpin, Item: Unpin>(Option<S>, Option<Item>);
+// Sends a value on an i32 channel sink
+struct StartSendFut<S: Sink<Item> + Unpin, Item: Unpin>(Option<S>, Option<Item>);
 
-    impl<S: Sink<Item> + Unpin, Item: Unpin> StartSendFut<S, Item> {
-        pub fn new(sink: S, item: Item) -> Self {
-            Self(Some(sink), Some(item))
-        }
+impl<S: Sink<Item> + Unpin, Item: Unpin> StartSendFut<S, Item> {
+    fn new(sink: S, item: Item) -> Self {
+        Self(Some(sink), Some(item))
     }
+}
 
-    impl<S: Sink<Item> + Unpin, Item: Unpin> Future for StartSendFut<S, Item> {
-        type Output = Result<S, S::Error>;
+impl<S: Sink<Item> + Unpin, Item: Unpin> Future for StartSendFut<S, Item> {
+    type Output = Result<S, S::Error>;
 
-        fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
-            let Self(inner, item) = self.get_mut();
-            {
-                let mut inner = inner.as_mut().unwrap();
-                ready!(Pin::new(&mut inner).poll_ready(cx))?;
-                Pin::new(&mut inner).start_send(item.take().unwrap())?;
-            }
-            Poll::Ready(Ok(inner.take().unwrap()))
+    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
+        let Self(inner, item) = self.get_mut();
+        {
+            let mut inner = inner.as_mut().unwrap();
+            ready!(Pin::new(&mut inner).poll_ready(cx))?;
+            Pin::new(&mut inner).start_send(item.take().unwrap())?;
         }
+        Poll::Ready(Ok(inner.take().unwrap()))
     }
 }
 
-mod manual_flush {
-    use futures::sink::Sink;
-    use futures::task::{Context, Poll, Waker};
-    use std::mem;
-    use std::pin::Pin;
-
-    // Immediately accepts all requests to start pushing, but completion is managed
-    // by manually flushing
-    pub struct ManualFlush<T: Unpin> {
-        data: Vec<T>,
-        waiting_tasks: Vec<Waker>,
-    }
+// Immediately accepts all requests to start pushing, but completion is managed
+// by manually flushing
+struct ManualFlush<T: Unpin> {
+    data: Vec<T>,
+    waiting_tasks: Vec<Waker>,
+}
 
-    impl<T: Unpin> Sink<Option<T>> for ManualFlush<T> {
-        type Error = ();
+impl<T: Unpin> Sink<Option<T>> for ManualFlush<T> {
+    type Error = ();
 
-        fn poll_ready(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
-            Poll::Ready(Ok(()))
-        }
+    fn poll_ready(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
+        Poll::Ready(Ok(()))
+    }
 
-        fn start_send(mut self: Pin<&mut Self>, item: Option<T>) -> Result<(), Self::Error> {
-            if let Some(item) = item {
-                self.data.push(item);
-            } else {
-                self.force_flush();
-            }
-            Ok(())
+    fn start_send(mut self: Pin<&mut Self>, item: Option<T>) -> Result<(), Self::Error> {
+        if let Some(item) = item {
+            self.data.push(item);
+        } else {
+            self.force_flush();
         }
+        Ok(())
+    }
 
-        fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
-            if self.data.is_empty() {
-                Poll::Ready(Ok(()))
-            } else {
-                self.waiting_tasks.push(cx.waker().clone());
-                Poll::Pending
-            }
+    fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
+        if self.data.is_empty() {
+            Poll::Ready(Ok(()))
+        } else {
+            self.waiting_tasks.push(cx.waker().clone());
+            Poll::Pending
         }
+    }
 
-        fn poll_close(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
-            self.poll_flush(cx)
-        }
+    fn poll_close(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
+        self.poll_flush(cx)
     }
+}
 
-    impl<T: Unpin> ManualFlush<T> {
-        pub fn new() -> Self {
-            Self {
-                data: Vec::new(),
-                waiting_tasks: Vec::new(),
-            }
-        }
+impl<T: Unpin> ManualFlush<T> {
+    fn new() -> Self {
+        Self { data: Vec::new(), waiting_tasks: Vec::new() }
+    }
 
-        pub fn force_flush(&mut self) -> Vec<T> {
-            for task in self.waiting_tasks.drain(..) {
-                task.wake()
-            }
-            mem::replace(&mut self.data, Vec::new())
+    fn force_flush(&mut self) -> Vec<T> {
+        for task in self.waiting_tasks.drain(..) {
+            task.wake()
         }
+        mem::replace(&mut self.data, Vec::new())
     }
 }
 
-mod allowance {
-    use futures::sink::Sink;
-    use futures::task::{Context, Poll, Waker};
-    use std::cell::{Cell, RefCell};
-    use std::pin::Pin;
-    use std::rc::Rc;
+struct ManualAllow<T: Unpin> {
+    data: Vec<T>,
+    allow: Rc<Allow>,
+}
 
-    pub struct ManualAllow<T: Unpin> {
-        pub data: Vec<T>,
-        allow: Rc<Allow>,
-    }
+struct Allow {
+    flag: Cell<bool>,
+    tasks: RefCell<Vec<Waker>>,
+}
 
-    pub struct Allow {
-        flag: Cell<bool>,
-        tasks: RefCell<Vec<Waker>>,
+impl Allow {
+    fn new() -> Self {
+        Self { flag: Cell::new(false), tasks: RefCell::new(Vec::new()) }
     }
 
-    impl Allow {
-        pub fn new() -> Self {
-            Self {
-                flag: Cell::new(false),
-                tasks: RefCell::new(Vec::new()),
-            }
-        }
-
-        pub fn check(&self, cx: &mut Context<'_>) -> bool {
-            if self.flag.get() {
-                true
-            } else {
-                self.tasks.borrow_mut().push(cx.waker().clone());
-                false
-            }
-        }
-
-        pub fn start(&self) {
-            self.flag.set(true);
-            let mut tasks = self.tasks.borrow_mut();
-            for task in tasks.drain(..) {
-                task.wake();
-            }
+    fn check(&self, cx: &mut Context<'_>) -> bool {
+        if self.flag.get() {
+            true
+        } else {
+            self.tasks.borrow_mut().push(cx.waker().clone());
+            false
         }
     }
 
-    impl<T: Unpin> Sink<T> for ManualAllow<T> {
-        type Error = ();
-
-        fn poll_ready(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
-            if self.allow.check(cx) {
-                Poll::Ready(Ok(()))
-            } else {
-                Poll::Pending
-            }
+    fn start(&self) {
+        self.flag.set(true);
+        let mut tasks = self.tasks.borrow_mut();
+        for task in tasks.drain(..) {
+            task.wake();
         }
+    }
+}
 
-        fn start_send(mut self: Pin<&mut Self>, item: T) -> Result<(), Self::Error> {
-            self.data.push(item);
-            Ok(())
-        }
+impl<T: Unpin> Sink<T> for ManualAllow<T> {
+    type Error = ();
 
-        fn poll_flush(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
+    fn poll_ready(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
+        if self.allow.check(cx) {
             Poll::Ready(Ok(()))
+        } else {
+            Poll::Pending
         }
+    }
 
-        fn poll_close(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
-            Poll::Ready(Ok(()))
-        }
+    fn start_send(mut self: Pin<&mut Self>, item: T) -> Result<(), Self::Error> {
+        self.data.push(item);
+        Ok(())
     }
 
-    pub fn manual_allow<T: Unpin>() -> (ManualAllow<T>, Rc<Allow>) {
-        let allow = Rc::new(Allow::new());
-        let manual_allow = ManualAllow {
-            data: Vec::new(),
-            allow: allow.clone(),
-        };
-        (manual_allow, allow)
+    fn poll_flush(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
+        Poll::Ready(Ok(()))
     }
+
+    fn poll_close(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
+        Poll::Ready(Ok(()))
+    }
+}
+
+fn manual_allow<T: Unpin>() -> (ManualAllow<T>, Rc<Allow>) {
+    let allow = Rc::new(Allow::new());
+    let manual_allow = ManualAllow { data: Vec::new(), allow: allow.clone() };
+    (manual_allow, allow)
 }
 
 #[test]
 fn either_sink() {
-    use futures::sink::{Sink, SinkExt};
-    use std::collections::VecDeque;
-    use std::pin::Pin;
-
-    let mut s = if true {
-        Vec::<i32>::new().left_sink()
-    } else {
-        VecDeque::<i32>::new().right_sink()
-    };
+    let mut s =
+        if true { Vec::<i32>::new().left_sink() } else { VecDeque::<i32>::new().right_sink() };
 
     Pin::new(&mut s).start_send(0).unwrap();
 }
 
 #[test]
 fn vec_sink() {
-    use futures::executor::block_on;
-    use futures::sink::{Sink, SinkExt};
-    use std::pin::Pin;
-
     let mut v = Vec::new();
     Pin::new(&mut v).start_send(0).unwrap();
     Pin::new(&mut v).start_send(1).unwrap();
@@ -269,10 +226,6 @@ fn vec_sink() {
 
 #[test]
 fn vecdeque_sink() {
-    use futures::sink::Sink;
-    use std::collections::VecDeque;
-    use std::pin::Pin;
-
     let mut deque = VecDeque::new();
     Pin::new(&mut deque).start_send(2).unwrap();
     Pin::new(&mut deque).start_send(3).unwrap();
@@ -284,9 +237,6 @@ fn vecdeque_sink() {
 
 #[test]
 fn send() {
-    use futures::executor::block_on;
-    use futures::sink::SinkExt;
-
     let mut v = Vec::new();
 
     block_on(v.send(0)).unwrap();
@@ -301,10 +251,6 @@ fn send() {
 
 #[test]
 fn send_all() {
-    use futures::executor::block_on;
-    use futures::sink::SinkExt;
-    use futures::stream::{self, StreamExt};
-
     let mut v = Vec::new();
 
     block_on(v.send_all(&mut stream::iter(vec![0, 1]).map(Ok))).unwrap();
@@ -321,15 +267,6 @@ fn send_all() {
 // channel is full
 #[test]
 fn mpsc_blocking_start_send() {
-    use futures::channel::mpsc;
-    use futures::executor::block_on;
-    use futures::future::{self, FutureExt};
-
-    use start_send_fut::StartSendFut;
-    use flag_cx::flag_cx;
-    use sassert_next::sassert_next;
-    use unwrap::unwrap;
-
     let (mut tx, mut rx) = mpsc::channel::<i32>(0);
 
     block_on(future::lazy(|_| {
@@ -353,17 +290,6 @@ fn mpsc_blocking_start_send() {
 // until a oneshot is completed
 #[test]
 fn with_flush() {
-    use futures::channel::oneshot;
-    use futures::executor::block_on;
-    use futures::future::{self, FutureExt, TryFutureExt};
-    use futures::never::Never;
-    use futures::sink::{Sink, SinkExt};
-    use std::mem;
-    use std::pin::Pin;
-
-    use flag_cx::flag_cx;
-    use unwrap::unwrap;
-
     let (tx, rx) = oneshot::channel();
     let mut block = rx.boxed();
     let mut sink = Vec::new().with(|elem| {
@@ -390,11 +316,6 @@ fn with_flush() {
 // test simple use of with to change data
 #[test]
 fn with_as_map() {
-    use futures::executor::block_on;
-    use futures::future;
-    use futures::never::Never;
-    use futures::sink::SinkExt;
-
     let mut sink = Vec::new().with(|item| future::ok::<i32, Never>(item * 2));
     block_on(sink.send(0)).unwrap();
     block_on(sink.send(1)).unwrap();
@@ -405,10 +326,6 @@ fn with_as_map() {
 // test simple use of with_flat_map
 #[test]
 fn with_flat_map() {
-    use futures::executor::block_on;
-    use futures::sink::SinkExt;
-    use futures::stream::{self, StreamExt};
-
     let mut sink = Vec::new().with_flat_map(|item| stream::iter(vec![item; item]).map(Ok));
     block_on(sink.send(0)).unwrap();
     block_on(sink.send(1)).unwrap();
@@ -421,16 +338,6 @@ fn with_flat_map() {
 // Regression test for the issue #1834.
 #[test]
 fn with_propagates_poll_ready() {
-    use futures::channel::mpsc;
-    use futures::executor::block_on;
-    use futures::future;
-    use futures::sink::{Sink, SinkExt};
-    use futures::task::Poll;
-    use std::pin::Pin;
-
-    use flag_cx::flag_cx;
-    use sassert_next::sassert_next;
-
     let (tx, mut rx) = mpsc::channel::<i32>(0);
     let mut tx = tx.with(|item: i32| future::ok::<i32, mpsc::SendError>(item + 10));
 
@@ -457,14 +364,6 @@ fn with_propagates_poll_ready() {
 // but doesn't claim to be flushed until the underlying sink is
 #[test]
 fn with_flush_propagate() {
-    use futures::future::{self, FutureExt};
-    use futures::sink::{Sink, SinkExt};
-    use std::pin::Pin;
-
-    use manual_flush::ManualFlush;
-    use flag_cx::flag_cx;
-    use unwrap::unwrap;
-
     let mut sink = ManualFlush::new().with(future::ok::<Option<i32>, ()>);
     flag_cx(|flag, cx| {
         unwrap(Pin::new(&mut sink).poll_ready(cx));
@@ -486,21 +385,13 @@ fn with_flush_propagate() {
 // test that `Clone` is implemented on `with` sinks
 #[test]
 fn with_implements_clone() {
-    use futures::channel::mpsc;
-    use futures::executor::block_on;
-    use futures::future;
-    use futures::{SinkExt, StreamExt};
-
     let (mut tx, rx) = mpsc::channel(5);
 
     {
-        let mut is_positive = tx
-            .clone()
-            .with(|item| future::ok::<bool, mpsc::SendError>(item > 0));
+        let mut is_positive = tx.clone().with(|item| future::ok::<bool, mpsc::SendError>(item > 0));
 
-        let mut is_long = tx
-            .clone()
-            .with(|item: &str| future::ok::<bool, mpsc::SendError>(item.len() > 5));
+        let mut is_long =
+            tx.clone().with(|item: &str| future::ok::<bool, mpsc::SendError>(item.len() > 5));
 
         block_on(is_positive.clone().send(-1)).unwrap();
         block_on(is_long.clone().send("123456")).unwrap();
@@ -512,18 +403,12 @@ fn with_implements_clone() {
 
     block_on(tx.close()).unwrap();
 
-    assert_eq!(
-        block_on(rx.collect::<Vec<_>>()),
-        vec![false, true, false, true, false]
-    );
+    assert_eq!(block_on(rx.collect::<Vec<_>>()), vec![false, true, false, true, false]);
 }
 
 // test that a buffer is a no-nop around a sink that always accepts sends
 #[test]
 fn buffer_noop() {
-    use futures::executor::block_on;
-    use futures::sink::SinkExt;
-
     let mut sink = Vec::new().buffer(0);
     block_on(sink.send(0)).unwrap();
     block_on(sink.send(1)).unwrap();
@@ -539,15 +424,6 @@ fn buffer_noop() {
 // and writing out when the underlying sink is ready
 #[test]
 fn buffer() {
-    use futures::executor::block_on;
-    use futures::future::FutureExt;
-    use futures::sink::SinkExt;
-
-    use start_send_fut::StartSendFut;
-    use flag_cx::flag_cx;
-    use unwrap::unwrap;
-    use allowance::manual_allow;
-
     let (sink, allow) = manual_allow::<i32>();
     let sink = sink.buffer(2);
 
@@ -567,10 +443,6 @@ fn buffer() {
 
 #[test]
 fn fanout_smoke() {
-    use futures::executor::block_on;
-    use futures::sink::SinkExt;
-    use futures::stream::{self, StreamExt};
-
     let sink1 = Vec::new();
     let sink2 = Vec::new();
     let mut sink = sink1.fanout(sink2);
@@ -582,16 +454,6 @@ fn fanout_smoke() {
 
 #[test]
 fn fanout_backpressure() {
-    use futures::channel::mpsc;
-    use futures::executor::block_on;
-    use futures::future::FutureExt;
-    use futures::sink::SinkExt;
-    use futures::stream::StreamExt;
-
-    use start_send_fut::StartSendFut;
-    use flag_cx::flag_cx;
-    use unwrap::unwrap;
-
     let (left_send, mut left_recv) = mpsc::channel(0);
     let (right_send, mut right_recv) = mpsc::channel(0);
     let sink = left_send.fanout(right_send);
@@ -624,12 +486,6 @@ fn fanout_backpressure() {
 
 #[test]
 fn sink_map_err() {
-    use futures::channel::mpsc;
-    use futures::sink::{Sink, SinkExt};
-    use futures::task::Poll;
-    use futures_test::task::panic_context;
-    use std::pin::Pin;
-
     {
         let cx = &mut panic_context();
         let (tx, _rx) = mpsc::channel(1);
@@ -639,20 +495,11 @@ fn sink_map_err() {
     }
 
     let tx = mpsc::channel(0).0;
-    assert_eq!(
-        Pin::new(&mut tx.sink_map_err(|_| ())).start_send(()),
-        Err(())
-    );
+    assert_eq!(Pin::new(&mut tx.sink_map_err(|_| ())).start_send(()), Err(()));
 }
 
 #[test]
 fn sink_unfold() {
-    use futures::channel::mpsc;
-    use futures::executor::block_on;
-    use futures::future::poll_fn;
-    use futures::sink::{self, Sink, SinkExt};
-    use futures::task::Poll;
-
     block_on(poll_fn(|cx| {
         let (tx, mut rx) = mpsc::channel(1);
         let unfold = sink::unfold((), |(), i: i32| {
@@ -685,14 +532,8 @@ fn sink_unfold() {
 
 #[test]
 fn err_into() {
-    use futures::channel::mpsc;
-    use futures::sink::{Sink, SinkErrInto, SinkExt};
-    use futures::task::Poll;
-    use futures_test::task::panic_context;
-    use std::pin::Pin;
-
     #[derive(Copy, Clone, Debug, PartialEq, Eq)]
-    pub struct ErrIntoTest;
+    struct ErrIntoTest;
 
     impl From<mpsc::SendError> for ErrIntoTest {
         fn from(_: mpsc::SendError) -> Self {
@@ -709,8 +550,5 @@ fn err_into() {
     }
 
     let tx = mpsc::channel(0).0;
-    assert_eq!(
-        Pin::new(&mut tx.sink_err_into()).start_send(()),
-        Err(ErrIntoTest)
-    );
+    assert_eq!(Pin::new(&mut tx.sink_err_into()).start_send(()), Err(ErrIntoTest));
 }
diff --git a/third_party/rust/futures/tests/sink_fanout.rs b/third_party/rust/futures/tests/sink_fanout.rs
index 7d1fa437901c103579426957af4b19a00c3b550d..e57b2d8c7b8a3590f5b5c7172c7520f4f4a1a2f0 100644
--- a/third_party/rust/futures/tests/sink_fanout.rs
+++ b/third_party/rust/futures/tests/sink_fanout.rs
@@ -1,11 +1,11 @@
+use futures::channel::mpsc;
+use futures::executor::block_on;
+use futures::future::join3;
+use futures::sink::SinkExt;
+use futures::stream::{self, StreamExt};
+
 #[test]
 fn it_works() {
-    use futures::channel::mpsc;
-    use futures::executor::block_on;
-    use futures::future::join3;
-    use futures::sink::SinkExt;
-    use futures::stream::{self, StreamExt};
-
     let (tx1, rx1) = mpsc::channel(1);
     let (tx2, rx2) = mpsc::channel(2);
     let tx = tx1.fanout(tx2).sink_map_err(|_| ());
diff --git a/third_party/rust/futures/tests/split.rs b/third_party/rust/futures/tests/split.rs
deleted file mode 100644
index 86c2fc6b821c82dd12ecd70e6941d03ac255fcee..0000000000000000000000000000000000000000
--- a/third_party/rust/futures/tests/split.rs
+++ /dev/null
@@ -1,75 +0,0 @@
-#[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_project::pin_project;
-    use std::pin::Pin;
-
-    #[pin_project]
-    struct Join<T, U> {
-        #[pin]
-        stream: T,
-        #[pin]
-        sink: U,
-    }
-
-    impl<T: Stream, U> Stream for Join<T, U> {
-        type Item = T::Item;
-
-        fn poll_next(
-            self: Pin<&mut Self>,
-            cx: &mut Context<'_>,
-        ) -> Poll<Option<T::Item>> {
-            self.project().stream.poll_next(cx)
-        }
-    }
-
-    impl<T, U: Sink<Item>, Item> Sink<Item> for Join<T, U> {
-        type Error = U::Error;
-
-        fn poll_ready(
-            self: Pin<&mut Self>,
-            cx: &mut Context<'_>,
-        ) -> Poll<Result<(), Self::Error>> {
-            self.project().sink.poll_ready(cx)
-        }
-
-        fn start_send(
-            self: Pin<&mut Self>,
-            item: Item,
-        ) -> Result<(), Self::Error> {
-            self.project().sink.start_send(item)
-        }
-
-        fn poll_flush(
-            self: Pin<&mut Self>,
-            cx: &mut Context<'_>,
-        ) -> Poll<Result<(), Self::Error>> {
-            self.project().sink.poll_flush(cx)
-        }
-
-        fn poll_close(
-            self: Pin<&mut Self>,
-            cx: &mut Context<'_>,
-        ) -> Poll<Result<(), Self::Error>> {
-            self.project().sink.poll_close(cx)
-        }
-    }
-
-    let mut dest: Vec<i32> = Vec::new();
-    {
-       let join = Join {
-            stream: stream::iter(vec![10, 20, 30]),
-            sink: &mut dest
-        };
-
-        let (sink, stream) = join.split();
-        let join = sink.reunite(stream).expect("test_split: reunite error");
-        let (mut sink, stream) = join.split();
-        let mut stream = stream.map(Ok);
-        block_on(sink.send_all(&mut stream)).unwrap();
-    }
-    assert_eq!(dest, vec![10, 20, 30]);
-}
diff --git a/third_party/rust/futures/tests/stream.rs b/third_party/rust/futures/tests/stream.rs
index 14b283db7a029f71649e6ada284c7442a07ff6ea..0d453d1752a50b37ec843d5e73dde187d653f31c 100644
--- a/third_party/rust/futures/tests/stream.rs
+++ b/third_party/rust/futures/tests/stream.rs
@@ -1,8 +1,14 @@
+use futures::channel::mpsc;
+use futures::executor::block_on;
+use futures::future::{self, Future};
+use futures::sink::SinkExt;
+use futures::stream::{self, StreamExt};
+use futures::task::Poll;
+use futures::FutureExt;
+use futures_test::task::noop_context;
+
 #[test]
 fn select() {
-    use futures::executor::block_on;
-    use futures::stream::{self, StreamExt};
-
     fn select_and_compare(a: Vec<u32>, b: Vec<u32>, expected: Vec<u32>) {
         let a = stream::iter(a);
         let b = stream::iter(b);
@@ -17,19 +23,12 @@ fn select() {
 
 #[test]
 fn flat_map() {
-    use futures::stream::{self, StreamExt};
-
-    futures::executor::block_on(async {
-        let st = stream::iter(vec![
-            stream::iter(0..=4u8),
-            stream::iter(6..=10),
-            stream::iter(0..=2),
-        ]);
-
-        let values: Vec<_> = st
-            .flat_map(|s| s.filter(|v| futures::future::ready(v % 2 == 0)))
-            .collect()
-            .await;
+    block_on(async {
+        let st =
+            stream::iter(vec![stream::iter(0..=4u8), stream::iter(6..=10), stream::iter(0..=2)]);
+
+        let values: Vec<_> =
+            st.flat_map(|s| s.filter(|v| futures::future::ready(v % 2 == 0))).collect().await;
 
         assert_eq!(values, vec![0, 2, 4, 6, 8, 10, 0, 2]);
     });
@@ -37,28 +36,21 @@ fn flat_map() {
 
 #[test]
 fn scan() {
-    use futures::stream::{self, StreamExt};
-
-    futures::executor::block_on(async {
-        assert_eq!(
-            stream::iter(vec![1u8, 2, 3, 4, 6, 8, 2])
-                .scan(1, |state, e| {
-                    *state += 1;
-                    futures::future::ready(if e < *state { Some(e) } else { None })
-                })
-                .collect::<Vec<_>>()
-                .await,
-            vec![1u8, 2, 3, 4]
-        );
+    block_on(async {
+        let values = stream::iter(vec![1u8, 2, 3, 4, 6, 8, 2])
+            .scan(1, |state, e| {
+                *state += 1;
+                futures::future::ready(if e < *state { Some(e) } else { None })
+            })
+            .collect::<Vec<_>>()
+            .await;
+
+        assert_eq!(values, vec![1u8, 2, 3, 4]);
     });
 }
 
 #[test]
 fn take_until() {
-    use futures::future::{self, Future};
-    use futures::stream::{self, StreamExt};
-    use futures::task::Poll;
-
     fn make_stop_fut(stop_on: u32) -> impl Future<Output = ()> {
         let mut i = 0;
         future::poll_fn(move |_cx| {
@@ -71,7 +63,7 @@ fn take_until() {
         })
     }
 
-    futures::executor::block_on(async {
+    block_on(async {
         // Verify stopping works:
         let stream = stream::iter(1u32..=10);
         let stop_fut = make_stop_fut(5);
@@ -123,10 +115,15 @@ fn take_until() {
 
 #[test]
 #[should_panic]
-fn ready_chunks_panic_on_cap_zero() {
-    use futures::channel::mpsc;
-    use futures::stream::StreamExt;
+fn chunks_panic_on_cap_zero() {
+    let (_, rx1) = mpsc::channel::<()>(1);
+
+    let _ = rx1.chunks(0);
+}
 
+#[test]
+#[should_panic]
+fn ready_chunks_panic_on_cap_zero() {
     let (_, rx1) = mpsc::channel::<()>(1);
 
     let _ = rx1.ready_chunks(0);
@@ -134,12 +131,6 @@ fn ready_chunks_panic_on_cap_zero() {
 
 #[test]
 fn ready_chunks() {
-    use futures::channel::mpsc;
-    use futures::stream::StreamExt;
-    use futures::sink::SinkExt;
-    use futures::FutureExt;
-    use futures_test::task::noop_context;
-
     let (mut tx, rx1) = mpsc::channel::<i32>(16);
 
     let mut s = rx1.ready_chunks(2);
@@ -147,14 +138,14 @@ fn ready_chunks() {
     let mut cx = noop_context();
     assert!(s.next().poll_unpin(&mut cx).is_pending());
 
-    futures::executor::block_on(async {
+    block_on(async {
         tx.send(1).await.unwrap();
 
         assert_eq!(s.next().await.unwrap(), vec![1]);
         tx.send(2).await.unwrap();
         tx.send(3).await.unwrap();
         tx.send(4).await.unwrap();
-        assert_eq!(s.next().await.unwrap(), vec![2,3]);
+        assert_eq!(s.next().await.unwrap(), vec![2, 3]);
         assert_eq!(s.next().await.unwrap(), vec![4]);
     });
 }
diff --git a/third_party/rust/futures/tests/stream_abortable.rs b/third_party/rust/futures/tests/stream_abortable.rs
new file mode 100644
index 0000000000000000000000000000000000000000..2339dd05224156d0e3a44b7fa45141a76647e2a0
--- /dev/null
+++ b/third_party/rust/futures/tests/stream_abortable.rs
@@ -0,0 +1,46 @@
+use futures::channel::mpsc;
+use futures::executor::block_on;
+use futures::stream::{abortable, Stream, StreamExt};
+use futures::task::{Context, Poll};
+use futures::SinkExt;
+use futures_test::task::new_count_waker;
+use std::pin::Pin;
+
+#[test]
+fn abortable_works() {
+    let (_tx, a_rx) = mpsc::channel::<()>(1);
+    let (mut abortable_rx, abort_handle) = abortable(a_rx);
+
+    abort_handle.abort();
+    assert!(abortable_rx.is_aborted());
+    assert_eq!(None, block_on(abortable_rx.next()));
+}
+
+#[test]
+fn abortable_awakens() {
+    let (_tx, a_rx) = mpsc::channel::<()>(1);
+    let (mut abortable_rx, abort_handle) = abortable(a_rx);
+
+    let (waker, counter) = new_count_waker();
+    let mut cx = Context::from_waker(&waker);
+
+    assert_eq!(counter, 0);
+    assert_eq!(Poll::Pending, Pin::new(&mut abortable_rx).poll_next(&mut cx));
+    assert_eq!(counter, 0);
+
+    abort_handle.abort();
+    assert_eq!(counter, 1);
+    assert!(abortable_rx.is_aborted());
+    assert_eq!(Poll::Ready(None), Pin::new(&mut abortable_rx).poll_next(&mut cx));
+}
+
+#[test]
+fn abortable_resolves() {
+    let (mut tx, a_rx) = mpsc::channel::<()>(1);
+    let (mut abortable_rx, _abort_handle) = abortable(a_rx);
+
+    block_on(tx.send(())).unwrap();
+
+    assert!(!abortable_rx.is_aborted());
+    assert_eq!(Some(()), block_on(abortable_rx.next()));
+}
diff --git a/third_party/rust/futures/tests/buffer_unordered.rs b/third_party/rust/futures/tests/stream_buffer_unordered.rs
similarity index 89%
rename from third_party/rust/futures/tests/buffer_unordered.rs
rename to third_party/rust/futures/tests/stream_buffer_unordered.rs
index 5c8b8bf7e5726812332d3719dd90357f36aa4e3f..9a2ee174ed01e26d993ef54d7b705603e3170424 100644
--- a/third_party/rust/futures/tests/buffer_unordered.rs
+++ b/third_party/rust/futures/tests/stream_buffer_unordered.rs
@@ -1,13 +1,13 @@
+use futures::channel::{mpsc, oneshot};
+use futures::executor::{block_on, block_on_stream};
+use futures::sink::SinkExt;
+use futures::stream::StreamExt;
+use std::sync::mpsc as std_mpsc;
+use std::thread;
+
 #[test]
 #[ignore] // FIXME: https://github.com/rust-lang/futures-rs/issues/1790
 fn works() {
-    use futures::channel::{oneshot, mpsc};
-    use futures::executor::{block_on, block_on_stream};
-    use futures::sink::SinkExt;
-    use futures::stream::StreamExt;
-    use std::sync::mpsc as std_mpsc;
-    use std::thread;
-
     const N: usize = 4;
 
     let (mut tx, rx) = mpsc::channel(1);
diff --git a/third_party/rust/futures/tests/stream_catch_unwind.rs b/third_party/rust/futures/tests/stream_catch_unwind.rs
index 272558cc613f9a68296ab37144e823f6262057e5..8b23a0a7efb30cc4372fc7837ffc2a0e550d9b34 100644
--- a/third_party/rust/futures/tests/stream_catch_unwind.rs
+++ b/third_party/rust/futures/tests/stream_catch_unwind.rs
@@ -1,8 +1,8 @@
+use futures::executor::block_on_stream;
+use futures::stream::{self, StreamExt};
+
 #[test]
 fn panic_in_the_middle_of_the_stream() {
-    use futures::executor::block_on_stream;
-    use futures::stream::{self, StreamExt};
-
     let stream = stream::iter(vec![Some(10), None, Some(11)]);
 
     // panic on second element
@@ -16,9 +16,6 @@ fn panic_in_the_middle_of_the_stream() {
 
 #[test]
 fn no_panic() {
-    use futures::executor::block_on_stream;
-    use futures::stream::{self, StreamExt};
-
     let stream = stream::iter(vec![10, 11, 12]);
 
     let mut iter = block_on_stream(stream.catch_unwind());
diff --git a/third_party/rust/futures/tests/futures_ordered.rs b/third_party/rust/futures/tests/stream_futures_ordered.rs
similarity index 58%
rename from third_party/rust/futures/tests/futures_ordered.rs
rename to third_party/rust/futures/tests/stream_futures_ordered.rs
index 7f21c829e34d09170b89ac6bbac06e122692b6eb..7506c65a63d082229812413f9b0bce238272f074 100644
--- a/third_party/rust/futures/tests/futures_ordered.rs
+++ b/third_party/rust/futures/tests/stream_futures_ordered.rs
@@ -1,10 +1,12 @@
+use futures::channel::oneshot;
+use futures::executor::{block_on, block_on_stream};
+use futures::future::{self, join, Future, FutureExt, TryFutureExt};
+use futures::stream::{FuturesOrdered, StreamExt};
+use futures_test::task::noop_context;
+use std::any::Any;
+
 #[test]
 fn works_1() {
-    use futures::channel::oneshot;
-    use futures::executor::block_on_stream;
-    use futures::stream::{StreamExt, FuturesOrdered};
-    use futures_test::task::noop_context;
-
     let (a_tx, a_rx) = oneshot::channel::<i32>();
     let (b_tx, b_rx) = oneshot::channel::<i32>();
     let (c_tx, c_rx) = oneshot::channel::<i32>();
@@ -26,19 +28,13 @@ fn works_1() {
 
 #[test]
 fn works_2() {
-    use futures::channel::oneshot;
-    use futures::future::{join, FutureExt};
-    use futures::stream::{StreamExt, FuturesOrdered};
-    use futures_test::task::noop_context;
-
     let (a_tx, a_rx) = oneshot::channel::<i32>();
     let (b_tx, b_rx) = oneshot::channel::<i32>();
     let (c_tx, c_rx) = oneshot::channel::<i32>();
 
-    let mut stream = vec![
-        a_rx.boxed(),
-        join(b_rx, c_rx).map(|(a, b)| Ok(a? + b?)).boxed(),
-    ].into_iter().collect::<FuturesOrdered<_>>();
+    let mut stream = vec![a_rx.boxed(), join(b_rx, c_rx).map(|(a, b)| Ok(a? + b?)).boxed()]
+        .into_iter()
+        .collect::<FuturesOrdered<_>>();
 
     let mut cx = noop_context();
     a_tx.send(33).unwrap();
@@ -51,37 +47,29 @@ fn works_2() {
 
 #[test]
 fn from_iterator() {
-    use futures::executor::block_on;
-    use futures::future;
-    use futures::stream::{StreamExt, FuturesOrdered};
-
-    let stream = vec![
-        future::ready::<i32>(1),
-        future::ready::<i32>(2),
-        future::ready::<i32>(3)
-    ].into_iter().collect::<FuturesOrdered<_>>();
+    let stream = vec![future::ready::<i32>(1), future::ready::<i32>(2), future::ready::<i32>(3)]
+        .into_iter()
+        .collect::<FuturesOrdered<_>>();
     assert_eq!(stream.len(), 3);
-    assert_eq!(block_on(stream.collect::<Vec<_>>()), vec![1,2,3]);
+    assert_eq!(block_on(stream.collect::<Vec<_>>()), vec![1, 2, 3]);
 }
 
 #[test]
 fn queue_never_unblocked() {
-    use futures::channel::oneshot;
-    use futures::future::{self, Future, TryFutureExt};
-    use futures::stream::{StreamExt, FuturesOrdered};
-    use futures_test::task::noop_context;
-    use std::any::Any;
-
     let (_a_tx, a_rx) = oneshot::channel::<Box<dyn Any + Send>>();
     let (b_tx, b_rx) = oneshot::channel::<Box<dyn Any + Send>>();
     let (c_tx, c_rx) = oneshot::channel::<Box<dyn Any + Send>>();
 
     let mut stream = vec![
         Box::new(a_rx) as Box<dyn Future<Output = _> + Unpin>,
-        Box::new(future::try_select(b_rx, c_rx)
-            .map_err(|e| e.factor_first().0)
-            .and_then(|e| future::ok(Box::new(e) as Box<dyn Any + Send>))) as _,
-    ].into_iter().collect::<FuturesOrdered<_>>();
+        Box::new(
+            future::try_select(b_rx, c_rx)
+                .map_err(|e| e.factor_first().0)
+                .and_then(|e| future::ok(Box::new(e) as Box<dyn Any + Send>)),
+        ) as _,
+    ]
+    .into_iter()
+    .collect::<FuturesOrdered<_>>();
 
     let cx = &mut noop_context();
     for _ in 0..10 {
diff --git a/third_party/rust/futures/tests/futures_unordered.rs b/third_party/rust/futures/tests/stream_futures_unordered.rs
similarity index 62%
rename from third_party/rust/futures/tests/futures_unordered.rs
rename to third_party/rust/futures/tests/stream_futures_unordered.rs
index 4dd0deb1670d29adbcfeb698e03a4a8e0796a280..4b9afccaf9b6caa44332b5bd018adde5d662b2e5 100644
--- a/third_party/rust/futures/tests/futures_unordered.rs
+++ b/third_party/rust/futures/tests/stream_futures_unordered.rs
@@ -1,10 +1,17 @@
+use futures::channel::oneshot;
+use futures::executor::{block_on, block_on_stream};
+use futures::future::{self, join, Future, FutureExt};
+use futures::stream::{FusedStream, FuturesUnordered, StreamExt};
+use futures::task::{Context, Poll};
+use futures_test::future::FutureTestExt;
+use futures_test::task::noop_context;
+use futures_test::{assert_stream_done, assert_stream_next, assert_stream_pending};
+use std::iter::FromIterator;
+use std::pin::Pin;
+use std::sync::atomic::{AtomicBool, Ordering};
+
 #[test]
 fn is_terminated() {
-    use futures::future;
-    use futures::stream::{FusedStream, FuturesUnordered, StreamExt};
-    use futures::task::Poll;
-    use futures_test::task::noop_context;
-
     let mut cx = noop_context();
     let mut tasks = FuturesUnordered::new();
 
@@ -32,19 +39,12 @@ fn is_terminated() {
 
 #[test]
 fn works_1() {
-    use futures::channel::oneshot;
-    use futures::executor::block_on_stream;
-    use futures::stream::FuturesUnordered;
-
     let (a_tx, a_rx) = oneshot::channel::<i32>();
     let (b_tx, b_rx) = oneshot::channel::<i32>();
     let (c_tx, c_rx) = oneshot::channel::<i32>();
 
-    let mut iter = block_on_stream(
-        vec![a_rx, b_rx, c_rx]
-            .into_iter()
-            .collect::<FuturesUnordered<_>>(),
-    );
+    let mut iter =
+        block_on_stream(vec![a_rx, b_rx, c_rx].into_iter().collect::<FuturesUnordered<_>>());
 
     b_tx.send(99).unwrap();
     assert_eq!(Some(Ok(99)), iter.next());
@@ -58,22 +58,13 @@ fn works_1() {
 
 #[test]
 fn works_2() {
-    use futures::channel::oneshot;
-    use futures::future::{join, FutureExt};
-    use futures::stream::{FuturesUnordered, StreamExt};
-    use futures::task::Poll;
-    use futures_test::task::noop_context;
-
     let (a_tx, a_rx) = oneshot::channel::<i32>();
     let (b_tx, b_rx) = oneshot::channel::<i32>();
     let (c_tx, c_rx) = oneshot::channel::<i32>();
 
-    let mut stream = vec![
-        a_rx.boxed(),
-        join(b_rx, c_rx).map(|(a, b)| Ok(a? + b?)).boxed(),
-    ]
-    .into_iter()
-    .collect::<FuturesUnordered<_>>();
+    let mut stream = vec![a_rx.boxed(), join(b_rx, c_rx).map(|(a, b)| Ok(a? + b?)).boxed()]
+        .into_iter()
+        .collect::<FuturesUnordered<_>>();
 
     a_tx.send(9).unwrap();
     b_tx.send(10).unwrap();
@@ -87,29 +78,15 @@ fn works_2() {
 
 #[test]
 fn from_iterator() {
-    use futures::executor::block_on;
-    use futures::future;
-    use futures::stream::{FuturesUnordered, StreamExt};
-
-    let stream = vec![
-        future::ready::<i32>(1),
-        future::ready::<i32>(2),
-        future::ready::<i32>(3),
-    ]
-    .into_iter()
-    .collect::<FuturesUnordered<_>>();
+    let stream = vec![future::ready::<i32>(1), future::ready::<i32>(2), future::ready::<i32>(3)]
+        .into_iter()
+        .collect::<FuturesUnordered<_>>();
     assert_eq!(stream.len(), 3);
     assert_eq!(block_on(stream.collect::<Vec<_>>()), vec![1, 2, 3]);
 }
 
 #[test]
 fn finished_future() {
-    use std::marker::Unpin;
-    use futures::channel::oneshot;
-    use futures::future::{self, Future, FutureExt};
-    use futures::stream::{FuturesUnordered, StreamExt};
-    use futures_test::task::noop_context;
-
     let (_a_tx, a_rx) = oneshot::channel::<i32>();
     let (b_tx, b_rx) = oneshot::channel::<i32>();
     let (c_tx, c_rx) = oneshot::channel::<i32>();
@@ -135,17 +112,11 @@ fn finished_future() {
 
 #[test]
 fn iter_mut_cancel() {
-    use futures::channel::oneshot;
-    use futures::executor::block_on_stream;
-    use futures::stream::FuturesUnordered;
-
     let (a_tx, a_rx) = oneshot::channel::<i32>();
     let (b_tx, b_rx) = oneshot::channel::<i32>();
     let (c_tx, c_rx) = oneshot::channel::<i32>();
 
-    let mut stream = vec![a_rx, b_rx, c_rx]
-        .into_iter()
-        .collect::<FuturesUnordered<_>>();
+    let mut stream = vec![a_rx, b_rx, c_rx].into_iter().collect::<FuturesUnordered<_>>();
 
     for rx in stream.iter_mut() {
         rx.close();
@@ -165,16 +136,10 @@ fn iter_mut_cancel() {
 
 #[test]
 fn iter_mut_len() {
-    use futures::future;
-    use futures::stream::FuturesUnordered;
-
-    let mut stream = vec![
-        future::pending::<()>(),
-        future::pending::<()>(),
-        future::pending::<()>(),
-    ]
-    .into_iter()
-    .collect::<FuturesUnordered<_>>();
+    let mut stream =
+        vec![future::pending::<()>(), future::pending::<()>(), future::pending::<()>()]
+            .into_iter()
+            .collect::<FuturesUnordered<_>>();
 
     let mut iter_mut = stream.iter_mut();
     assert_eq!(iter_mut.len(), 3);
@@ -189,15 +154,6 @@ fn iter_mut_len() {
 
 #[test]
 fn iter_cancel() {
-    use std::marker::Unpin;
-    use std::pin::Pin;
-    use std::sync::atomic::{AtomicBool, Ordering};
-
-    use futures::executor::block_on_stream;
-    use futures::future::{self, Future, FutureExt};
-    use futures::stream::FuturesUnordered;
-    use futures::task::{Context, Poll};
-
     struct AtomicCancel<F> {
         future: F,
         cancel: AtomicBool,
@@ -243,16 +199,9 @@ fn iter_cancel() {
 
 #[test]
 fn iter_len() {
-    use futures::future;
-    use futures::stream::FuturesUnordered;
-
-    let stream = vec![
-        future::pending::<()>(),
-        future::pending::<()>(),
-        future::pending::<()>(),
-    ]
-    .into_iter()
-    .collect::<FuturesUnordered<_>>();
+    let stream = vec![future::pending::<()>(), future::pending::<()>(), future::pending::<()>()]
+        .into_iter()
+        .collect::<FuturesUnordered<_>>();
 
     let mut iter = stream.iter();
     assert_eq!(iter.len(), 3);
@@ -266,16 +215,57 @@ fn iter_len() {
 }
 
 #[test]
-fn futures_not_moved_after_poll() {
-    use futures::future;
-    use futures::stream::FuturesUnordered;
-    use futures_test::future::FutureTestExt;
-    use futures_test::{assert_stream_done, assert_stream_next};
+fn into_iter_cancel() {
+    let (a_tx, a_rx) = oneshot::channel::<i32>();
+    let (b_tx, b_rx) = oneshot::channel::<i32>();
+    let (c_tx, c_rx) = oneshot::channel::<i32>();
+
+    let stream = vec![a_rx, b_rx, c_rx].into_iter().collect::<FuturesUnordered<_>>();
+
+    let stream = stream
+        .into_iter()
+        .map(|mut rx| {
+            rx.close();
+            rx
+        })
+        .collect::<FuturesUnordered<_>>();
 
+    let mut iter = block_on_stream(stream);
+
+    assert!(a_tx.is_canceled());
+    assert!(b_tx.is_canceled());
+    assert!(c_tx.is_canceled());
+
+    assert_eq!(iter.next(), Some(Err(futures::channel::oneshot::Canceled)));
+    assert_eq!(iter.next(), Some(Err(futures::channel::oneshot::Canceled)));
+    assert_eq!(iter.next(), Some(Err(futures::channel::oneshot::Canceled)));
+    assert_eq!(iter.next(), None);
+}
+
+#[test]
+fn into_iter_len() {
+    let stream = vec![future::pending::<()>(), future::pending::<()>(), future::pending::<()>()]
+        .into_iter()
+        .collect::<FuturesUnordered<_>>();
+
+    let mut into_iter = stream.into_iter();
+    assert_eq!(into_iter.len(), 3);
+    assert!(into_iter.next().is_some());
+    assert_eq!(into_iter.len(), 2);
+    assert!(into_iter.next().is_some());
+    assert_eq!(into_iter.len(), 1);
+    assert!(into_iter.next().is_some());
+    assert_eq!(into_iter.len(), 0);
+    assert!(into_iter.next().is_none());
+}
+
+#[test]
+fn futures_not_moved_after_poll() {
     // Future that will be ready after being polled twice,
     // asserting that it does not move.
     let fut = future::ready(()).pending_once().assert_unmoved();
     let mut stream = vec![fut; 3].into_iter().collect::<FuturesUnordered<_>>();
+    assert_stream_pending!(stream);
     assert_stream_next!(stream, ());
     assert_stream_next!(stream, ());
     assert_stream_next!(stream, ());
@@ -284,11 +274,6 @@ fn futures_not_moved_after_poll() {
 
 #[test]
 fn len_valid_during_out_of_order_completion() {
-    use futures::channel::oneshot;
-    use futures::stream::{FuturesUnordered, StreamExt};
-    use futures::task::Poll;
-    use futures_test::task::noop_context;
-
     // Complete futures out-of-order and add new futures afterwards to ensure
     // length values remain correct.
     let (a_tx, a_rx) = oneshot::channel::<i32>();
@@ -326,3 +311,59 @@ fn len_valid_during_out_of_order_completion() {
     assert_eq!(stream.poll_next_unpin(&mut cx), Poll::Ready(Some(Ok(7))));
     assert_eq!(stream.len(), 0);
 }
+
+#[test]
+fn polled_only_once_at_most_per_iteration() {
+    #[derive(Debug, Clone, Copy, Default)]
+    struct F {
+        polled: bool,
+    }
+
+    impl Future for F {
+        type Output = ();
+
+        fn poll(mut self: Pin<&mut Self>, _: &mut Context) -> Poll<Self::Output> {
+            if self.polled {
+                panic!("polled twice")
+            } else {
+                self.polled = true;
+                Poll::Pending
+            }
+        }
+    }
+
+    let cx = &mut noop_context();
+
+    let mut tasks = FuturesUnordered::from_iter(vec![F::default(); 10]);
+    assert!(tasks.poll_next_unpin(cx).is_pending());
+    assert_eq!(10, tasks.iter().filter(|f| f.polled).count());
+
+    let mut tasks = FuturesUnordered::from_iter(vec![F::default(); 33]);
+    assert!(tasks.poll_next_unpin(cx).is_pending());
+    assert_eq!(33, tasks.iter().filter(|f| f.polled).count());
+
+    let mut tasks = FuturesUnordered::<F>::new();
+    assert_eq!(Poll::Ready(None), tasks.poll_next_unpin(cx));
+}
+
+#[test]
+fn clear() {
+    let mut tasks = FuturesUnordered::from_iter(vec![future::ready(1), future::ready(2)]);
+
+    assert_eq!(block_on(tasks.next()), Some(1));
+    assert!(!tasks.is_empty());
+
+    tasks.clear();
+    assert!(tasks.is_empty());
+
+    tasks.push(future::ready(3));
+    assert!(!tasks.is_empty());
+
+    tasks.clear();
+    assert!(tasks.is_empty());
+
+    assert_eq!(block_on(tasks.next()), None);
+    assert!(tasks.is_terminated());
+    tasks.clear();
+    assert!(!tasks.is_terminated());
+}
diff --git a/third_party/rust/futures/tests/stream_into_async_read.rs b/third_party/rust/futures/tests/stream_into_async_read.rs
index 222c985706c08a5998d772e12d10092ee6225206..60188d3e58ea875a519b046df07b0251b11c97d3 100644
--- a/third_party/rust/futures/tests/stream_into_async_read.rs
+++ b/third_party/rust/futures/tests/stream_into_async_read.rs
@@ -1,31 +1,51 @@
-#[test]
-fn test_into_async_read() {
-    use core::pin::Pin;
-    use futures::io::AsyncRead;
-    use futures::stream::{self, TryStreamExt};
-    use futures::task::Poll;
-    use futures_test::{task::noop_context, stream::StreamTestExt};
-
-    macro_rules! assert_read {
-        ($reader:expr, $buf:expr, $item:expr) => {
-            let mut cx = noop_context();
-            loop {
-                match Pin::new(&mut $reader).poll_read(&mut cx, $buf) {
-                    Poll::Ready(Ok(x)) => {
-                        assert_eq!(x, $item);
-                        break;
-                    }
-                    Poll::Ready(Err(err)) => {
-                        panic!("assertion failed: expected value but got {}", err);
-                    }
-                    Poll::Pending => {
-                        continue;
-                    }
+use core::pin::Pin;
+use futures::io::{AsyncBufRead, AsyncRead};
+use futures::stream::{self, TryStreamExt};
+use futures::task::Poll;
+use futures_test::{stream::StreamTestExt, task::noop_context};
+
+macro_rules! assert_read {
+    ($reader:expr, $buf:expr, $item:expr) => {
+        let mut cx = noop_context();
+        loop {
+            match Pin::new(&mut $reader).poll_read(&mut cx, $buf) {
+                Poll::Ready(Ok(x)) => {
+                    assert_eq!(x, $item);
+                    break;
+                }
+                Poll::Ready(Err(err)) => {
+                    panic!("assertion failed: expected value but got {}", err);
+                }
+                Poll::Pending => {
+                    continue;
+                }
+            }
+        }
+    };
+}
+
+macro_rules! assert_fill_buf {
+    ($reader:expr, $buf:expr) => {
+        let mut cx = noop_context();
+        loop {
+            match Pin::new(&mut $reader).poll_fill_buf(&mut cx) {
+                Poll::Ready(Ok(x)) => {
+                    assert_eq!(x, $buf);
+                    break;
+                }
+                Poll::Ready(Err(err)) => {
+                    panic!("assertion failed: expected value but got {}", err);
+                }
+                Poll::Pending => {
+                    continue;
                 }
             }
-        };
-    }
+        }
+    };
+}
 
+#[test]
+fn test_into_async_read() {
     let stream = stream::iter((1..=3).flat_map(|_| vec![Ok(vec![]), Ok(vec![1, 2, 3, 4, 5])]));
     let mut reader = stream.interleave_pending().into_async_read();
     let mut buf = vec![0; 3];
@@ -53,32 +73,6 @@ fn test_into_async_read() {
 
 #[test]
 fn test_into_async_bufread() {
-    use core::pin::Pin;
-    use futures::io::AsyncBufRead;
-    use futures::stream::{self, TryStreamExt};
-    use futures::task::Poll;
-    use futures_test::{task::noop_context, stream::StreamTestExt};
-
-    macro_rules! assert_fill_buf {
-        ($reader:expr, $buf:expr) => {
-            let mut cx = noop_context();
-            loop {
-                match Pin::new(&mut $reader).poll_fill_buf(&mut cx) {
-                    Poll::Ready(Ok(x)) => {
-                        assert_eq!(x, $buf);
-                        break;
-                    }
-                    Poll::Ready(Err(err)) => {
-                        panic!("assertion failed: expected value but got {}", err);
-                    }
-                    Poll::Pending => {
-                        continue;
-                    }
-                }
-            }
-        };
-    }
-
     let stream = stream::iter((1..=2).flat_map(|_| vec![Ok(vec![]), Ok(vec![1, 2, 3, 4, 5])]));
     let mut reader = stream.interleave_pending().into_async_read();
 
diff --git a/third_party/rust/futures/tests/stream_peekable.rs b/third_party/rust/futures/tests/stream_peekable.rs
index 66a7385ae912fafa378da6c6fabf2aa54df66302..2fa7f3a4f535677f7f28f77fd43d70597cec0507 100644
--- a/third_party/rust/futures/tests/stream_peekable.rs
+++ b/third_party/rust/futures/tests/stream_peekable.rs
@@ -1,9 +1,9 @@
+use futures::executor::block_on;
+use futures::pin_mut;
+use futures::stream::{self, Peekable, StreamExt};
+
 #[test]
 fn peekable() {
-    use futures::executor::block_on;
-    use futures::pin_mut;
-    use futures::stream::{self, Peekable, StreamExt};
-
     block_on(async {
         let peekable: Peekable<_> = stream::iter(vec![1u8, 2, 3]).peekable();
         pin_mut!(peekable);
@@ -11,3 +11,29 @@ fn peekable() {
         assert_eq!(peekable.collect::<Vec<u8>>().await, vec![1, 2, 3]);
     });
 }
+
+#[test]
+fn peekable_next_if_eq() {
+    block_on(async {
+        // first, try on references
+        let s = stream::iter(vec!["Heart", "of", "Gold"]).peekable();
+        pin_mut!(s);
+        // try before `peek()`
+        assert_eq!(s.as_mut().next_if_eq(&"trillian").await, None);
+        assert_eq!(s.as_mut().next_if_eq(&"Heart").await, Some("Heart"));
+        // try after peek()
+        assert_eq!(s.as_mut().peek().await, Some(&"of"));
+        assert_eq!(s.as_mut().next_if_eq(&"of").await, Some("of"));
+        assert_eq!(s.as_mut().next_if_eq(&"zaphod").await, None);
+        // make sure `next()` still behaves
+        assert_eq!(s.next().await, Some("Gold"));
+
+        // make sure comparison works for owned values
+        let s = stream::iter(vec![String::from("Ludicrous"), "speed".into()]).peekable();
+        pin_mut!(s);
+        // make sure basic functionality works
+        assert_eq!(s.as_mut().next_if_eq("Ludicrous").await, Some("Ludicrous".into()));
+        assert_eq!(s.as_mut().next_if_eq("speed").await, Some("speed".into()));
+        assert_eq!(s.as_mut().next_if_eq("").await, None);
+    });
+}
diff --git a/third_party/rust/futures/tests/stream_select_all.rs b/third_party/rust/futures/tests/stream_select_all.rs
index 6178412f4dcec08abf686e60b2dc4ce1b51cbebe..4ae0735762cad32b3a9691984b779197f2a1c761 100644
--- a/third_party/rust/futures/tests/stream_select_all.rs
+++ b/third_party/rust/futures/tests/stream_select_all.rs
@@ -1,10 +1,12 @@
+use futures::channel::mpsc;
+use futures::executor::{block_on, block_on_stream};
+use futures::future::{self, FutureExt};
+use futures::stream::{self, select_all, FusedStream, SelectAll, StreamExt};
+use futures::task::Poll;
+use futures_test::task::noop_context;
+
 #[test]
 fn is_terminated() {
-    use futures::future::{self, FutureExt};
-    use futures::stream::{FusedStream, SelectAll, StreamExt};
-    use futures::task::Poll;
-    use futures_test::task::noop_context;
-
     let mut cx = noop_context();
     let mut tasks = SelectAll::new();
 
@@ -30,9 +32,6 @@ fn is_terminated() {
 
 #[test]
 fn issue_1626() {
-    use futures::executor::block_on_stream;
-    use futures::stream;
-
     let a = stream::iter(0..=2);
     let b = stream::iter(10..=14);
 
@@ -51,10 +50,6 @@ fn issue_1626() {
 
 #[test]
 fn works_1() {
-    use futures::channel::mpsc;
-    use futures::executor::block_on_stream;
-    use futures::stream::select_all;
-
     let (a_tx, a_rx) = mpsc::unbounded::<u32>();
     let (b_tx, b_rx) = mpsc::unbounded::<u32>();
     let (c_tx, c_rx) = mpsc::unbounded::<u32>();
@@ -81,3 +76,122 @@ fn works_1() {
     drop((a_tx, b_tx, c_tx));
     assert_eq!(None, stream.next());
 }
+
+#[test]
+fn clear() {
+    let mut tasks =
+        select_all(vec![stream::iter(vec![1].into_iter()), stream::iter(vec![2].into_iter())]);
+
+    assert_eq!(block_on(tasks.next()), Some(1));
+    assert!(!tasks.is_empty());
+
+    tasks.clear();
+    assert!(tasks.is_empty());
+
+    tasks.push(stream::iter(vec![3].into_iter()));
+    assert!(!tasks.is_empty());
+
+    tasks.clear();
+    assert!(tasks.is_empty());
+
+    assert_eq!(block_on(tasks.next()), None);
+    assert!(tasks.is_terminated());
+    tasks.clear();
+    assert!(!tasks.is_terminated());
+}
+
+#[test]
+fn iter_mut() {
+    let mut stream =
+        vec![stream::pending::<()>(), stream::pending::<()>(), stream::pending::<()>()]
+            .into_iter()
+            .collect::<SelectAll<_>>();
+
+    let mut iter = stream.iter_mut();
+    assert_eq!(iter.len(), 3);
+    assert!(iter.next().is_some());
+    assert_eq!(iter.len(), 2);
+    assert!(iter.next().is_some());
+    assert_eq!(iter.len(), 1);
+    assert!(iter.next().is_some());
+    assert_eq!(iter.len(), 0);
+    assert!(iter.next().is_none());
+
+    let mut stream = vec![stream::iter(vec![]), stream::iter(vec![1]), stream::iter(vec![2])]
+        .into_iter()
+        .collect::<SelectAll<_>>();
+
+    assert_eq!(stream.len(), 3);
+    assert_eq!(block_on(stream.next()), Some(1));
+    assert_eq!(stream.len(), 2);
+    let mut iter = stream.iter_mut();
+    assert_eq!(iter.len(), 2);
+    assert!(iter.next().is_some());
+    assert_eq!(iter.len(), 1);
+    assert!(iter.next().is_some());
+    assert_eq!(iter.len(), 0);
+    assert!(iter.next().is_none());
+
+    assert_eq!(block_on(stream.next()), Some(2));
+    assert_eq!(stream.len(), 2);
+    assert_eq!(block_on(stream.next()), None);
+    let mut iter = stream.iter_mut();
+    assert_eq!(iter.len(), 0);
+    assert!(iter.next().is_none());
+}
+
+#[test]
+fn iter() {
+    let stream = vec![stream::pending::<()>(), stream::pending::<()>(), stream::pending::<()>()]
+        .into_iter()
+        .collect::<SelectAll<_>>();
+
+    let mut iter = stream.iter();
+    assert_eq!(iter.len(), 3);
+    assert!(iter.next().is_some());
+    assert_eq!(iter.len(), 2);
+    assert!(iter.next().is_some());
+    assert_eq!(iter.len(), 1);
+    assert!(iter.next().is_some());
+    assert_eq!(iter.len(), 0);
+    assert!(iter.next().is_none());
+
+    let mut stream = vec![stream::iter(vec![]), stream::iter(vec![1]), stream::iter(vec![2])]
+        .into_iter()
+        .collect::<SelectAll<_>>();
+
+    assert_eq!(stream.len(), 3);
+    assert_eq!(block_on(stream.next()), Some(1));
+    assert_eq!(stream.len(), 2);
+    let mut iter = stream.iter();
+    assert_eq!(iter.len(), 2);
+    assert!(iter.next().is_some());
+    assert_eq!(iter.len(), 1);
+    assert!(iter.next().is_some());
+    assert_eq!(iter.len(), 0);
+    assert!(iter.next().is_none());
+
+    assert_eq!(block_on(stream.next()), Some(2));
+    assert_eq!(stream.len(), 2);
+    assert_eq!(block_on(stream.next()), None);
+    let mut iter = stream.iter();
+    assert_eq!(iter.len(), 0);
+    assert!(iter.next().is_none());
+}
+
+#[test]
+fn into_iter() {
+    let stream = vec![stream::pending::<()>(), stream::pending::<()>(), stream::pending::<()>()]
+        .into_iter()
+        .collect::<SelectAll<_>>();
+
+    let mut iter = stream.into_iter();
+    assert_eq!(iter.len(), 3);
+    assert!(iter.next().is_some());
+    assert_eq!(iter.len(), 2);
+    assert!(iter.next().is_some());
+    assert_eq!(iter.len(), 1);
+    assert!(iter.next().is_some());
+    assert_eq!(iter.len(), 0);
+    assert!(iter.next().is_none());
+}
diff --git a/third_party/rust/futures/tests/stream_select_next_some.rs b/third_party/rust/futures/tests/stream_select_next_some.rs
index bec5262c1de1a541869a6aacb2836874d544ba86..8252ad7b543c6321c826c868eba3b489d2354d84 100644
--- a/third_party/rust/futures/tests/stream_select_next_some.rs
+++ b/third_party/rust/futures/tests/stream_select_next_some.rs
@@ -1,11 +1,13 @@
+use futures::executor::block_on;
+use futures::future::{self, FusedFuture, FutureExt};
+use futures::select;
+use futures::stream::{FuturesUnordered, StreamExt};
+use futures::task::{Context, Poll};
+use futures_test::future::FutureTestExt;
+use futures_test::task::new_count_waker;
+
 #[test]
 fn is_terminated() {
-    use futures::future;
-    use futures::future::{FusedFuture, FutureExt};
-    use futures::stream::{FuturesUnordered, StreamExt};
-    use futures::task::{Context, Poll};
-    use futures_test::task::new_count_waker;
-
     let (waker, counter) = new_count_waker();
     let mut cx = Context::from_waker(&waker);
 
@@ -30,15 +32,11 @@ fn is_terminated() {
 
 #[test]
 fn select() {
-    use futures::{future, select};
-    use futures::stream::{FuturesUnordered, StreamExt};
-    use futures_test::future::FutureTestExt;
-
     // Checks that even though `async_tasks` will yield a `None` and return
     // `is_terminated() == true` during the first poll, it manages to toggle
     // back to having items after a future is pushed into it during the second
     // poll (after pending_once completes).
-    futures::executor::block_on(async {
+    block_on(async {
         let mut fut = future::ready(1).pending_once();
         let mut async_tasks = FuturesUnordered::new();
         let mut total = 0;
@@ -61,17 +59,13 @@ fn select() {
 // Check that `select!` macro does not fail when importing from `futures_util`.
 #[test]
 fn futures_util_select() {
-    use futures::future;
-    use futures::stream::{FuturesUnordered, StreamExt};
-    use futures_test::future::FutureTestExt;
-
     use futures_util::select;
 
     // Checks that even though `async_tasks` will yield a `None` and return
     // `is_terminated() == true` during the first poll, it manages to toggle
     // back to having items after a future is pushed into it during the second
     // poll (after pending_once completes).
-    futures::executor::block_on(async {
+    block_on(async {
         let mut fut = future::ready(1).pending_once();
         let mut async_tasks = FuturesUnordered::new();
         let mut total = 0;
diff --git a/third_party/rust/futures/tests/stream_split.rs b/third_party/rust/futures/tests/stream_split.rs
new file mode 100644
index 0000000000000000000000000000000000000000..694c151807b8929d2b453379880854cffe51d15a
--- /dev/null
+++ b/third_party/rust/futures/tests/stream_split.rs
@@ -0,0 +1,57 @@
+use futures::executor::block_on;
+use futures::sink::{Sink, SinkExt};
+use futures::stream::{self, Stream, StreamExt};
+use futures::task::{Context, Poll};
+use pin_project::pin_project;
+use std::pin::Pin;
+
+#[test]
+fn test_split() {
+    #[pin_project]
+    struct Join<T, U> {
+        #[pin]
+        stream: T,
+        #[pin]
+        sink: U,
+    }
+
+    impl<T: Stream, U> Stream for Join<T, U> {
+        type Item = T::Item;
+
+        fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<T::Item>> {
+            self.project().stream.poll_next(cx)
+        }
+    }
+
+    impl<T, U: Sink<Item>, Item> Sink<Item> for Join<T, U> {
+        type Error = U::Error;
+
+        fn poll_ready(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
+            self.project().sink.poll_ready(cx)
+        }
+
+        fn start_send(self: Pin<&mut Self>, item: Item) -> Result<(), Self::Error> {
+            self.project().sink.start_send(item)
+        }
+
+        fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
+            self.project().sink.poll_flush(cx)
+        }
+
+        fn poll_close(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
+            self.project().sink.poll_close(cx)
+        }
+    }
+
+    let mut dest: Vec<i32> = Vec::new();
+    {
+        let join = Join { stream: stream::iter(vec![10, 20, 30]), sink: &mut dest };
+
+        let (sink, stream) = join.split();
+        let join = sink.reunite(stream).expect("test_split: reunite error");
+        let (mut sink, stream) = join.split();
+        let mut stream = stream.map(Ok);
+        block_on(sink.send_all(&mut stream)).unwrap();
+    }
+    assert_eq!(dest, vec![10, 20, 30]);
+}
diff --git a/third_party/rust/futures/tests/try_stream.rs b/third_party/rust/futures/tests/stream_try_stream.rs
similarity index 100%
rename from third_party/rust/futures/tests/try_stream.rs
rename to third_party/rust/futures/tests/stream_try_stream.rs
diff --git a/third_party/rust/futures/tests/unfold.rs b/third_party/rust/futures/tests/stream_unfold.rs
similarity index 89%
rename from third_party/rust/futures/tests/unfold.rs
rename to third_party/rust/futures/tests/stream_unfold.rs
index 95722cf8a634aa7f5894d31eba6c87f59a52198e..16b10813b131483afe1042b0be624c672522faff 100644
--- a/third_party/rust/futures/tests/unfold.rs
+++ b/third_party/rust/futures/tests/stream_unfold.rs
@@ -1,10 +1,7 @@
 use futures::future;
 use futures::stream;
-
 use futures_test::future::FutureTestExt;
-use futures_test::{
-    assert_stream_done, assert_stream_next, assert_stream_pending,
-};
+use futures_test::{assert_stream_done, assert_stream_next, assert_stream_pending};
 
 #[test]
 fn unfold1() {
diff --git a/third_party/rust/futures/tests/task_arc_wake.rs b/third_party/rust/futures/tests/task_arc_wake.rs
new file mode 100644
index 0000000000000000000000000000000000000000..aedc15bcb82f7c90886d32fb718dc98f2be9623f
--- /dev/null
+++ b/third_party/rust/futures/tests/task_arc_wake.rs
@@ -0,0 +1,79 @@
+use futures::task::{self, ArcWake, Waker};
+use std::panic;
+use std::sync::{Arc, Mutex};
+
+struct CountingWaker {
+    nr_wake: Mutex<i32>,
+}
+
+impl CountingWaker {
+    fn new() -> Self {
+        Self { nr_wake: Mutex::new(0) }
+    }
+
+    fn wakes(&self) -> i32 {
+        *self.nr_wake.lock().unwrap()
+    }
+}
+
+impl ArcWake for CountingWaker {
+    fn wake_by_ref(arc_self: &Arc<Self>) {
+        let mut lock = arc_self.nr_wake.lock().unwrap();
+        *lock += 1;
+    }
+}
+
+#[test]
+fn create_from_arc() {
+    let some_w = Arc::new(CountingWaker::new());
+
+    let w1: Waker = task::waker(some_w.clone());
+    assert_eq!(2, Arc::strong_count(&some_w));
+    w1.wake_by_ref();
+    assert_eq!(1, some_w.wakes());
+
+    let w2 = w1.clone();
+    assert_eq!(3, Arc::strong_count(&some_w));
+
+    w2.wake_by_ref();
+    assert_eq!(2, some_w.wakes());
+
+    drop(w2);
+    assert_eq!(2, Arc::strong_count(&some_w));
+    drop(w1);
+    assert_eq!(1, Arc::strong_count(&some_w));
+}
+
+#[test]
+fn ref_wake_same() {
+    let some_w = Arc::new(CountingWaker::new());
+
+    let w1: Waker = task::waker(some_w.clone());
+    let w2 = task::waker_ref(&some_w);
+    let w3 = w2.clone();
+
+    assert!(w1.will_wake(&w2));
+    assert!(w2.will_wake(&w3));
+}
+
+#[test]
+fn proper_refcount_on_wake_panic() {
+    struct PanicWaker;
+
+    impl ArcWake for PanicWaker {
+        fn wake_by_ref(_arc_self: &Arc<Self>) {
+            panic!("WAKE UP");
+        }
+    }
+
+    let some_w = Arc::new(PanicWaker);
+
+    let w1: Waker = task::waker(some_w.clone());
+    assert_eq!(
+        "WAKE UP",
+        *panic::catch_unwind(|| w1.wake_by_ref()).unwrap_err().downcast::<&str>().unwrap()
+    );
+    assert_eq!(2, Arc::strong_count(&some_w)); // some_w + w1
+    drop(w1);
+    assert_eq!(1, Arc::strong_count(&some_w)); // some_w
+}
diff --git a/third_party/rust/futures/tests/atomic_waker.rs b/third_party/rust/futures/tests/task_atomic_waker.rs
similarity index 82%
rename from third_party/rust/futures/tests/atomic_waker.rs
rename to third_party/rust/futures/tests/task_atomic_waker.rs
index bf15d0f0c70a0b09d5ee1e9b561cf5eb2832ee7c..cec3db2876517d7f2584ed494119f84eb8bada86 100644
--- a/third_party/rust/futures/tests/atomic_waker.rs
+++ b/third_party/rust/futures/tests/task_atomic_waker.rs
@@ -1,14 +1,13 @@
+use futures::executor::block_on;
+use futures::future::poll_fn;
+use futures::task::{AtomicWaker, Poll};
+use std::sync::atomic::AtomicUsize;
+use std::sync::atomic::Ordering;
+use std::sync::Arc;
+use std::thread;
+
 #[test]
 fn basic() {
-    use std::sync::atomic::AtomicUsize;
-    use std::sync::atomic::Ordering;
-    use std::sync::Arc;
-    use std::thread;
-
-    use futures::executor::block_on;
-    use futures::future::poll_fn;
-    use futures::task::{AtomicWaker, Poll};
-
     let atomic_waker = Arc::new(AtomicWaker::new());
     let atomic_waker_copy = atomic_waker.clone();
 
diff --git a/third_party/rust/futures/tests/test_macro.rs b/third_party/rust/futures/tests/test_macro.rs
new file mode 100644
index 0000000000000000000000000000000000000000..6adf51d8bb55ee5c0f483d73a652cce03403b45f
--- /dev/null
+++ b/third_party/rust/futures/tests/test_macro.rs
@@ -0,0 +1,20 @@
+#[futures_test::test]
+async fn it_works() {
+    let fut = async { true };
+    assert!(fut.await);
+
+    let fut = async { false };
+    assert!(!fut.await);
+}
+
+#[should_panic]
+#[futures_test::test]
+async fn it_is_being_run() {
+    let fut = async { false };
+    assert!(fut.await);
+}
+
+#[futures_test::test]
+async fn return_ty() -> Result<(), ()> {
+    Ok(())
+}
diff --git a/third_party/rust/futures/tests/try_join.rs b/third_party/rust/futures/tests/try_join.rs
index 6c6d0843d573963158273d643ef000a7d3276733..8b0b38c1a359713a3daf9f429a030941aaafd2bf 100644
--- a/third_party/rust/futures/tests/try_join.rs
+++ b/third_party/rust/futures/tests/try_join.rs
@@ -1,6 +1,6 @@
 #![deny(unreachable_code)]
 
-use futures::{try_join, executor::block_on};
+use futures::{executor::block_on, try_join};
 
 // TODO: This abuses https://github.com/rust-lang/rust/issues/58733 in order to
 // test behaviour of the `try_join!` macro with the never type before it is
@@ -14,7 +14,6 @@ impl<T> MyTrait for fn() -> T {
 }
 type Never = <fn() -> ! as MyTrait>::Output;
 
-
 #[test]
 fn try_join_never_error() {
     block_on(async {
diff --git a/third_party/rust/futures/tests_disabled/all.rs b/third_party/rust/futures/tests_disabled/all.rs
index 6c7e11cf7b366f9f8be125e605fed3ee4c79c9cf..a7a571040a3fa2b89ea651d0670abfd1914add64 100644
--- a/third_party/rust/futures/tests_disabled/all.rs
+++ b/third_party/rust/futures/tests_disabled/all.rs
@@ -1,27 +1,27 @@
-use futures::future;
-use futures::executor::block_on;
 use futures::channel::oneshot::{self, Canceled};
+use futures::executor::block_on;
+use futures::future;
 use std::sync::mpsc::{channel, TryRecvError};
 
-mod support;
-use support::*;
+// mod support;
+// use support::*;
 
 fn unselect<T, E, A, B>(r: Result<Either<(T, B), (T, A)>, Either<(E, B), (E, A)>>) -> Result<T, E> {
     match r {
-        Ok(Either::Left((t, _))) |
-        Ok(Either::Right((t, _))) => Ok(t),
-        Err(Either::Left((e, _))) |
-        Err(Either::Right((e, _))) => Err(e),
+        Ok(Either::Left((t, _))) | Ok(Either::Right((t, _))) => Ok(t),
+        Err(Either::Left((e, _))) | Err(Either::Right((e, _))) => Err(e),
     }
 }
 
 #[test]
 fn result_smoke() {
     fn is_future_v<A, B, C>(_: C)
-        where A: Send + 'static,
-              B: Send + 'static,
-              C: Future<Item=A, Error=B>
-    {}
+    where
+        A: Send + 'static,
+        B: Send + 'static,
+        C: Future<Item = A, Error = B>,
+    {
+    }
 
     is_future_v::<i32, u32, _>(f_ok(1).map(|a| a + 1));
     is_future_v::<i32, u32, _>(f_ok(1).map_err(|a| a + 1));
@@ -64,7 +64,9 @@ fn result_smoke() {
 
 #[test]
 fn test_empty() {
-    fn empty() -> Empty<i32, u32> { future::empty() }
+    fn empty() -> Empty<i32, u32> {
+        future::empty()
+    }
 
     assert_empty(|| empty());
     assert_empty(|| empty().select(empty()));
@@ -105,16 +107,22 @@ fn flatten() {
 
 #[test]
 fn smoke_oneshot() {
-    assert_done(|| {
-        let (c, p) = oneshot::channel();
-        c.send(1).unwrap();
-        p
-    }, Ok(1));
-    assert_done(|| {
-        let (c, p) = oneshot::channel::<i32>();
-        drop(c);
-        p
-    }, Err(Canceled));
+    assert_done(
+        || {
+            let (c, p) = oneshot::channel();
+            c.send(1).unwrap();
+            p
+        },
+        Ok(1),
+    );
+    assert_done(
+        || {
+            let (c, p) = oneshot::channel::<i32>();
+            drop(c);
+            p
+        },
+        Err(Canceled),
+    );
     let mut completes = Vec::new();
     assert_empty(|| {
         let (a, b) = oneshot::channel::<i32>();
@@ -129,9 +137,7 @@ fn smoke_oneshot() {
     let (c, p) = oneshot::channel::<i32>();
     drop(c);
     let (tx, rx) = channel();
-    p.then(move |_| {
-        tx.send(())
-    }).forget();
+    p.then(move |_| tx.send(())).forget();
     rx.recv().unwrap();
 }
 
@@ -139,8 +145,14 @@ fn smoke_oneshot() {
 fn select_cancels() {
     let ((a, b), (c, d)) = (oneshot::channel::<i32>(), oneshot::channel::<i32>());
     let ((btx, brx), (dtx, drx)) = (channel(), channel());
-    let b = b.map(move |b| { btx.send(b).unwrap(); b });
-    let d = d.map(move |d| { dtx.send(d).unwrap(); d });
+    let b = b.map(move |b| {
+        btx.send(b).unwrap();
+        b
+    });
+    let d = d.map(move |d| {
+        dtx.send(d).unwrap();
+        d
+    });
 
     let mut f = b.select(d).then(unselect);
     // assert!(f.poll(&mut Task::new()).is_pending());
@@ -156,8 +168,14 @@ fn select_cancels() {
 
         let ((a, b), (c, d)) = (oneshot::channel::<i32>(), oneshot::channel::<i32>());
         let ((btx, _brx), (dtx, drx)) = (channel(), channel());
-        let b = b.map(move |b| { btx.send(b).unwrap(); b });
-        let d = d.map(move |d| { dtx.send(d).unwrap(); d });
+        let b = b.map(move |b| {
+            btx.send(b).unwrap();
+            b
+        });
+        let d = d.map(move |d| {
+            dtx.send(d).unwrap();
+            d
+        });
 
         let mut f = b.select(d).then(unselect);
         assert!(f.poll(lw).ok().unwrap().is_pending());
@@ -173,8 +191,14 @@ fn select_cancels() {
 fn join_cancels() {
     let ((a, b), (c, d)) = (oneshot::channel::<i32>(), oneshot::channel::<i32>());
     let ((btx, _brx), (dtx, drx)) = (channel(), channel());
-    let b = b.map(move |b| { btx.send(b).unwrap(); b });
-    let d = d.map(move |d| { dtx.send(d).unwrap(); d });
+    let b = b.map(move |b| {
+        btx.send(b).unwrap();
+        b
+    });
+    let d = d.map(move |d| {
+        dtx.send(d).unwrap();
+        d
+    });
 
     let mut f = b.join(d);
     drop(a);
@@ -185,8 +209,14 @@ fn join_cancels() {
 
     let ((a, b), (c, d)) = (oneshot::channel::<i32>(), oneshot::channel::<i32>());
     let ((btx, _brx), (dtx, drx)) = (channel(), channel());
-    let b = b.map(move |b| { btx.send(b).unwrap(); b });
-    let d = d.map(move |d| { dtx.send(d).unwrap(); d });
+    let b = b.map(move |b| {
+        btx.send(b).unwrap();
+        b
+    });
+    let d = d.map(move |d| {
+        dtx.send(d).unwrap();
+        d
+    });
 
     let (tx, rx) = channel();
     let f = b.join(d);
@@ -194,7 +224,8 @@ fn join_cancels() {
         tx.send(()).unwrap();
         let res: Result<(), ()> = Ok(());
         res
-    }).forget();
+    })
+    .forget();
     assert!(rx.try_recv().is_err());
     drop(a);
     rx.recv().unwrap();
@@ -243,7 +274,6 @@ fn join_incomplete() {
     })
 }
 
-
 #[test]
 fn select2() {
     assert_done(|| f_ok(2).select(empty()).then(unselect), Ok(2));
@@ -251,14 +281,15 @@ fn select2() {
     assert_done(|| f_err(2).select(empty()).then(unselect), Err(2));
     assert_done(|| empty().select(f_err(2)).then(unselect), Err(2));
 
-    assert_done(|| {
-        f_ok(1).select(f_ok(2))
-               .map_err(|_| 0)
-               .and_then(|either_tup| {
-                   let (a, b) = either_tup.into_inner();
-                   b.map(move |b| a + b)
-               })
-    }, Ok(3));
+    assert_done(
+        || {
+            f_ok(1).select(f_ok(2)).map_err(|_| 0).and_then(|either_tup| {
+                let (a, b) = either_tup.into_inner();
+                b.map(move |b| a + b)
+            })
+        },
+        Ok(3),
+    );
 
     // Finish one half of a select and then fail the second, ensuring that we
     // get the notification of the second one.
@@ -297,8 +328,14 @@ fn select2() {
     {
         let ((_a, b), (_c, d)) = (oneshot::channel::<i32>(), oneshot::channel::<i32>());
         let ((btx, brx), (dtx, drx)) = (channel(), channel());
-        let b = b.map(move |v| { btx.send(v).unwrap(); v });
-        let d = d.map(move |v| { dtx.send(v).unwrap(); v });
+        let b = b.map(move |v| {
+            btx.send(v).unwrap();
+            v
+        });
+        let d = d.map(move |v| {
+            dtx.send(v).unwrap();
+            v
+        });
         let f = b.select(d);
         drop(f);
         assert!(drx.recv().is_err());
@@ -309,8 +346,14 @@ fn select2() {
     {
         let ((_a, b), (_c, d)) = (oneshot::channel::<i32>(), oneshot::channel::<i32>());
         let ((btx, brx), (dtx, drx)) = (channel(), channel());
-        let b = b.map(move |v| { btx.send(v).unwrap(); v });
-        let d = d.map(move |v| { dtx.send(v).unwrap(); v });
+        let b = b.map(move |v| {
+            btx.send(v).unwrap();
+            v
+        });
+        let d = d.map(move |v| {
+            dtx.send(v).unwrap();
+            v
+        });
         let mut f = b.select(d);
         let _res = noop_waker_lw(|lw| f.poll(lw));
         drop(f);
@@ -322,8 +365,14 @@ fn select2() {
     {
         let ((a, b), (_c, d)) = (oneshot::channel::<i32>(), oneshot::channel::<i32>());
         let ((btx, brx), (dtx, drx)) = (channel(), channel());
-        let b = b.map(move |v| { btx.send(v).unwrap(); v });
-        let d = d.map(move |v| { dtx.send(v).unwrap(); v });
+        let b = b.map(move |v| {
+            btx.send(v).unwrap();
+            v
+        });
+        let d = d.map(move |v| {
+            dtx.send(v).unwrap();
+            v
+        });
         let (tx, rx) = channel();
         b.select(d).map(move |_| tx.send(()).unwrap()).forget();
         drop(a);
diff --git a/third_party/rust/futures/tests_disabled/bilock.rs b/third_party/rust/futures/tests_disabled/bilock.rs
index c1bc33f507f1e37fc2a4e5e2341f8ca6f0ffacee..0166ca48bad9e80b4e72e76e2e9deb42f81ca313 100644
--- a/third_party/rust/futures/tests_disabled/bilock.rs
+++ b/third_party/rust/futures/tests_disabled/bilock.rs
@@ -1,11 +1,11 @@
-use futures::task;
-use futures::stream;
 use futures::future;
+use futures::stream;
+use futures::task;
 use futures_util::lock::BiLock;
 use std::thread;
 
-mod support;
-use support::*;
+// mod support;
+// use support::*;
 
 #[test]
 fn smoke() {
@@ -41,9 +41,9 @@ fn smoke() {
     });
 
     assert!(task::spawn(future)
-                .poll_future_notify(&notify_noop(), 0)
-                .expect("failure in poll")
-                .is_ready());
+        .poll_future_notify(&notify_noop(), 0)
+        .expect("failure in poll")
+        .is_ready());
 }
 
 #[test]
@@ -51,10 +51,7 @@ fn concurrent() {
     const N: usize = 10000;
     let (a, b) = BiLock::new(0);
 
-    let a = Increment {
-        a: Some(a),
-        remaining: N,
-    };
+    let a = Increment { a: Some(a), remaining: N };
     let b = stream::iter_ok(0..N).fold(b, |b, _n| {
         b.lock().map(|mut b| {
             *b += 1;
@@ -89,7 +86,7 @@ fn concurrent() {
         fn poll(&mut self) -> Poll<BiLock<usize>, ()> {
             loop {
                 if self.remaining == 0 {
-                    return Ok(self.a.take().unwrap().into())
+                    return Ok(self.a.take().unwrap().into());
                 }
 
                 let a = self.a.as_ref().unwrap();
diff --git a/third_party/rust/futures/tests_disabled/stream.rs b/third_party/rust/futures/tests_disabled/stream.rs
index ef0676db35a25dc25672fbb6775f019e6ec60a43..854dbad829745475a03d2598f2cb3bd306e1d4bf 100644
--- a/third_party/rust/futures/tests_disabled/stream.rs
+++ b/third_party/rust/futures/tests_disabled/stream.rs
@@ -1,26 +1,26 @@
+use futures::channel::mpsc;
+use futures::channel::oneshot;
 use futures::executor::{block_on, block_on_stream};
 use futures::future::{err, ok};
 use futures::stream::{empty, iter_ok, poll_fn, Peekable};
-use futures::channel::oneshot;
-use futures::channel::mpsc;
 
-mod support;
-use support::*;
+// mod support;
+// use support::*;
 
 pub struct Iter<I> {
     iter: I,
 }
 
 pub fn iter<J, T, E>(i: J) -> Iter<J::IntoIter>
-    where J: IntoIterator<Item=Result<T, E>>,
+where
+    J: IntoIterator<Item = Result<T, E>>,
 {
-    Iter {
-        iter: i.into_iter(),
-    }
+    Iter { iter: i.into_iter() }
 }
 
 impl<I, T, E> Stream for Iter<I>
-    where I: Iterator<Item=Result<T, E>>,
+where
+    I: Iterator<Item = Result<T, E>>,
 {
     type Item = T;
     type Error = E;
@@ -34,21 +34,15 @@ impl<I, T, E> Stream for Iter<I>
     }
 }
 
-fn list() -> Box<Stream<Item=i32, Error=u32> + Send> {
+fn list() -> Box<Stream<Item = i32, Error = u32> + Send> {
     let (tx, rx) = mpsc::channel(1);
-    tx.send(Ok(1))
-      .and_then(|tx| tx.send(Ok(2)))
-      .and_then(|tx| tx.send(Ok(3)))
-      .forget();
+    tx.send(Ok(1)).and_then(|tx| tx.send(Ok(2))).and_then(|tx| tx.send(Ok(3))).forget();
     Box::new(rx.then(|r| r.unwrap()))
 }
 
-fn err_list() -> Box<Stream<Item=i32, Error=u32> + Send> {
+fn err_list() -> Box<Stream<Item = i32, Error = u32> + Send> {
     let (tx, rx) = mpsc::channel(1);
-    tx.send(Ok(1))
-      .and_then(|tx| tx.send(Ok(2)))
-      .and_then(|tx| tx.send(Err(3)))
-      .forget();
+    tx.send(Ok(1)).and_then(|tx| tx.send(Ok(2))).and_then(|tx| tx.send(Err(3))).forget();
     Box::new(rx.then(|r| r.unwrap()))
 }
 
@@ -89,40 +83,31 @@ fn filter() {
 
 #[test]
 fn filter_map() {
-    assert_done(|| list().filter_map(|x| {
-        ok(if x % 2 == 0 {
-            Some(x + 10)
-        } else {
-            None
-        })
-    }).collect(), Ok(vec![12]));
+    assert_done(
+        || list().filter_map(|x| ok(if x % 2 == 0 { Some(x + 10) } else { None })).collect(),
+        Ok(vec![12]),
+    );
 }
 
 #[test]
 fn and_then() {
     assert_done(|| list().and_then(|a| Ok(a + 1)).collect(), Ok(vec![2, 3, 4]));
-    assert_done(|| list().and_then(|a| err::<i32, u32>(a as u32)).collect::<Vec<_>>(),
-                Err(1));
+    assert_done(|| list().and_then(|a| err::<i32, u32>(a as u32)).collect::<Vec<_>>(), Err(1));
 }
 
 #[test]
 fn then() {
     assert_done(|| list().then(|a| a.map(|e| e + 1)).collect(), Ok(vec![2, 3, 4]));
-
 }
 
 #[test]
 fn or_else() {
-    assert_done(|| err_list().or_else(|a| {
-        ok::<i32, u32>(a as i32)
-    }).collect(), Ok(vec![1, 2, 3]));
+    assert_done(|| err_list().or_else(|a| ok::<i32, u32>(a as i32)).collect(), Ok(vec![1, 2, 3]));
 }
 
 #[test]
 fn flatten() {
-    assert_done(|| list().map(|_| list()).flatten().collect(),
-                Ok(vec![1, 2, 3, 1, 2, 3, 1, 2, 3]));
-
+    assert_done(|| list().map(|_| list()).flatten().collect(), Ok(vec![1, 2, 3, 1, 2, 3, 1, 2, 3]));
 }
 
 #[test]
@@ -132,9 +117,7 @@ fn skip() {
 
 #[test]
 fn skip_passes_errors_through() {
-    let mut s = block_on_stream(
-        iter(vec![Err(1), Err(2), Ok(3), Ok(4), Ok(5)]).skip(1)
-    );
+    let mut s = block_on_stream(iter(vec![Err(1), Err(2), Ok(3), Ok(4), Ok(5)]).skip(1));
     assert_eq!(s.next(), Some(Err(1)));
     assert_eq!(s.next(), Some(Err(2)));
     assert_eq!(s.next(), Some(Ok(4)));
@@ -144,8 +127,7 @@ fn skip_passes_errors_through() {
 
 #[test]
 fn skip_while() {
-    assert_done(|| list().skip_while(|e| Ok(*e % 2 == 1)).collect(),
-                Ok(vec![2, 3]));
+    assert_done(|| list().skip_while(|e| Ok(*e % 2 == 1)).collect(), Ok(vec![2, 3]));
 }
 #[test]
 fn take() {
@@ -154,8 +136,7 @@ fn take() {
 
 #[test]
 fn take_while() {
-    assert_done(|| list().take_while(|e| Ok(*e < 3)).collect(),
-                Ok(vec![1, 2]));
+    assert_done(|| list().take_while(|e| Ok(*e < 3)).collect(), Ok(vec![1, 2]));
 }
 
 #[test]
@@ -193,9 +174,9 @@ fn buffered() {
     let (a, b) = oneshot::channel::<u32>();
     let (c, d) = oneshot::channel::<u32>();
 
-    tx.send(Box::new(b.recover(|_| panic!())) as Box<Future<Item=_, Error=_> + Send>)
-      .and_then(|tx| tx.send(Box::new(d.map_err(|_| panic!()))))
-      .forget();
+    tx.send(Box::new(b.recover(|_| panic!())) as Box<Future<Item = _, Error = _> + Send>)
+        .and_then(|tx| tx.send(Box::new(d.map_err(|_| panic!()))))
+        .forget();
 
     let mut rx = rx.buffered(2);
     sassert_empty(&mut rx);
@@ -211,9 +192,9 @@ fn buffered() {
     let (a, b) = oneshot::channel::<u32>();
     let (c, d) = oneshot::channel::<u32>();
 
-    tx.send(Box::new(b.recover(|_| panic!())) as Box<Future<Item=_, Error=_> + Send>)
-      .and_then(|tx| tx.send(Box::new(d.map_err(|_| panic!()))))
-      .forget();
+    tx.send(Box::new(b.recover(|_| panic!())) as Box<Future<Item = _, Error = _> + Send>)
+        .and_then(|tx| tx.send(Box::new(d.map_err(|_| panic!()))))
+        .forget();
 
     let mut rx = rx.buffered(1);
     sassert_empty(&mut rx);
@@ -233,8 +214,8 @@ fn unordered() {
     let (c, d) = oneshot::channel::<u32>();
 
     tx.send(Box::new(b.recover(|_| panic!())) as Box<Future<Item = _, Error = _> + Send>)
-      .and_then(|tx| tx.send(Box::new(d.recover(|_| panic!()))))
-      .forget();
+        .and_then(|tx| tx.send(Box::new(d.recover(|_| panic!()))))
+        .forget();
 
     let mut rx = rx.buffer_unordered(2);
     sassert_empty(&mut rx);
@@ -250,8 +231,8 @@ fn unordered() {
     let (c, d) = oneshot::channel::<u32>();
 
     tx.send(Box::new(b.recover(|_| panic!())) as Box<Future<Item = _, Error = _> + Send>)
-      .and_then(|tx| tx.send(Box::new(d.recover(|_| panic!()))))
-      .forget();
+        .and_then(|tx| tx.send(Box::new(d.recover(|_| panic!()))))
+        .forget();
 
     // We don't even get to see `c` until `a` completes.
     let mut rx = rx.buffer_unordered(1);
@@ -267,21 +248,17 @@ fn unordered() {
 
 #[test]
 fn zip() {
-    assert_done(|| list().zip(list()).collect(),
-                Ok(vec![(1, 1), (2, 2), (3, 3)]));
-    assert_done(|| list().zip(list().take(2)).collect(),
-                Ok(vec![(1, 1), (2, 2)]));
-    assert_done(|| list().take(2).zip(list()).collect(),
-                Ok(vec![(1, 1), (2, 2)]));
+    assert_done(|| list().zip(list()).collect(), Ok(vec![(1, 1), (2, 2), (3, 3)]));
+    assert_done(|| list().zip(list().take(2)).collect(), Ok(vec![(1, 1), (2, 2)]));
+    assert_done(|| list().take(2).zip(list()).collect(), Ok(vec![(1, 1), (2, 2)]));
     assert_done(|| err_list().zip(list()).collect::<Vec<_>>(), Err(3));
-    assert_done(|| list().zip(list().map(|x| x + 1)).collect(),
-                Ok(vec![(1, 2), (2, 3), (3, 4)]));
+    assert_done(|| list().zip(list().map(|x| x + 1)).collect(), Ok(vec![(1, 2), (2, 3), (3, 4)]));
 }
 
 #[test]
 fn peek() {
     struct Peek {
-        inner: Peekable<Box<Stream<Item = i32, Error =u32> + Send>>
+        inner: Peekable<Box<Stream<Item = i32, Error = u32> + Send>>,
     }
 
     impl Future for Peek {
@@ -299,15 +276,12 @@ fn peek() {
         }
     }
 
-    block_on(Peek {
-        inner: list().peekable(),
-    }).unwrap()
+    block_on(Peek { inner: list().peekable() }).unwrap()
 }
 
 #[test]
 fn wait() {
-    assert_eq!(block_on_stream(list()).collect::<Result<Vec<_>, _>>(),
-               Ok(vec![1, 2, 3]));
+    assert_eq!(block_on_stream(list()).collect::<Result<Vec<_>, _>>(), Ok(vec![1, 2, 3]));
 }
 
 #[test]
@@ -337,8 +311,10 @@ fn forward() {
     let v = block_on(iter_ok::<_, Never>(vec![2, 3]).forward(v)).unwrap().1;
     assert_eq!(v, vec![0, 1, 2, 3]);
 
-    assert_done(move || iter_ok::<_, Never>(vec![4, 5]).forward(v).map(|(_, s)| s),
-                Ok(vec![0, 1, 2, 3, 4, 5]));
+    assert_done(
+        move || iter_ok::<_, Never>(vec![4, 5]).forward(v).map(|(_, s)| s),
+        Ok(vec![0, 1, 2, 3, 4, 5]),
+    );
 }
 
 #[test]