diff --git a/Cargo.lock b/Cargo.lock
index 198bc5c82be643480db0c2734913871eed51acf0..84f55aa43070d797886d42c157755aaedfa69581 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -149,7 +149,7 @@ dependencies = [
  "ashmem",
  "audio_thread_priority",
  "bincode",
- "bytes 0.4.9",
+ "bytes 0.4.12",
  "cc",
  "cubeb",
  "error-chain",
@@ -454,9 +454,9 @@ checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
 
 [[package]]
 name = "bytes"
-version = "0.4.9"
+version = "0.4.12"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e178b8e0e239e844b083d5a0d4a156b2654e67f9f80144d48398fcd736a24fb8"
+checksum = "206fdffcfa2df7cbe15601ef46c813fce0965eb3286db6b56c583b814b51c81c"
 dependencies = [
  "byteorder",
  "iovec",
@@ -464,9 +464,9 @@ dependencies = [
 
 [[package]]
 name = "bytes"
-version = "0.5.3"
+version = "0.5.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "10004c15deb332055f7a4a208190aed362cf9a7c2f6ab70a305fba50e1105f38"
+checksum = "0e4cec68f03f32e44924783795810fa50a7035d8c8ebe78580ad7e6c703fba38"
 
 [[package]]
 name = "c2-chacha"
@@ -2229,7 +2229,7 @@ version = "0.2.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "7938e6aa2a31df4e21f224dc84704bd31c089a6d1355c535b03667371cccc843"
 dependencies = [
- "bytes 0.5.3",
+ "bytes 0.5.6",
  "fnv",
  "futures-core",
  "futures-sink",
@@ -2289,7 +2289,7 @@ checksum = "ed18eb2459bf1a09ad2d6b1547840c3e5e62882fa09b9a6a20b1de8e3228848f"
 dependencies = [
  "base64 0.12.3",
  "bitflags",
- "bytes 0.5.3",
+ "bytes 0.5.6",
  "headers-core",
  "http",
  "mime",
@@ -2327,7 +2327,7 @@ version = "0.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "b708cc7f06493459026f53b9a61a7a121a5d1ec6238dee58ea4941132b30156b"
 dependencies = [
- "bytes 0.5.3",
+ "bytes 0.5.6",
  "fnv",
  "itoa",
 ]
@@ -2338,7 +2338,7 @@ version = "0.3.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "13d5ff830006f7646652e057693569bfe0d51760c0085a071769d142a205111b"
 dependencies = [
- "bytes 0.5.3",
+ "bytes 0.5.6",
  "http",
 ]
 
@@ -2386,7 +2386,7 @@ version = "0.13.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "96816e1d921eca64d208a85aab4f7798455a8e34229ee5a88c935bdee1b78b14"
 dependencies = [
- "bytes 0.5.3",
+ "bytes 0.5.6",
  "futures-channel",
  "futures-core",
  "futures-util",
@@ -3976,7 +3976,7 @@ version = "0.6.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "ce49aefe0a6144a45de32927c77bd2859a5f7677b55f220ae5b744e87389c212"
 dependencies = [
- "bytes 0.5.3",
+ "bytes 0.5.6",
  "prost-derive",
 ]
 
@@ -5176,7 +5176,7 @@ version = "0.1.11"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "6e93c78d23cc61aa245a8acd2c4a79c4d7fa7fb5c3ca90d5737029f043a84895"
 dependencies = [
- "bytes 0.4.9",
+ "bytes 0.4.12",
  "futures 0.1.29",
  "mio",
  "tokio-codec",
@@ -5198,7 +5198,7 @@ version = "0.2.18"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "34ef16d072d2b6dc8b4a56c70f5c5ced1a37752116f8e7c1e80c659aa7cb6713"
 dependencies = [
- "bytes 0.5.3",
+ "bytes 0.5.6",
  "fnv",
  "futures-core",
  "iovec",
@@ -5215,7 +5215,7 @@ version = "0.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "881e9645b81c2ce95fcb799ded2c29ffb9f25ef5bef909089a420e5961dd8ccb"
 dependencies = [
- "bytes 0.4.9",
+ "bytes 0.4.12",
  "futures 0.1.29",
  "tokio-io",
 ]
@@ -5257,7 +5257,7 @@ version = "0.1.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "a5c9635ee806f26d302b8baa1e145689a280d8f5aa8d0552e7344808da54cc21"
 dependencies = [
- "bytes 0.4.9",
+ "bytes 0.4.12",
  "futures 0.1.29",
  "log",
 ]
@@ -5282,7 +5282,7 @@ version = "0.1.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "5b4c329b47f071eb8a746040465fa751bd95e4716e98daef6a9b4e434c17d565"
 dependencies = [
- "bytes 0.4.9",
+ "bytes 0.4.12",
  "futures 0.1.29",
  "iovec",
  "mio",
@@ -5325,7 +5325,7 @@ version = "0.1.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "43eb534af6e8f37d43ab1b612660df14755c42bd003c5f8d2475ee78cc4600c0"
 dependencies = [
- "bytes 0.4.9",
+ "bytes 0.4.12",
  "futures 0.1.29",
  "log",
  "mio",
@@ -5340,7 +5340,7 @@ version = "0.2.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "037ffc3ba0e12a0ab4aca92e5234e0dedeb48fddf6ccd260f1f150a36a9f2445"
 dependencies = [
- "bytes 0.4.9",
+ "bytes 0.4.12",
  "futures 0.1.29",
  "iovec",
  "libc",
@@ -5358,7 +5358,7 @@ version = "0.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "571da51182ec208780505a32528fc5512a8fe1443ab960b3f2f3ef093cd16930"
 dependencies = [
- "bytes 0.5.3",
+ "bytes 0.5.6",
  "futures-core",
  "futures-sink",
  "log",
@@ -5595,7 +5595,7 @@ version = "0.2.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "54cd1e2b3eb3539284d88b76a9afcf5e20f2ef2fab74db5b21a1c30d7d945e82"
 dependencies = [
- "bytes 0.5.3",
+ "bytes 0.5.6",
  "futures 0.3.12",
  "headers",
  "http",
@@ -5648,7 +5648,7 @@ name = "webdriver"
 version = "0.43.1"
 dependencies = [
  "base64 0.12.3",
- "bytes 0.5.3",
+ "bytes 0.5.6",
  "cookie",
  "http",
  "log",
diff --git a/third_party/rust/bytes-0.4.12/.cargo-checksum.json b/third_party/rust/bytes-0.4.12/.cargo-checksum.json
new file mode 100644
index 0000000000000000000000000000000000000000..a8c04d53fdd1b09e7dfd525d013fcae1f2f53b50
--- /dev/null
+++ b/third_party/rust/bytes-0.4.12/.cargo-checksum.json
@@ -0,0 +1 @@
+{"files":{"CHANGELOG.md":"4653003b329c39ab26967eb8e867f678f91848c0b9110087cf2f1f94cd9fa5fb","Cargo.toml":"c26672075ad52777c94facd5d1a8bd5a062a8cae93dd19fed7261f309c478380","LICENSE":"45f522cacecb1023856e46df79ca625dfc550c94910078bd8aec6e02880b3d42","README.md":"98017aa9d4a827389919b1a35cbf4173a50fe631a33923d77f51b49388f5f47b","benches/bytes.rs":"a60889c35cf76faf2b403f94d3ab2831a569f2e1f6e4cc4d5e88f3c26bddb8b0","ci/before_deploy.ps1":"a8ee0204dd1397a245a47626fecd98eff5da76e12b15139c06271b3cc309a3e1","ci/before_deploy.sh":"ea008e2c544482cba5b659c17887ccd5354779c629096f28e667d40391299cc5","ci/install.sh":"8b165fc99df296261fcc9cdcbc8b8a177c11c505cdc9255cc19efb66cb0055db","ci/script.sh":"4e6f6b7df02d316ce5166a3526dc6bca6b6d051dbc5bd6d5b28a7c79fc646834","ci/tsan":"ab91828d326a1fa304097de624c00bc264066223fcb6ff2a0e1eef0b3365abeb","src/buf/buf.rs":"bb75d85a07d132c869cf2f34200003c8ff9f721642df17a8a98a935a7562d886","src/buf/buf_mut.rs":"576750f263091bfb15e7ad00be086d252fb75bbf8d63017186ce67438987355d","src/buf/chain.rs":"3a4f88879d27240e84e58bbeddf3f7c0958d0d81f4707245199b53e922029a26","src/buf/from_buf.rs":"949683c6a08099b280bd324d0c8646b1d6ff80af4d3e9397edb76cc2f1b18c88","src/buf/into_buf.rs":"b6e35d34533fae229f5209b95a39a1c35485f48a873a1d357d99218c486b0b95","src/buf/iter.rs":"325428e4f913beb602f6451b59847d4c8658ec23939a15f7b145733969c17f03","src/buf/mod.rs":"481a8f937f0f015ac1136febe59148e8b7039326102983e5a4cce8dab4d4de1e","src/buf/reader.rs":"ba26856d56300cf4397cf0d1b19089267c8e51355c38133e3d25d63331bb3a7a","src/buf/take.rs":"0bdd0720afc546c999e5a3125f20b6f31a5692b37f7218c25f414773e2702f3d","src/buf/vec_deque.rs":"4023992fd8607a7a6a45f3120d39c33fd4ec5cb68f171dcd9eff6b92fde15599","src/buf/writer.rs":"4a28c1d362e837682a4b3197732a6dbb4072dc660f0dbba18616679adf8a60f2","src/bytes.rs":"213533117810e44a669972d8166a7215228e4bbf4ae18796fca4ebdbbc7c16ac","src/debug.rs":"a8bd8062e7e500fdc5a79cb6c848fb860be8359d95e1c91034777fe33c78d54e","src/either.rs":"5ecb5bcec6faea2454d274cdfef8fd26096e1b93d586cb29aebfe42291026e43","src/lib.rs":"ceabc03d07402008c2177b21cc9ea9ca0556d67b07dc4740908942145188c573","src/serde.rs":"e8d0fe3630e173272756fb24a8c3ccb112f4cb551b8b88b64f669a71f39ef83b","tests/test_buf.rs":"6409f32f734969bebeffa7592fed531953d252c5a639e422b6e4b14ec024b1d5","tests/test_buf_mut.rs":"a6a653d5053340b0254900c33e36df6db1421f821c3e985be0044b1b447ecedc","tests/test_bytes.rs":"59538b70536e0947e00b9503da24f2c511cd8b454ad2d57b8e7e7f6ed34b0490","tests/test_chain.rs":"3fe1f28f3bce4377f8ed506718f95f3ed3ebaf251a1cb43b2705331e3dd6b43a","tests/test_debug.rs":"4cfd44c30d0b8f7c5eb8e8916ad7436e9f538732fe9f4b696dc22b84c31ac64a","tests/test_from_buf.rs":"9bf743c77e69c643d0a7673426547dacaedbcc65028a26cf5864eb6714e4897a","tests/test_iter.rs":"bc8a5da0b3cc7e5a5dc37e91dd2a3ca3fc78ba74b087883473043be45cd9b265","tests/test_reader.rs":"a23c969882dda095c42f5e4da54b2274854c3ece9864ff9ff2439ab4ee289b11","tests/test_serde.rs":"98e0ab121153a7ead47538257ac7fc7d5db081fc35050552b5e5dc9500b414f9","tests/test_take.rs":"bb81822eec5d3774bd2626f0f29b543d3651f4f5a95c51dfe8f93dec8b4f8e94"},"package":"206fdffcfa2df7cbe15601ef46c813fce0965eb3286db6b56c583b814b51c81c"}
\ No newline at end of file
diff --git a/third_party/rust/bytes-0.4.9/CHANGELOG.md b/third_party/rust/bytes-0.4.12/CHANGELOG.md
similarity index 81%
rename from third_party/rust/bytes-0.4.9/CHANGELOG.md
rename to third_party/rust/bytes-0.4.12/CHANGELOG.md
index 1e87d35be20ff6ece31a2c2d890b52489e43fda2..881b6f602933710a8b98441c469c317b27557fcd 100644
--- a/third_party/rust/bytes-0.4.9/CHANGELOG.md
+++ b/third_party/rust/bytes-0.4.12/CHANGELOG.md
@@ -1,3 +1,20 @@
+# 0.4.12 (March 6, 2018)
+
+### Added
+- Implement `FromIterator<&'a u8>` for `BytesMut`/`Bytes` (#244).
+- Implement `Buf` for `VecDeque` (#249).
+
+# 0.4.11 (November 17, 2018)
+
+* Use raw pointers for potentially racy loads (#233).
+* Implement `BufRead` for `buf::Reader` (#232).
+* Documentation tweaks (#234).
+
+# 0.4.10 (September 4, 2018)
+
+* impl `Buf` and `BufMut` for `Either` (#225).
+* Add `Bytes::slice_ref` (#208).
+
 # 0.4.9 (July 12, 2018)
 
 * Add 128 bit number support behind a feature flag (#209).
diff --git a/third_party/rust/bytes-0.4.9/Cargo.toml b/third_party/rust/bytes-0.4.12/Cargo.toml
similarity index 89%
rename from third_party/rust/bytes-0.4.9/Cargo.toml
rename to third_party/rust/bytes-0.4.12/Cargo.toml
index 61ed633cbc0e64c39407dcc3130dc2bb16327d3e..96137c151954f62e8bacc8e4ac0d5fdd7928f702 100644
--- a/third_party/rust/bytes-0.4.9/Cargo.toml
+++ b/third_party/rust/bytes-0.4.12/Cargo.toml
@@ -12,12 +12,12 @@
 
 [package]
 name = "bytes"
-version = "0.4.9"
+version = "0.4.12"
 authors = ["Carl Lerche <me@carllerche.com>"]
 exclude = [".gitignore", ".travis.yml", "deploy.sh", "bench/**/*", "test/**/*"]
 description = "Types and traits for working with bytes"
 homepage = "https://github.com/carllerche/bytes"
-documentation = "https://carllerche.github.io/bytes/bytes"
+documentation = "https://docs.rs/bytes/0.4.12/bytes"
 readme = "README.md"
 keywords = ["buffers", "zero-copy", "io"]
 categories = ["network-programming", "data-structures"]
@@ -28,6 +28,11 @@ features = ["i128"]
 [dependencies.byteorder]
 version = "1.1.0"
 
+[dependencies.either]
+version = "1.5"
+optional = true
+default-features = false
+
 [dependencies.iovec]
 version = "0.1"
 
diff --git a/third_party/rust/bytes-0.4.9/LICENSE b/third_party/rust/bytes-0.4.12/LICENSE
similarity index 100%
rename from third_party/rust/bytes-0.4.9/LICENSE
rename to third_party/rust/bytes-0.4.12/LICENSE
diff --git a/third_party/rust/bytes-0.4.9/README.md b/third_party/rust/bytes-0.4.12/README.md
similarity index 86%
rename from third_party/rust/bytes-0.4.9/README.md
rename to third_party/rust/bytes-0.4.12/README.md
index 3b2a80b3bbfe794c1b350041634edcdbf93e0601..01359742ce4dc2297a6e107642422d42f540558a 100644
--- a/third_party/rust/bytes-0.4.9/README.md
+++ b/third_party/rust/bytes-0.4.12/README.md
@@ -5,7 +5,7 @@ A utility library for working with bytes.
 [![Crates.io](https://img.shields.io/crates/v/bytes.svg?maxAge=2592000)](https://crates.io/crates/bytes)
 [![Build Status](https://travis-ci.org/carllerche/bytes.svg?branch=master)](https://travis-ci.org/carllerche/bytes)
 
-[Documentation](https://carllerche.github.io/bytes/bytes/index.html)
+[Documentation](https://docs.rs/bytes/0.4.12/bytes/)
 
 ## Usage
 
@@ -13,7 +13,7 @@ To use `bytes`, first add this to your `Cargo.toml`:
 
 ```toml
 [dependencies]
-bytes = "0.4"
+bytes = "0.4.12"
 ```
 
 Next, add this to your crate:
@@ -30,7 +30,7 @@ Serde support is optional and disabled by default. To enable use the feature `se
 
 ```toml
 [dependencies]
-bytes = { version = "0.4", features = ["serde"] }
+bytes = { version = "0.4.12", features = ["serde"] }
 ```
 
 ## License
diff --git a/third_party/rust/bytes-0.4.9/benches/bytes.rs b/third_party/rust/bytes-0.4.12/benches/bytes.rs
similarity index 100%
rename from third_party/rust/bytes-0.4.9/benches/bytes.rs
rename to third_party/rust/bytes-0.4.12/benches/bytes.rs
diff --git a/third_party/rust/bytes-0.4.9/ci/before_deploy.ps1 b/third_party/rust/bytes-0.4.12/ci/before_deploy.ps1
similarity index 100%
rename from third_party/rust/bytes-0.4.9/ci/before_deploy.ps1
rename to third_party/rust/bytes-0.4.12/ci/before_deploy.ps1
diff --git a/third_party/rust/bytes-0.4.9/ci/before_deploy.sh b/third_party/rust/bytes-0.4.12/ci/before_deploy.sh
similarity index 100%
rename from third_party/rust/bytes-0.4.9/ci/before_deploy.sh
rename to third_party/rust/bytes-0.4.12/ci/before_deploy.sh
diff --git a/third_party/rust/bytes-0.4.9/ci/install.sh b/third_party/rust/bytes-0.4.12/ci/install.sh
similarity index 100%
rename from third_party/rust/bytes-0.4.9/ci/install.sh
rename to third_party/rust/bytes-0.4.12/ci/install.sh
diff --git a/third_party/rust/bytes-0.4.9/ci/script.sh b/third_party/rust/bytes-0.4.12/ci/script.sh
similarity index 100%
rename from third_party/rust/bytes-0.4.9/ci/script.sh
rename to third_party/rust/bytes-0.4.12/ci/script.sh
diff --git a/third_party/rust/bytes/ci/tsan b/third_party/rust/bytes-0.4.12/ci/tsan
similarity index 82%
rename from third_party/rust/bytes/ci/tsan
rename to third_party/rust/bytes-0.4.12/ci/tsan
index e53f9b893d3b3cdc0e06ee774244ee5ac84baad1..9cc54841bf39b19b46c6dc606c07fd1eb44acf33 100644
--- a/third_party/rust/bytes/ci/tsan
+++ b/third_party/rust/bytes-0.4.12/ci/tsan
@@ -19,6 +19,10 @@ race:test::run_tests_console::*closure
 # Probably more fences in std.
 race:__call_tls_dtors
 
+# `is_inline_or_static` is explicitly called concurrently without synchronization.
+# The safety explanation can be found in a comment.
+race:Inner::is_inline_or_static
+
 # This ignores a false positive caused by `thread::park()`/`thread::unpark()`.
 # See: https://github.com/rust-lang/rust/pull/54806#issuecomment-436193353
 race:pthread_cond_destroy
diff --git a/third_party/rust/bytes-0.4.9/src/buf/buf.rs b/third_party/rust/bytes-0.4.12/src/buf/buf.rs
similarity index 99%
rename from third_party/rust/bytes-0.4.9/src/buf/buf.rs
rename to third_party/rust/bytes-0.4.12/src/buf/buf.rs
index b72c8d91cbe91dc25502ee082394c366202cc129..dc20567d3b61730c0b9559305bcb64338c768c35 100644
--- a/third_party/rust/bytes-0.4.9/src/buf/buf.rs
+++ b/third_party/rust/bytes-0.4.12/src/buf/buf.rs
@@ -91,7 +91,8 @@ pub trait Buf {
     fn remaining(&self) -> usize;
 
     /// Returns a slice starting at the current position and of length between 0
-    /// and `Buf::remaining()`.
+    /// and `Buf::remaining()`. Note that this *can* return shorter slice (this allows
+    /// non-continuous internal representation).
     ///
     /// This is a lower level function. Most operations are done with other
     /// functions.
diff --git a/third_party/rust/bytes-0.4.9/src/buf/buf_mut.rs b/third_party/rust/bytes-0.4.12/src/buf/buf_mut.rs
similarity index 99%
rename from third_party/rust/bytes-0.4.9/src/buf/buf_mut.rs
rename to third_party/rust/bytes-0.4.12/src/buf/buf_mut.rs
index 71dbda9afe6c3ea6b962d3f3249853ad5785a319..7f3c1f756fbbc8accc598a24dccc26fd01b7bef5 100644
--- a/third_party/rust/bytes-0.4.9/src/buf/buf_mut.rs
+++ b/third_party/rust/bytes-0.4.12/src/buf/buf_mut.rs
@@ -121,7 +121,8 @@ pub trait BufMut {
     }
 
     /// Returns a mutable slice starting at the current BufMut position and of
-    /// length between 0 and `BufMut::remaining_mut()`.
+    /// length between 0 and `BufMut::remaining_mut()`. Note that this *can* be shorter than the
+    /// whole remainder of the buffer (this allows non-continuous implementation).
     ///
     /// This is a lower level function. Most operations are done with other
     /// functions.
diff --git a/third_party/rust/bytes-0.4.9/src/buf/chain.rs b/third_party/rust/bytes-0.4.12/src/buf/chain.rs
similarity index 100%
rename from third_party/rust/bytes-0.4.9/src/buf/chain.rs
rename to third_party/rust/bytes-0.4.12/src/buf/chain.rs
diff --git a/third_party/rust/bytes-0.4.9/src/buf/from_buf.rs b/third_party/rust/bytes-0.4.12/src/buf/from_buf.rs
similarity index 100%
rename from third_party/rust/bytes-0.4.9/src/buf/from_buf.rs
rename to third_party/rust/bytes-0.4.12/src/buf/from_buf.rs
diff --git a/third_party/rust/bytes-0.4.9/src/buf/into_buf.rs b/third_party/rust/bytes-0.4.12/src/buf/into_buf.rs
similarity index 100%
rename from third_party/rust/bytes-0.4.9/src/buf/into_buf.rs
rename to third_party/rust/bytes-0.4.12/src/buf/into_buf.rs
diff --git a/third_party/rust/bytes-0.4.9/src/buf/iter.rs b/third_party/rust/bytes-0.4.12/src/buf/iter.rs
similarity index 100%
rename from third_party/rust/bytes-0.4.9/src/buf/iter.rs
rename to third_party/rust/bytes-0.4.12/src/buf/iter.rs
diff --git a/third_party/rust/bytes-0.4.9/src/buf/mod.rs b/third_party/rust/bytes-0.4.12/src/buf/mod.rs
similarity index 98%
rename from third_party/rust/bytes-0.4.9/src/buf/mod.rs
rename to third_party/rust/bytes-0.4.12/src/buf/mod.rs
index 1f74e0ab40f78fd215bbf03e2d8c80da9958a562..35b4857ecb352ca3b63ee40c9b97864e48c247b9 100644
--- a/third_party/rust/bytes-0.4.9/src/buf/mod.rs
+++ b/third_party/rust/bytes-0.4.12/src/buf/mod.rs
@@ -24,6 +24,7 @@ mod into_buf;
 mod iter;
 mod reader;
 mod take;
+mod vec_deque;
 mod writer;
 
 pub use self::buf::Buf;
diff --git a/third_party/rust/bytes-0.4.9/src/buf/reader.rs b/third_party/rust/bytes-0.4.12/src/buf/reader.rs
similarity index 91%
rename from third_party/rust/bytes-0.4.9/src/buf/reader.rs
rename to third_party/rust/bytes-0.4.12/src/buf/reader.rs
index 59f9c3304908cd5efe270db44e58670fa99ecf10..f1154dacebb71790254b5249af949037e2d860ae 100644
--- a/third_party/rust/bytes-0.4.9/src/buf/reader.rs
+++ b/third_party/rust/bytes-0.4.12/src/buf/reader.rs
@@ -86,3 +86,12 @@ impl<B: Buf + Sized> io::Read for Reader<B> {
         Ok(len)
     }
 }
+
+impl<B: Buf + Sized> io::BufRead for Reader<B> {
+    fn fill_buf(&mut self) -> io::Result<&[u8]> {
+        Ok(self.buf.bytes())
+    }
+    fn consume(&mut self, amt: usize) {
+        self.buf.advance(amt)
+    }
+}
diff --git a/third_party/rust/bytes-0.4.9/src/buf/take.rs b/third_party/rust/bytes-0.4.12/src/buf/take.rs
similarity index 100%
rename from third_party/rust/bytes-0.4.9/src/buf/take.rs
rename to third_party/rust/bytes-0.4.12/src/buf/take.rs
diff --git a/third_party/rust/bytes-0.4.12/src/buf/vec_deque.rs b/third_party/rust/bytes-0.4.12/src/buf/vec_deque.rs
new file mode 100644
index 0000000000000000000000000000000000000000..1cd650f51ddcdae2417ce429424f77e28e0a2f54
--- /dev/null
+++ b/third_party/rust/bytes-0.4.12/src/buf/vec_deque.rs
@@ -0,0 +1,39 @@
+use std::collections::VecDeque;
+
+use super::Buf;
+
+impl Buf for VecDeque<u8> {
+    fn remaining(&self) -> usize {
+        self.len()
+    }
+
+    fn bytes(&self) -> &[u8] {
+        let (s1, s2) = self.as_slices();
+        if s1.is_empty() {
+            s2
+        } else {
+            s1
+        }
+    }
+
+    fn advance(&mut self, cnt: usize) {
+        self.drain(..cnt);
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+
+    #[test]
+    fn hello_world() {
+        let mut buffer: VecDeque<u8> = VecDeque::new();
+        buffer.extend(b"hello world");
+        assert_eq!(11, buffer.remaining());
+        assert_eq!(b"hello world", buffer.bytes());
+        buffer.advance(6);
+        assert_eq!(b"world", buffer.bytes());
+        buffer.extend(b" piece");
+        assert_eq!(b"world piece" as &[u8], &buffer.collect::<Vec<u8>>()[..]);
+    }
+}
diff --git a/third_party/rust/bytes-0.4.9/src/buf/writer.rs b/third_party/rust/bytes-0.4.12/src/buf/writer.rs
similarity index 100%
rename from third_party/rust/bytes-0.4.9/src/buf/writer.rs
rename to third_party/rust/bytes-0.4.12/src/buf/writer.rs
diff --git a/third_party/rust/bytes-0.4.9/src/bytes.rs b/third_party/rust/bytes-0.4.12/src/bytes.rs
similarity index 95%
rename from third_party/rust/bytes-0.4.9/src/bytes.rs
rename to third_party/rust/bytes-0.4.12/src/bytes.rs
index 89244dd40603205cfae22725f6252fe6b877a162..e1559311b0daead7cbf6a49ae96e12cd8a876e9d 100644
--- a/third_party/rust/bytes-0.4.9/src/bytes.rs
+++ b/third_party/rust/bytes-0.4.12/src/bytes.rs
@@ -273,7 +273,7 @@ pub struct BytesMut {
 // The rest of `arc`'s bytes are used as part of the inline buffer, which means
 // that those bytes need to be located next to the `ptr`, `len`, and `cap`
 // fields, which make up the rest of the inline buffer. This requires special
-// casing the layout of `Inner` depending on if the target platform is bit or
+// casing the layout of `Inner` depending on if the target platform is big or
 // little endian.
 //
 // On little endian platforms, the `arc` field must be the first field in the
@@ -576,6 +576,46 @@ impl Bytes {
         self.slice(0, end)
     }
 
+    /// Returns a slice of self that is equivalent to the given `subset`.
+    ///
+    /// When processing a `Bytes` buffer with other tools, one often gets a
+    /// `&[u8]` which is in fact a slice of the `Bytes`, i.e. a subset of it.
+    /// This function turns that `&[u8]` into another `Bytes`, as if one had
+    /// called `self.slice()` with the offsets that correspond to `subset`.
+    ///
+    /// This operation is `O(1)`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::Bytes;
+    ///
+    /// let bytes = Bytes::from(&b"012345678"[..]);
+    /// let as_slice = bytes.as_ref();
+    /// let subset = &as_slice[2..6];
+    /// let subslice = bytes.slice_ref(&subset);
+    /// assert_eq!(&subslice[..], b"2345");
+    /// ```
+    ///
+    /// # Panics
+    ///
+    /// Requires that the given `sub` slice is in fact contained within the
+    /// `Bytes` buffer; otherwise this function will panic.
+    pub fn slice_ref(&self, subset: &[u8]) -> Bytes {
+        let bytes_p = self.as_ptr() as usize;
+        let bytes_len = self.len();
+
+        let sub_p = subset.as_ptr() as usize;
+        let sub_len = subset.len();
+
+        assert!(sub_p >= bytes_p);
+        assert!(sub_p + sub_len <= bytes_p + bytes_len);
+
+        let sub_offset = sub_p - bytes_p;
+
+        self.slice(sub_offset, sub_offset + sub_len)
+    }
+
     /// Splits the bytes into two at the given index.
     ///
     /// Afterwards `self` contains elements `[0, at)`, and the returned `Bytes`
@@ -886,6 +926,18 @@ impl FromIterator<u8> for Bytes {
     }
 }
 
+impl<'a> FromIterator<&'a u8> for BytesMut {
+    fn from_iter<T: IntoIterator<Item = &'a u8>>(into_iter: T) -> Self {
+        BytesMut::from_iter(into_iter.into_iter().map(|b| *b))
+    }
+}
+
+impl<'a> FromIterator<&'a u8> for Bytes {
+    fn from_iter<T: IntoIterator<Item = &'a u8>>(into_iter: T) -> Self {
+        BytesMut::from_iter(into_iter).freeze()
+    }
+}
+
 impl PartialEq for Bytes {
     fn eq(&self, other: &Bytes) -> bool {
         self.inner.as_ref() == other.inner.as_ref()
@@ -2389,6 +2441,10 @@ impl Inner {
         // bits, so even without any explicit atomic operations, reading the
         // flag will be correct.
         //
+        // This is undefind behavior due to a data race, but experimental
+        // evidence shows that it works in practice (discussion:
+        // https://internals.rust-lang.org/t/bit-wise-reasoning-for-atomic-accesses/8853).
+        //
         // This function is very critical performance wise as it is called for
         // every operation. Performing an atomic load would mess with the
         // compiler's ability to optimize. Simple benchmarks show up to a 10%
@@ -2398,7 +2454,7 @@ impl Inner {
         #[inline]
         fn imp(arc: &AtomicPtr<Shared>) -> usize {
             unsafe {
-                let p: &u8 = mem::transmute(arc);
+                let p: *const u8 = mem::transmute(arc);
                 (*p as usize) & KIND_MASK
             }
         }
@@ -2407,7 +2463,7 @@ impl Inner {
         #[inline]
         fn imp(arc: &AtomicPtr<Shared>) -> usize {
             unsafe {
-                let p: &usize = mem::transmute(arc);
+                let p: *const usize = mem::transmute(arc);
                 *p & KIND_MASK
             }
         }
@@ -2423,7 +2479,7 @@ impl Inner {
         // function.
         let prev = unsafe {
             let p: &AtomicPtr<Shared> = &self.arc;
-            let p: &usize = mem::transmute(p);
+            let p: *const usize = mem::transmute(p);
             *p
         };
 
@@ -2530,35 +2586,51 @@ fn original_capacity_from_repr(repr: usize) -> usize {
 
 #[test]
 fn test_original_capacity_to_repr() {
-    for &cap in &[0, 1, 16, 1000] {
-        assert_eq!(0, original_capacity_to_repr(cap));
-    }
+    assert_eq!(original_capacity_to_repr(0), 0);
 
-    for &cap in &[1024, 1025, 1100, 2000, 2047] {
-        assert_eq!(1, original_capacity_to_repr(cap));
-    }
+    let max_width = 32;
 
-    for &cap in &[2048, 2049] {
-        assert_eq!(2, original_capacity_to_repr(cap));
-    }
+    for width in 1..(max_width + 1) {
+        let cap = 1 << width - 1;
 
-    // TODO: more
+        let expected = if width < MIN_ORIGINAL_CAPACITY_WIDTH {
+            0
+        } else if width < MAX_ORIGINAL_CAPACITY_WIDTH {
+            width - MIN_ORIGINAL_CAPACITY_WIDTH
+        } else {
+            MAX_ORIGINAL_CAPACITY_WIDTH - MIN_ORIGINAL_CAPACITY_WIDTH
+        };
 
-    for &cap in &[65536, 65537, 68000, 1 << 17, 1 << 18, 1 << 20, 1 << 30] {
-        assert_eq!(7, original_capacity_to_repr(cap), "cap={}", cap);
+        assert_eq!(original_capacity_to_repr(cap), expected);
+
+        if width > 1 {
+            assert_eq!(original_capacity_to_repr(cap + 1), expected);
+        }
+
+        //  MIN_ORIGINAL_CAPACITY_WIDTH must be bigger than 7 to pass tests below
+        if width == MIN_ORIGINAL_CAPACITY_WIDTH + 1 {
+            assert_eq!(original_capacity_to_repr(cap - 24), expected - 1);
+            assert_eq!(original_capacity_to_repr(cap + 76), expected);
+        } else if width == MIN_ORIGINAL_CAPACITY_WIDTH + 2 {
+            assert_eq!(original_capacity_to_repr(cap - 1), expected - 1);
+            assert_eq!(original_capacity_to_repr(cap - 48), expected - 1);
+        }
     }
 }
 
 #[test]
 fn test_original_capacity_from_repr() {
     assert_eq!(0, original_capacity_from_repr(0));
-    assert_eq!(1024, original_capacity_from_repr(1));
-    assert_eq!(1024 * 2, original_capacity_from_repr(2));
-    assert_eq!(1024 * 4, original_capacity_from_repr(3));
-    assert_eq!(1024 * 8, original_capacity_from_repr(4));
-    assert_eq!(1024 * 16, original_capacity_from_repr(5));
-    assert_eq!(1024 * 32, original_capacity_from_repr(6));
-    assert_eq!(1024 * 64, original_capacity_from_repr(7));
+
+    let min_cap = 1 << MIN_ORIGINAL_CAPACITY_WIDTH;
+
+    assert_eq!(min_cap, original_capacity_from_repr(1));
+    assert_eq!(min_cap * 2, original_capacity_from_repr(2));
+    assert_eq!(min_cap * 4, original_capacity_from_repr(3));
+    assert_eq!(min_cap * 8, original_capacity_from_repr(4));
+    assert_eq!(min_cap * 16, original_capacity_from_repr(5));
+    assert_eq!(min_cap * 32, original_capacity_from_repr(6));
+    assert_eq!(min_cap * 64, original_capacity_from_repr(7));
 }
 
 unsafe impl Send for Inner {}
diff --git a/third_party/rust/bytes-0.4.9/src/debug.rs b/third_party/rust/bytes-0.4.12/src/debug.rs
similarity index 100%
rename from third_party/rust/bytes-0.4.9/src/debug.rs
rename to third_party/rust/bytes-0.4.12/src/debug.rs
diff --git a/third_party/rust/bytes-0.4.12/src/either.rs b/third_party/rust/bytes-0.4.12/src/either.rs
new file mode 100644
index 0000000000000000000000000000000000000000..53a2775996c2e5082d3c3eb8d10442601e78f1dc
--- /dev/null
+++ b/third_party/rust/bytes-0.4.12/src/either.rs
@@ -0,0 +1,89 @@
+extern crate either;
+
+use {Buf, BufMut};
+
+use self::either::Either;
+use self::either::Either::*;
+use iovec::IoVec;
+
+impl<L, R> Buf for Either<L, R>
+where
+    L: Buf,
+    R: Buf,
+{
+    fn remaining(&self) -> usize {
+        match *self {
+            Left(ref b) => b.remaining(),
+            Right(ref b) => b.remaining(),
+        }
+    }
+
+    fn bytes(&self) -> &[u8] {
+        match *self {
+            Left(ref b) => b.bytes(),
+            Right(ref b) => b.bytes(),
+        }
+    }
+
+    fn bytes_vec<'a>(&'a self, dst: &mut [&'a IoVec]) -> usize {
+        match *self {
+            Left(ref b) => b.bytes_vec(dst),
+            Right(ref b) => b.bytes_vec(dst),
+        }
+    }
+
+    fn advance(&mut self, cnt: usize) {
+        match *self {
+            Left(ref mut b) => b.advance(cnt),
+            Right(ref mut b) => b.advance(cnt),
+        }
+    }
+
+    fn copy_to_slice(&mut self, dst: &mut [u8]) {
+        match *self {
+            Left(ref mut b) => b.copy_to_slice(dst),
+            Right(ref mut b) => b.copy_to_slice(dst),
+        }
+    }
+}
+
+impl<L, R> BufMut for Either<L, R>
+where
+    L: BufMut,
+    R: BufMut,
+{
+    fn remaining_mut(&self) -> usize {
+        match *self {
+            Left(ref b) => b.remaining_mut(),
+            Right(ref b) => b.remaining_mut(),
+        }
+    }
+
+    unsafe fn bytes_mut(&mut self) -> &mut [u8] {
+        match *self {
+            Left(ref mut b) => b.bytes_mut(),
+            Right(ref mut b) => b.bytes_mut(),
+        }
+    }
+
+    unsafe fn bytes_vec_mut<'a>(&'a mut self, dst: &mut [&'a mut IoVec]) -> usize {
+        match *self {
+            Left(ref mut b) => b.bytes_vec_mut(dst),
+            Right(ref mut b) => b.bytes_vec_mut(dst),
+        }
+    }
+
+    unsafe fn advance_mut(&mut self, cnt: usize) {
+        match *self {
+            Left(ref mut b) => b.advance_mut(cnt),
+            Right(ref mut b) => b.advance_mut(cnt),
+        }
+    }
+
+    fn put_slice(&mut self, src: &[u8]) {
+        match *self {
+            Left(ref mut b) => b.put_slice(src),
+            Right(ref mut b) => b.put_slice(src),
+        }
+    }
+}
diff --git a/third_party/rust/bytes-0.4.9/src/lib.rs b/third_party/rust/bytes-0.4.12/src/lib.rs
similarity index 96%
rename from third_party/rust/bytes-0.4.9/src/lib.rs
rename to third_party/rust/bytes-0.4.12/src/lib.rs
index eccb8a3806db2813a22b6e379888e9e7899cc8e7..a4f1573e07714b0b48871b05a512705ebc5cbd5b 100644
--- a/third_party/rust/bytes-0.4.9/src/lib.rs
+++ b/third_party/rust/bytes-0.4.12/src/lib.rs
@@ -69,7 +69,7 @@
 //! and `BufMut` are infallible.
 
 #![deny(warnings, missing_docs, missing_debug_implementations)]
-#![doc(html_root_url = "https://docs.rs/bytes/0.4.9")]
+#![doc(html_root_url = "https://docs.rs/bytes/0.4.12")]
 
 extern crate byteorder;
 extern crate iovec;
@@ -99,3 +99,7 @@ pub use byteorder::{ByteOrder, BigEndian, LittleEndian};
 #[cfg(feature = "serde")]
 #[doc(hidden)]
 pub mod serde;
+
+// Optional `Either` support
+#[cfg(feature = "either")]
+mod either;
diff --git a/third_party/rust/bytes-0.4.9/src/serde.rs b/third_party/rust/bytes-0.4.12/src/serde.rs
similarity index 100%
rename from third_party/rust/bytes-0.4.9/src/serde.rs
rename to third_party/rust/bytes-0.4.12/src/serde.rs
diff --git a/third_party/rust/bytes-0.4.9/tests/test_buf.rs b/third_party/rust/bytes-0.4.12/tests/test_buf.rs
similarity index 100%
rename from third_party/rust/bytes-0.4.9/tests/test_buf.rs
rename to third_party/rust/bytes-0.4.12/tests/test_buf.rs
diff --git a/third_party/rust/bytes-0.4.9/tests/test_buf_mut.rs b/third_party/rust/bytes-0.4.12/tests/test_buf_mut.rs
similarity index 100%
rename from third_party/rust/bytes-0.4.9/tests/test_buf_mut.rs
rename to third_party/rust/bytes-0.4.12/tests/test_buf_mut.rs
diff --git a/third_party/rust/bytes-0.4.9/tests/test_bytes.rs b/third_party/rust/bytes-0.4.12/tests/test_bytes.rs
similarity index 93%
rename from third_party/rust/bytes-0.4.9/tests/test_bytes.rs
rename to third_party/rust/bytes-0.4.12/tests/test_bytes.rs
index c0cba6b7675991228e47efe046d5be837e777df0..4cf340e6a190865554ebef426b0dbd275d44f255 100644
--- a/third_party/rust/bytes-0.4.9/tests/test_bytes.rs
+++ b/third_party/rust/bytes-0.4.12/tests/test_bytes.rs
@@ -717,3 +717,57 @@ fn from_iter_no_size_hint() {
 
     assert_eq!(&actual[..], &expect[..]);
 }
+
+fn test_slice_ref(bytes: &Bytes, start: usize, end: usize, expected: &[u8]) {
+    let slice = &(bytes.as_ref()[start..end]);
+    let sub = bytes.slice_ref(&slice);
+    assert_eq!(&sub[..], expected);
+}
+
+#[test]
+fn slice_ref_works() {
+    let bytes = Bytes::from(&b"012345678"[..]);
+
+    test_slice_ref(&bytes, 0, 0, b"");
+    test_slice_ref(&bytes, 0, 3, b"012");
+    test_slice_ref(&bytes, 2, 6, b"2345");
+    test_slice_ref(&bytes, 7, 9, b"78");
+    test_slice_ref(&bytes, 9, 9, b"");
+}
+
+
+#[test]
+fn slice_ref_empty() {
+    let bytes = Bytes::from(&b""[..]);
+    let slice = &(bytes.as_ref()[0..0]);
+
+    let sub = bytes.slice_ref(&slice);
+    assert_eq!(&sub[..], b"");
+}
+
+#[test]
+#[should_panic]
+fn slice_ref_catches_not_a_subset() {
+    let bytes = Bytes::from(&b"012345678"[..]);
+    let slice = &b"012345"[0..4];
+
+    bytes.slice_ref(slice);
+}
+
+#[test]
+#[should_panic]
+fn slice_ref_catches_not_an_empty_subset() {
+    let bytes = Bytes::from(&b"012345678"[..]);
+    let slice = &b""[0..0];
+
+    bytes.slice_ref(slice);
+}
+
+#[test]
+#[should_panic]
+fn empty_slice_ref_catches_not_an_empty_subset() {
+    let bytes = Bytes::from(&b""[..]);
+    let slice = &b""[0..0];
+
+    bytes.slice_ref(slice);
+}
diff --git a/third_party/rust/bytes-0.4.9/tests/test_chain.rs b/third_party/rust/bytes-0.4.12/tests/test_chain.rs
similarity index 100%
rename from third_party/rust/bytes-0.4.9/tests/test_chain.rs
rename to third_party/rust/bytes-0.4.12/tests/test_chain.rs
diff --git a/third_party/rust/bytes-0.4.9/tests/test_debug.rs b/third_party/rust/bytes-0.4.12/tests/test_debug.rs
similarity index 100%
rename from third_party/rust/bytes-0.4.9/tests/test_debug.rs
rename to third_party/rust/bytes-0.4.12/tests/test_debug.rs
diff --git a/third_party/rust/bytes-0.4.9/tests/test_from_buf.rs b/third_party/rust/bytes-0.4.12/tests/test_from_buf.rs
similarity index 100%
rename from third_party/rust/bytes-0.4.9/tests/test_from_buf.rs
rename to third_party/rust/bytes-0.4.12/tests/test_from_buf.rs
diff --git a/third_party/rust/bytes-0.4.9/tests/test_iter.rs b/third_party/rust/bytes-0.4.12/tests/test_iter.rs
similarity index 100%
rename from third_party/rust/bytes-0.4.9/tests/test_iter.rs
rename to third_party/rust/bytes-0.4.12/tests/test_iter.rs
diff --git a/third_party/rust/bytes-0.4.12/tests/test_reader.rs b/third_party/rust/bytes-0.4.12/tests/test_reader.rs
new file mode 100644
index 0000000000000000000000000000000000000000..7103f3592ae8d0c8e4ddd578e23d3872724ca00d
--- /dev/null
+++ b/third_party/rust/bytes-0.4.12/tests/test_reader.rs
@@ -0,0 +1,28 @@
+extern crate bytes;
+
+use std::io::{BufRead, Cursor, Read};
+
+use bytes::Buf;
+
+#[test]
+fn read() {
+    let buf1 = Cursor::new(b"hello ");
+    let buf2 = Cursor::new(b"world");
+    let buf = Buf::chain(buf1, buf2); // Disambiguate with Read::chain
+    let mut buffer = Vec::new();
+    buf.reader().read_to_end(&mut buffer).unwrap();
+    assert_eq!(b"hello world", &buffer[..]);
+}
+
+#[test]
+fn buf_read() {
+    let buf1 = Cursor::new(b"hell");
+    let buf2 = Cursor::new(b"o\nworld");
+    let mut reader = Buf::chain(buf1, buf2).reader();
+    let mut line = String::new();
+    reader.read_line(&mut line).unwrap();
+    assert_eq!("hello\n", &line);
+    line.clear();
+    reader.read_line(&mut line).unwrap();
+    assert_eq!("world", &line);
+}
diff --git a/third_party/rust/bytes-0.4.9/tests/test_serde.rs b/third_party/rust/bytes-0.4.12/tests/test_serde.rs
similarity index 100%
rename from third_party/rust/bytes-0.4.9/tests/test_serde.rs
rename to third_party/rust/bytes-0.4.12/tests/test_serde.rs
diff --git a/third_party/rust/bytes-0.4.9/tests/test_take.rs b/third_party/rust/bytes-0.4.12/tests/test_take.rs
similarity index 100%
rename from third_party/rust/bytes-0.4.9/tests/test_take.rs
rename to third_party/rust/bytes-0.4.12/tests/test_take.rs
diff --git a/third_party/rust/bytes-0.4.9/.cargo-checksum.json b/third_party/rust/bytes-0.4.9/.cargo-checksum.json
deleted file mode 100644
index 8301dbd01e9ee06956d531244379fc8ec88d6199..0000000000000000000000000000000000000000
--- a/third_party/rust/bytes-0.4.9/.cargo-checksum.json
+++ /dev/null
@@ -1 +0,0 @@
-{"files":{"CHANGELOG.md":"55941e30721c4b104cc8f84473da5acd0cd57903d66e8fd029b8c5160d99ed53","Cargo.toml":"f71e10b42ed8637ed615222f6d9e2af5df707f7f3d9d4fd203358c2af87b7ff0","LICENSE":"45f522cacecb1023856e46df79ca625dfc550c94910078bd8aec6e02880b3d42","README.md":"3ca600d7b4175eee634621a870904fe5ec761e6fd623f745423d378dec1bfd51","benches/bytes.rs":"a60889c35cf76faf2b403f94d3ab2831a569f2e1f6e4cc4d5e88f3c26bddb8b0","ci/before_deploy.ps1":"a8ee0204dd1397a245a47626fecd98eff5da76e12b15139c06271b3cc309a3e1","ci/before_deploy.sh":"ea008e2c544482cba5b659c17887ccd5354779c629096f28e667d40391299cc5","ci/install.sh":"8b165fc99df296261fcc9cdcbc8b8a177c11c505cdc9255cc19efb66cb0055db","ci/script.sh":"4e6f6b7df02d316ce5166a3526dc6bca6b6d051dbc5bd6d5b28a7c79fc646834","ci/tsan":"905d22267f7493550d123b1482fc1a7f4b24e8cbc4ae4f0e0c2d42383e79ad83","src/buf/buf.rs":"1b5ff3ab694380fe59588b8d195111ba663c5f8901b272b531851deb26e4629a","src/buf/buf_mut.rs":"d2f54e9c64b86c8ddd325d40b3c8e1b2132d361937bac3b5fccb7a81154b89b8","src/buf/chain.rs":"3a4f88879d27240e84e58bbeddf3f7c0958d0d81f4707245199b53e922029a26","src/buf/from_buf.rs":"949683c6a08099b280bd324d0c8646b1d6ff80af4d3e9397edb76cc2f1b18c88","src/buf/into_buf.rs":"b6e35d34533fae229f5209b95a39a1c35485f48a873a1d357d99218c486b0b95","src/buf/iter.rs":"325428e4f913beb602f6451b59847d4c8658ec23939a15f7b145733969c17f03","src/buf/mod.rs":"4f385ce47d6d19a064a1dbec3339e95e116aa9b501eb9d8a47030c2794e1ee9e","src/buf/reader.rs":"62098e87bd1aa8b7f57ed4a4d1b5417462f01ad2cfebfbac46b6ce7f00ea0192","src/buf/take.rs":"0bdd0720afc546c999e5a3125f20b6f31a5692b37f7218c25f414773e2702f3d","src/buf/writer.rs":"4a28c1d362e837682a4b3197732a6dbb4072dc660f0dbba18616679adf8a60f2","src/bytes.rs":"546f2ef082656be2639314994d4228833f331747578a9ebf69075d2bcec0ae2d","src/debug.rs":"a8bd8062e7e500fdc5a79cb6c848fb860be8359d95e1c91034777fe33c78d54e","src/lib.rs":"fb61bba13236978f2c3b93cc39eb4a99c02f1ecd539c917a8380e5d344e67706","src/serde.rs":"e8d0fe3630e173272756fb24a8c3ccb112f4cb551b8b88b64f669a71f39ef83b","tests/test_buf.rs":"6409f32f734969bebeffa7592fed531953d252c5a639e422b6e4b14ec024b1d5","tests/test_buf_mut.rs":"a6a653d5053340b0254900c33e36df6db1421f821c3e985be0044b1b447ecedc","tests/test_bytes.rs":"92ae28671dee4ab91c7e0366e094b009c547defd8fd1c977520e5ad574eea70d","tests/test_chain.rs":"3fe1f28f3bce4377f8ed506718f95f3ed3ebaf251a1cb43b2705331e3dd6b43a","tests/test_debug.rs":"4cfd44c30d0b8f7c5eb8e8916ad7436e9f538732fe9f4b696dc22b84c31ac64a","tests/test_from_buf.rs":"9bf743c77e69c643d0a7673426547dacaedbcc65028a26cf5864eb6714e4897a","tests/test_iter.rs":"bc8a5da0b3cc7e5a5dc37e91dd2a3ca3fc78ba74b087883473043be45cd9b265","tests/test_serde.rs":"98e0ab121153a7ead47538257ac7fc7d5db081fc35050552b5e5dc9500b414f9","tests/test_take.rs":"bb81822eec5d3774bd2626f0f29b543d3651f4f5a95c51dfe8f93dec8b4f8e94"},"package":"e178b8e0e239e844b083d5a0d4a156b2654e67f9f80144d48398fcd736a24fb8"}
\ No newline at end of file
diff --git a/third_party/rust/bytes-0.4.9/ci/tsan b/third_party/rust/bytes-0.4.9/ci/tsan
deleted file mode 100644
index 657d4266a3aaeabaa5725e0989eaecd226d5ccff..0000000000000000000000000000000000000000
--- a/third_party/rust/bytes-0.4.9/ci/tsan
+++ /dev/null
@@ -1,21 +0,0 @@
-# TSAN suppressions file for `bytes`
-
-# TSAN does not understand fences and `Arc::drop` is implemented using a fence.
-# This causes many false positives.
-race:Arc*drop
-race:arc*Weak*drop
-
-# `std` mpsc is not used in any Bytes code base. This race is triggered by some
-# rust runtime logic.
-race:std*mpsc_queue
-
-# Not sure why this is warning, but it is in the test harness and not the library.
-race:TestEvent*clone
-race:test::run_tests_console::*closure
-
-# Probably more fences in std.
-race:__call_tls_dtors
-
-# `is_inline_or_static` is explicitly called concurrently without synchronization.
-# The safety explanation can be found in a comment.
-race:Inner::is_inline_or_static
diff --git a/third_party/rust/bytes/.cargo-checksum.json b/third_party/rust/bytes/.cargo-checksum.json
index 8883d9092dc10ebec9f756ce582409dcdf30b968..5f6f1d2f7a0d2508eabbf06db1be3b73737936b6 100644
--- a/third_party/rust/bytes/.cargo-checksum.json
+++ b/third_party/rust/bytes/.cargo-checksum.json
@@ -1 +1 @@
-{"files":{"CHANGELOG.md":"4faf2b723ed25868249363523d3506a939810e53877d7a68f72b705564e7200a","Cargo.toml":"52ab465c70fd369a72545d6fd12f5700edf6b741bfb26ef49076cd74770301a8","LICENSE":"45f522cacecb1023856e46df79ca625dfc550c94910078bd8aec6e02880b3d42","README.md":"c2aac235762c99395ae437e5f561d135a06e390a98f74baf80fb4c71dfb91ece","azure-pipelines.yml":"80098a973fbec019ae6da61ffe075047371ebb574acf4e726379628449a77016","benches/buf.rs":"7cfbe40095c70dfc42ebe1ed2cb59c84b557a89c09e8925842efd76be226bd12","benches/bytes.rs":"dd7a4c89e1bb1d7490d0532e19c50634c118bfbfd32d5b1c189b4f96fcce381e","benches/bytes_mut.rs":"e2510665597135634c96fcb85e11519a8cf0363d51460d87821229cf1745b16b","ci/azure-cross-compile.yml":"93d711ef0d66262f762624f82deb0b61afd69637e9a6cfe38d18ad84cd09781d","ci/azure-deploy-docs.yml":"fce86e75cb8bc61aca7513cd6afa5ebe0fff8963beda7d6775e341945bec7eb2","ci/azure-install-rust.yml":"898f3dd92859375bdc14b7449a9da56860936d0e77e9de5d2505663d22abd95e","ci/azure-loom.yml":"c1e8782e855b27d26c022bcf2b34239ed5b0a7de2802de68fd7140566e175317","ci/azure-test-stable.yml":"e8a264a813f17b62db1ca1c7e34ba1842a87cdc5ad4a591c1643af0a8a4057f6","ci/azure-tsan.yml":"3996de625bf276ee16cc815809a3c312d5e9fe62424c38d2e1bc97614caf7df3","ci/tsan":"5194270c4e37b1a72e890c98eb2a4aae5f5506fb26a67af3d2834360d2e3d3c2","src/buf/buf_impl.rs":"d921c3171094f824bba4ec3bd69f07ce47257af257741a3cb0ff96887f5f5bd0","src/buf/buf_mut.rs":"289a9348aa2788e0cc12419d311c89c0e87a5e84d62bd8cd71f045924eb0349f","src/buf/ext/chain.rs":"d526cd39d870b7ae8c08e3bd2bc9e7770e9d014b9d9360246dd42c236b6400db","src/buf/ext/limit.rs":"99a42933ac6e309ee5b87818f9560ff041a3e388e8cef18b78ccfd00e3c5eec9","src/buf/ext/mod.rs":"aa2b370a4b44cd7c56ef7c5b07bdaf3723efe3cc465cef358df56433881503b3","src/buf/ext/reader.rs":"d48f07cb1ae0404a224162509fd356eb217b5f8ab020403467491445631616b1","src/buf/ext/take.rs":"fa1009c96175fc67a66f5a8d013140fed7cf0199fefe49bcd4ace82b7a82741b","src/buf/ext/writer.rs":"f01022d4589cee78e36c96032d01e68b6d559062d549e35132a3af869099a2d0","src/buf/iter.rs":"6de36052c0f428d912cea4055fd5c027038f70d369e881e42b6ada6aa9ea92c2","src/buf/mod.rs":"4f66903ca61fe88513c23664a4f33f26c00e4218fbc607e7f52981ba66b90456","src/buf/vec_deque.rs":"5a4063961d10380c1ab3681f8b3f6201112766d9f57a63e2861dc9f2b134668d","src/bytes.rs":"5af1de291faa0344fd7ebf6c1a5834f04aa9f9a7f1b405c8173c31819dd27ca2","src/bytes_mut.rs":"28af39ed6576df6be1c0e57d526ba4f7dd9d50d0d7b0767a3da54940f9fb3417","src/debug.rs":"0875de8307c223bce68e861bc78917e0ad7ef00d75966c0151a0b1aa83a6521a","src/hex.rs":"39c8ee531a45a25b8ef085b4279a9ba7f3b488e4d36c4f80d8769e04b1e51bfd","src/lib.rs":"7fedc5dee1f1d6968ccdccc84514003b1293a22a4b712b4557b49fa57d0752b2","src/loom.rs":"70263b3847d1e4960450a64cb34a87947eaa73755b45977d151265c13ebe4598","src/serde.rs":"c42e0644bed431852445433ac0d6e46f04891e40c046456350323dd3f7b8cf1c","tests/test_buf.rs":"dd3a83218bf5bcc277a8aa1c59c7ed6deeb7e752252b01bce5be4219e65a3e4f","tests/test_buf_mut.rs":"de50fcb03c984f299a84131829b72e351263541c592eec2c23e7ff4504c8e376","tests/test_bytes.rs":"a3b429df530ad90d450d236e893705b218b0319d61b074e9445715df56a15416","tests/test_chain.rs":"d3dab042b20b35e865af1101d78db002878a6604a0a4f4b7901bb1ee98f60684","tests/test_debug.rs":"5b425e056a32d0319d1857b54c88cf58952397bda6fee26b39c624d6c1444eee","tests/test_iter.rs":"95c531b984bcd9b60222b31558925f9662a38b409e731e4aaaafa904b1a64896","tests/test_reader.rs":"1b782d370c757dac14d59df1c4432a25fd8209cbe31b07fa4c380f5b82eec409","tests/test_serde.rs":"2cd4426bfa3a886745dd6958aab21c3493d1116b961acbbf35ec2866c2168a52","tests/test_take.rs":"998d16facf37fa0b2358e7aa42380279d4466d8dde2a3f8c1ae8a082bb37b180"},"package":"10004c15deb332055f7a4a208190aed362cf9a7c2f6ab70a305fba50e1105f38"}
\ No newline at end of file
+{"files":{"CHANGELOG.md":"7c1c6fe9fa6aa8a155d4a04dab5d4e3abadb349121886b2f24252db0e45fba51","Cargo.toml":"bb5072cd9bad83919ed35f49f3a7f88b608a0150d6ccdcbb4bf17dfb3c64ef3f","LICENSE":"45f522cacecb1023856e46df79ca625dfc550c94910078bd8aec6e02880b3d42","README.md":"2c2f6f1a240ad375f9dbd8e7f023510b645d98e327ea0a42ba339c94fd9baaa9","benches/buf.rs":"b0f4f1130081680f6f99d1efd49a75bd1d97d9a30117b7ad9525c96b7c8968e6","benches/bytes.rs":"dc5289a9ce82be35e71ed5853ab33aa108a30460e481135f6058fe4d2f7dc15e","benches/bytes_mut.rs":"1326fe6224b26826228e02b4133151e756f38152c2d9cfe66adf83af76c3ec98","ci/test-stable.sh":"6e010f1a95b72fea7bebdd217fda78427f3eb07b1e753f79507c71d982b2d38a","ci/tsan.sh":"466b86b19225dd26c756cf2252cb1973f87a145642c99364b462ed7ceb55c7dd","src/buf/buf_impl.rs":"fe1bc64bb9aef5b57d83901268f89bf148490e71bebc340c7ecc40ff95bcfb70","src/buf/buf_mut.rs":"d226189d9db76c9023537dcca0687aa5dd25851a9052d19154de8ee9b25bdee3","src/buf/ext/chain.rs":"337f58e1a8da5b4768e55921ff394f4ba3a0c6d476448fd5bceab6f3c1db1b3e","src/buf/ext/limit.rs":"a705d7cf38f9a11a904d6ee5e7afea83e9abdf8f454bb8e16b407b0e055dc11a","src/buf/ext/mod.rs":"ba2fa392c61b7429530c71797114e3f09d9b6b750b6f77f57fde964d2b218bc4","src/buf/ext/reader.rs":"ee4733fa2c2d893c6df8151c2333a46171619e8a45ec9bae863edc8deb438ac5","src/buf/ext/take.rs":"e92be765539b8b0c1cb67a01b691319cccd35fc098f2bb59ced3bbbe41ee0257","src/buf/ext/writer.rs":"3c52df6e73d09935d37bed9a05689c1966952f980b85b40aaab05081ec7ef6d8","src/buf/iter.rs":"a0de69367fa61d0d1c6c2ff4b4d337de9c5f4213d0c86e083226cf409666d860","src/buf/mod.rs":"4f8e3b4c4b69b7d004306d458ad835801e53659b38ca08312d7217d82da4c64f","src/buf/vec_deque.rs":"5a4063961d10380c1ab3681f8b3f6201112766d9f57a63e2861dc9f2b134668d","src/bytes.rs":"8c3aa5fe425604206ffc1b85a8bff5a9be38917786453450955984523f829cec","src/bytes_mut.rs":"e276f74da841ab65ca681cb09820de98aa2e9837dd975ed564b1a9be40440cf3","src/fmt/debug.rs":"19ebe7e5516e40ab712995f3ec2e0ba78ddfa905cce117e6d01e8eb330f3970a","src/fmt/hex.rs":"13755ec6f1b79923e1f1a05c51b179a38c03c40bb8ed2db0210e8901812e61e7","src/fmt/mod.rs":"176da4e359da99b8e5cf16e480cb7b978f574876827f1b9bb9c08da4d74ac0f5","src/lib.rs":"9b96e2a011a782ceb82428e6b71fd212a46bc186bd152102018c7b6428a0d441","src/loom.rs":"5dc97a5afce14875a66e44cbf0afa67e084c8b6b8c560bc14e7a70ef73aee96e","src/serde.rs":"3ecd7e828cd4c2b7db93c807cb1548fad209e674df493edf7cda69a7b04d405d","tests/test_buf.rs":"3ca99c58f470e7c4beb18e5dc69250ce541dd8ac96b88fb1162640510a735ada","tests/test_buf_mut.rs":"56636e439cb07af2fabdfb60a08995829680c9730a8ebe5c6ad2f54dbf208e32","tests/test_bytes.rs":"3ec0a82ce98fea633ed7d635caca21cd8035d0c9ea4287d1cc0199e167a4a3c1","tests/test_bytes_odd_alloc.rs":"87d51d4ab6ad98193b140ea8158f6631eba985a204c2ea94d34b3bb157791a16","tests/test_bytes_vec_alloc.rs":"2b686b6ab44f924e69d8270a4f256eb3626a3b4db8c1919b74bc422c10124899","tests/test_chain.rs":"71772fbc0bab72a697bd85c6c1be0eddfe7d7dc4f4737a0cd53be4ad191d076b","tests/test_debug.rs":"13299107172809e8cbbd823964ac9450cd0d6b6de79f2e6a2e0f44b9225a0593","tests/test_iter.rs":"c1f46823df26a90139645fd8728a03138edd95b2849dfec830452a80ddd9726d","tests/test_reader.rs":"9c94e164aa7de4c10966f8084ad04d06f4e9c66e156d017d194a1dac3dfc6619","tests/test_serde.rs":"2691f891796ba259de0ecf926de05c514f4912cc5fcd3e6a1591efbcd23ed4d0","tests/test_take.rs":"975aa2e216b6a3c939b31e41ecfbb3a90938096413a14a2ae986c842d2250180"},"package":"0e4cec68f03f32e44924783795810fa50a7035d8c8ebe78580ad7e6c703fba38"}
\ No newline at end of file
diff --git a/third_party/rust/bytes/CHANGELOG.md b/third_party/rust/bytes/CHANGELOG.md
index 960bd79ed43b9fb17fa48362a03dd5aa0e0f3638..1b821da4286483b3484835df31affff8a481a3a3 100644
--- a/third_party/rust/bytes/CHANGELOG.md
+++ b/third_party/rust/bytes/CHANGELOG.md
@@ -1,3 +1,31 @@
+# 0.5.6 (July 13, 2020)
+
+- Improve `BytesMut` to reuse buffer when fully `advance`d.
+- Mark `BytesMut::{as_mut, set_len}` with `#[inline]`.
+- Relax synchronization when cloning in shared vtable of `Bytes`.
+- Move `loom` to `dev-dependencies`.
+
+# 0.5.5 (June 18, 2020)
+
+### Added
+- Allow using the `serde` feature in `no_std` environments (#385).
+
+### Fix
+- Fix `BufMut::advance_mut` to panic if advanced passed the capacity (#354)..
+- Fix `BytesMut::freeze` ignoring amount previously `advance`d (#352).
+
+# 0.5.4 (January 23, 2020)
+
+### Added
+- Make `Bytes::new` a `const fn`.
+- Add `From<BytesMut>` for `Bytes`.
+
+### Fix
+- Fix reversed arguments in `PartialOrd` for `Bytes`.
+- Fix `Bytes::truncate` losing original capacity when repr is an unshared `Vec`.
+- Fix `Bytes::from(Vec)` when allocator gave `Vec` a pointer with LSB set.
+- Fix panic in `Bytes::slice_ref` if argument is an empty slice.
+
 # 0.5.3 (December 12, 2019)
 
 ### Added
diff --git a/third_party/rust/bytes/Cargo.toml b/third_party/rust/bytes/Cargo.toml
index 2a33deff79d0e055cd91fd860b61181069305777..81a7224790efa9440850366b0e7617ad309f6c8e 100644
--- a/third_party/rust/bytes/Cargo.toml
+++ b/third_party/rust/bytes/Cargo.toml
@@ -13,7 +13,7 @@
 [package]
 edition = "2018"
 name = "bytes"
-version = "0.5.3"
+version = "0.5.6"
 authors = ["Carl Lerche <me@carllerche.com>", "Sean McArthur <sean@seanmonstar.com>"]
 description = "Types and traits for working with bytes"
 documentation = "https://docs.rs/bytes"
@@ -23,14 +23,15 @@ categories = ["network-programming", "data-structures"]
 license = "MIT"
 repository = "https://github.com/tokio-rs/bytes"
 [dependencies.serde]
-version = "1.0"
+version = "1.0.60"
+features = ["alloc"]
 optional = true
-[dev-dependencies.loom]
-version = "0.2.10"
-
+default-features = false
 [dev-dependencies.serde_test]
 version = "1.0"
 
 [features]
 default = ["std"]
 std = []
+[target."cfg(loom)".dev-dependencies.loom]
+version = "0.3"
diff --git a/third_party/rust/bytes/README.md b/third_party/rust/bytes/README.md
index afc2ed21cb495615934d0cdb7f710c1b5b5c30ee..73c43abc8990907e72cd3f6c6706742c8d5fa74f 100644
--- a/third_party/rust/bytes/README.md
+++ b/third_party/rust/bytes/README.md
@@ -3,12 +3,12 @@
 A utility library for working with bytes.
 
 [![Crates.io][crates-badge]][crates-url]
-[![Build Status][azure-badge]][azure-url]
+[![Build Status][ci-badge]][ci-url]
 
 [crates-badge]: https://img.shields.io/crates/v/bytes.svg
 [crates-url]: https://crates.io/crates/bytes
-[azure-badge]: https://dev.azure.com/tokio-rs/bytes/_apis/build/status/tokio-rs.bytes?branchName=master
-[azure-url]: https://dev.azure.com/tokio-rs/bytes/_build/latest?definitionId=3&branchName=master
+[ci-badge]: https://github.com/tokio-rs/bytes/workflows/CI/badge.svg
+[ci-url]: https://github.com/tokio-rs/bytes/actions
 
 [Documentation](https://docs.rs/bytes)
 
@@ -45,4 +45,3 @@ This project is licensed under the [MIT license](LICENSE).
 Unless you explicitly state otherwise, any contribution intentionally submitted
 for inclusion in `bytes` by you, shall be licensed as MIT, without any additional
 terms or conditions.
-
diff --git a/third_party/rust/bytes/azure-pipelines.yml b/third_party/rust/bytes/azure-pipelines.yml
deleted file mode 100644
index 18b59745d145a13ec692e2998049ef99a59b00ec..0000000000000000000000000000000000000000
--- a/third_party/rust/bytes/azure-pipelines.yml
+++ /dev/null
@@ -1,68 +0,0 @@
-trigger: ["master"]
-pr: ["master"]
-
-jobs:
-# Check formatting
-# - template: ci/azure-rustfmt.yml
-#   parameters:
-#     name: rustfmt
-
-# Apply clippy lints
-# - template: ci/azure-clippy.yml
-#   parameters:
-#     name: clippy
-
-# This represents the minimum Rust version supported by
-# Bytes. Updating this should be done in a dedicated PR.
-#
-# Tests are not run as tests may require newer versions of
-# rust.
-- template: ci/azure-test-stable.yml
-  parameters:
-    name: minrust
-    rust_version: 1.39.0
-    cmd: check
-
-# Stable
-- template: ci/azure-test-stable.yml
-  parameters:
-    name: stable
-    cross: true
-    features:
-      - serde
-
-# Nightly
-- template: ci/azure-test-stable.yml
-  parameters:
-    name: nightly
-    # Pin nightly to avoid being impacted by breakage
-    rust_version: nightly-2019-09-25
-    benches: true
-
-# Run tests on some extra platforms
-- template: ci/azure-cross-compile.yml
-  parameters:
-    name: cross
-
-# Sanitizers
-- template: ci/azure-tsan.yml
-  parameters:
-    name: tsan
-    rust_version: nightly
-
-# Loom
-- template: ci/azure-loom.yml
-  parameters:
-    name: loom
-    rust_version: stable
-
-
-- template: ci/azure-deploy-docs.yml
-  parameters:
-    dependsOn:
-      # - rustfmt
-      # - clippy
-      - stable
-      - nightly
-      - minrust
-      - cross
diff --git a/third_party/rust/bytes/benches/buf.rs b/third_party/rust/bytes/benches/buf.rs
index 0c9a1d955767ff8808a32c07e5f70014e494285a..77b0633eeccea52a43cb08a9827b2df43be3fc7d 100644
--- a/third_party/rust/bytes/benches/buf.rs
+++ b/third_party/rust/bytes/benches/buf.rs
@@ -1,10 +1,10 @@
 #![feature(test)]
-#![deny(warnings, rust_2018_idioms)]
+#![warn(rust_2018_idioms)]
 
 extern crate test;
 
-use test::Bencher;
 use bytes::Buf;
+use test::Bencher;
 
 /// Dummy Buf implementation
 struct TestBuf {
diff --git a/third_party/rust/bytes/benches/bytes.rs b/third_party/rust/bytes/benches/bytes.rs
index 9c36e6081b63440f39c064f0b6205b7c2b7af8d5..c5b84124f1732b037162f2bff75202ee66308a4d 100644
--- a/third_party/rust/bytes/benches/bytes.rs
+++ b/third_party/rust/bytes/benches/bytes.rs
@@ -1,10 +1,10 @@
 #![feature(test)]
-#![deny(warnings, rust_2018_idioms)]
+#![warn(rust_2018_idioms)]
 
 extern crate test;
 
-use test::Bencher;
 use bytes::Bytes;
+use test::Bencher;
 
 #[bench]
 fn deref_unique(b: &mut Bencher) {
@@ -42,7 +42,8 @@ fn deref_static(b: &mut Bencher) {
 
 #[bench]
 fn clone_static(b: &mut Bencher) {
-    let bytes = Bytes::from_static("hello world 1234567890 and have a good byte 0987654321".as_bytes());
+    let bytes =
+        Bytes::from_static("hello world 1234567890 and have a good byte 0987654321".as_bytes());
 
     b.iter(|| {
         for _ in 0..1024 {
diff --git a/third_party/rust/bytes/benches/bytes_mut.rs b/third_party/rust/bytes/benches/bytes_mut.rs
index ded1d14864df418adff69116b547846bc2e7c398..b069436210058094f410038801b9e3f1280ad036 100644
--- a/third_party/rust/bytes/benches/bytes_mut.rs
+++ b/third_party/rust/bytes/benches/bytes_mut.rs
@@ -1,10 +1,10 @@
 #![feature(test)]
-#![deny(warnings, rust_2018_idioms)]
+#![warn(rust_2018_idioms)]
 
 extern crate test;
 
-use test::Bencher;
 use bytes::{BufMut, BytesMut};
+use test::Bencher;
 
 #[bench]
 fn alloc_small(b: &mut Bencher) {
@@ -29,7 +29,6 @@ fn alloc_big(b: &mut Bencher) {
     })
 }
 
-
 #[bench]
 fn deref_unique(b: &mut Bencher) {
     let mut buf = BytesMut::with_capacity(4096);
@@ -92,7 +91,9 @@ fn deref_two(b: &mut Bencher) {
 
 #[bench]
 fn clone_frozen(b: &mut Bencher) {
-    let bytes = BytesMut::from(&b"hello world 1234567890 and have a good byte 0987654321"[..]).split().freeze();
+    let bytes = BytesMut::from(&b"hello world 1234567890 and have a good byte 0987654321"[..])
+        .split()
+        .freeze();
 
     b.iter(|| {
         for _ in 0..1024 {
@@ -137,7 +138,9 @@ fn fmt_write(b: &mut Bencher) {
     b.iter(|| {
         let _ = write!(buf, "{}", s);
         test::black_box(&buf);
-        unsafe { buf.set_len(0); }
+        unsafe {
+            buf.set_len(0);
+        }
     })
 }
 
@@ -152,7 +155,9 @@ fn bytes_mut_extend(b: &mut Bencher) {
             buf.extend(&data);
         }
         test::black_box(&buf);
-        unsafe { buf.set_len(0); }
+        unsafe {
+            buf.set_len(0);
+        }
     });
 }
 
@@ -169,7 +174,9 @@ fn put_slice_bytes_mut(b: &mut Bencher) {
             buf.put_slice(&data);
         }
         test::black_box(&buf);
-        unsafe { buf.set_len(0); }
+        unsafe {
+            buf.set_len(0);
+        }
     });
 }
 
@@ -184,7 +191,9 @@ fn put_u8_bytes_mut(b: &mut Bencher) {
             buf.put_u8(b'x');
         }
         test::black_box(&buf);
-        unsafe { buf.set_len(0); }
+        unsafe {
+            buf.set_len(0);
+        }
     });
 }
 
@@ -199,7 +208,9 @@ fn put_slice_vec(b: &mut Bencher) {
             buf.put_slice(&data);
         }
         test::black_box(&buf);
-        unsafe { buf.set_len(0); }
+        unsafe {
+            buf.set_len(0);
+        }
     });
 }
 
@@ -214,7 +225,9 @@ fn put_u8_vec(b: &mut Bencher) {
             buf.put_u8(b'x');
         }
         test::black_box(&buf);
-        unsafe { buf.set_len(0); }
+        unsafe {
+            buf.set_len(0);
+        }
     });
 }
 
@@ -229,7 +242,9 @@ fn put_slice_vec_extend(b: &mut Bencher) {
             buf.extend_from_slice(&data);
         }
         test::black_box(&buf);
-        unsafe { buf.set_len(0); }
+        unsafe {
+            buf.set_len(0);
+        }
     });
 }
 
@@ -244,6 +259,8 @@ fn put_u8_vec_push(b: &mut Bencher) {
             buf.push(b'x');
         }
         test::black_box(&buf);
-        unsafe { buf.set_len(0); }
+        unsafe {
+            buf.set_len(0);
+        }
     });
 }
diff --git a/third_party/rust/bytes/ci/azure-cross-compile.yml b/third_party/rust/bytes/ci/azure-cross-compile.yml
deleted file mode 100644
index be46ca3460374bb93f09bdaa853a57994c869c0d..0000000000000000000000000000000000000000
--- a/third_party/rust/bytes/ci/azure-cross-compile.yml
+++ /dev/null
@@ -1,46 +0,0 @@
-parameters:
-  cmd: build
-  rust_version: stable
-
-jobs:
-- job: ${{ parameters.name }}
-  displayName: Cross
-  strategy:
-    matrix:
-      i686:
-        vmImage: ubuntu-16.04
-        target: i686-unknown-linux-gnu
-      armv7:
-        vmImage: ubuntu-16.04
-        target: armv7-unknown-linux-gnueabihf
-      powerpc:
-        vmImage: ubuntu-16.04
-        target: powerpc-unknown-linux-gnu
-      powerpc64:
-        vmImage: ubuntu-16.04
-        target: powerpc64-unknown-linux-gnu
-      wasm:
-        vmImage: ubuntu-16.04
-        target: wasm32-unknown-unknown
-  pool:
-    vmImage: $(vmImage)
-
-  steps:
-    - template: azure-install-rust.yml
-      parameters:
-        rust_version: ${{parameters.rust_version}}
-
-    - script: cargo install cross
-      displayName: Install cross
-      condition: not(eq(variables['target'], 'wasm32-unknown-unknown'))
-
-    - script: cross ${{ parameters.cmd }} --target $(target)
-      displayName: cross ${{ parameters.cmd }} --target $(target)
-      condition: not(eq(variables['target'], 'wasm32-unknown-unknown'))
-
-    # WASM support
-    - script: |
-        rustup target add $(target)
-        cargo build --target $(target)
-      displayName: cargo build --target $(target)
-      condition: eq(variables['target'], 'wasm32-unknown-unknown')
diff --git a/third_party/rust/bytes/ci/azure-deploy-docs.yml b/third_party/rust/bytes/ci/azure-deploy-docs.yml
deleted file mode 100644
index 52ac48fcdcf0b315c5a08d3d382e40d19a3bf37a..0000000000000000000000000000000000000000
--- a/third_party/rust/bytes/ci/azure-deploy-docs.yml
+++ /dev/null
@@ -1,39 +0,0 @@
-parameters:
-  dependsOn: []
-
-jobs:
-- job: documentation
-  displayName: 'Deploy API Documentation'
-  condition: and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/master'))
-  pool:
-    vmImage: 'Ubuntu 16.04'
-  dependsOn:
-    - ${{ parameters.dependsOn }}
-  steps:
-  - template: azure-install-rust.yml
-    parameters:
-      rust_version: stable
-  - script: |
-      cargo doc --no-deps
-      cp -R target/doc '$(Build.BinariesDirectory)'
-    displayName: 'Generate Documentation'
-  - script: |
-      set -e
-
-      git --version
-      ls -la
-      git init
-      git config user.name 'Deployment Bot (from Azure Pipelines)'
-      git config user.email 'deploy@tokio-rs.com'
-      git config --global credential.helper 'store --file ~/.my-credentials'
-      printf "protocol=https\nhost=github.com\nusername=carllerche\npassword=%s\n\n" "$GITHUB_TOKEN" | git credential-store --file ~/.my-credentials store
-      git remote add origin https://github.com/tokio-rs/bytes
-      git checkout -b gh-pages
-      git add .
-      git commit -m 'Deploy Bytes API documentation'
-      git push -f origin gh-pages
-    env:
-      GITHUB_TOKEN: $(githubPersonalToken)
-    workingDirectory: '$(Build.BinariesDirectory)'
-    displayName: 'Deploy Documentation'
-
diff --git a/third_party/rust/bytes/ci/azure-install-rust.yml b/third_party/rust/bytes/ci/azure-install-rust.yml
deleted file mode 100644
index 02176592a6f1f9d1af936778e2318263c0edc0b8..0000000000000000000000000000000000000000
--- a/third_party/rust/bytes/ci/azure-install-rust.yml
+++ /dev/null
@@ -1,33 +0,0 @@
-steps:
-  # Linux and macOS.
-  - script: |
-      set -e
-      curl https://sh.rustup.rs -sSf | sh -s -- -y --default-toolchain none
-      export PATH=$PATH:$HOME/.cargo/bin
-      rustup toolchain install $RUSTUP_TOOLCHAIN
-      rustup default $RUSTUP_TOOLCHAIN
-      echo "##vso[task.setvariable variable=PATH;]$PATH:$HOME/.cargo/bin"
-    env:
-      RUSTUP_TOOLCHAIN: ${{parameters.rust_version}}
-    displayName: "Install rust (*nix)"
-    condition: not(eq(variables['Agent.OS'], 'Windows_NT'))
-
-  # Windows.
-  - script: |
-      curl -sSf -o rustup-init.exe https://win.rustup.rs
-      rustup-init.exe -y --default-toolchain none
-      set PATH=%PATH%;%USERPROFILE%\.cargo\bin
-      rustup toolchain install %RUSTUP_TOOLCHAIN%
-      rustup default %RUSTUP_TOOLCHAIN%
-      echo "##vso[task.setvariable variable=PATH;]%PATH%;%USERPROFILE%\.cargo\bin"
-    env:
-      RUSTUP_TOOLCHAIN: ${{parameters.rust_version}}
-    displayName: "Install rust (windows)"
-    condition: eq(variables['Agent.OS'], 'Windows_NT')
-
-  # All platforms.
-  - script: |
-        rustup toolchain list
-        rustc -Vv
-        cargo -V
-    displayName: Query rust and cargo versions
diff --git a/third_party/rust/bytes/ci/azure-loom.yml b/third_party/rust/bytes/ci/azure-loom.yml
deleted file mode 100644
index 1db9c3afe1088ab7e54ee69dcd73cb5bae9e2238..0000000000000000000000000000000000000000
--- a/third_party/rust/bytes/ci/azure-loom.yml
+++ /dev/null
@@ -1,15 +0,0 @@
-jobs:
-- job: ${{parameters.name}}
-  displayName: Loom tests
-  pool:
-    vmImage: ubuntu-16.04
-
-  steps:
-  - template: azure-install-rust.yml
-    parameters:
-      rust_version: ${{parameters.rust_version}}
-
-  - script: RUSTFLAGS="--cfg loom" cargo test --lib
-    displayName: RUSTFLAGS="--cfg loom" cargo test --lib
-
-
diff --git a/third_party/rust/bytes/ci/azure-test-stable.yml b/third_party/rust/bytes/ci/azure-test-stable.yml
deleted file mode 100644
index e543eeeb438f49829283dff0a0a808b687ac80c2..0000000000000000000000000000000000000000
--- a/third_party/rust/bytes/ci/azure-test-stable.yml
+++ /dev/null
@@ -1,50 +0,0 @@
-parameters:
-  cmd: test
-  rust_version: stable
-  features: []
-
-jobs:
-- job: ${{ parameters.name }}
-  displayName: ${{ parameters.displayName }}
-  strategy:
-    matrix:
-      Linux:
-        vmImage: ubuntu-16.04
-
-      ${{ if parameters.cross }}:
-        MacOS:
-          vmImage: macOS-10.13
-        Windows:
-          vmImage: vs2017-win2016
-  pool:
-    vmImage: $(vmImage)
-
-  steps:
-  - template: azure-install-rust.yml
-    parameters:
-      rust_version: ${{parameters.rust_version}}
-
-  # Run with default crate features
-  - script: cargo ${{ parameters.cmd }}
-    displayName: cargo ${{ parameters.cmd }}
-
-  # Run with each specified feature
-  - ${{ each feature in parameters.features }}:
-    - script: cargo ${{ parameters.cmd }} --features ${{ feature }}
-      displayName: cargo ${{ parameters.cmd }} --features ${{ feature }}
-
-  - ${{ if eq(parameters.cmd, 'test') }}:
-    - script: cargo doc --no-deps
-      displayName: cargo doc --no-deps
-
-  - ${{ if parameters.benches }}:
-    - script: cargo check --benches
-      displayName: Check benchmarks
-
-  # Run with all features
-  - script: cargo ${{ parameters.cmd }} --all-features
-    displayName: cargo ${{ parameters.cmd }} --all-features
-
-  # Run with no default features
-  - script: cargo check --no-default-features
-    displayName: cargo check --no-default-features
diff --git a/third_party/rust/bytes/ci/azure-tsan.yml b/third_party/rust/bytes/ci/azure-tsan.yml
deleted file mode 100644
index 198b187abf038abbd32182ac8b59e0eab621baeb..0000000000000000000000000000000000000000
--- a/third_party/rust/bytes/ci/azure-tsan.yml
+++ /dev/null
@@ -1,26 +0,0 @@
-jobs:
-- job: ${{ parameters.name }}
-  displayName: TSAN
-  pool:
-    vmImage: ubuntu-16.04
-
-  steps:
-  - template: azure-install-rust.yml
-    parameters:
-      rust_version: ${{ parameters.rust_version }}
-
-  - script: |
-      set -e
-
-      export RUST_TEST_THREADS=1
-      export ASAN_OPTIONS="detect_odr_violation=0 detect_leaks=0"
-      export TSAN_OPTIONS="suppressions=`pwd`/ci/tsan"
-
-      # Run address sanitizer
-      RUSTFLAGS="-Z sanitizer=address" \
-      cargo test --target x86_64-unknown-linux-gnu --test test_bytes --test test_buf --test test_buf_mut
-
-      # Run thread sanitizer
-      RUSTFLAGS="-Z sanitizer=thread" \
-      cargo test --target x86_64-unknown-linux-gnu --test test_bytes --test test_buf --test test_buf_mut
-    displayName: TSAN / MSAN
diff --git a/third_party/rust/bytes/ci/test-stable.sh b/third_party/rust/bytes/ci/test-stable.sh
new file mode 100644
index 0000000000000000000000000000000000000000..01a32f5a661c68ac8abd06fa14e444fcabe615f1
--- /dev/null
+++ b/third_party/rust/bytes/ci/test-stable.sh
@@ -0,0 +1,27 @@
+#!/bin/bash
+
+set -ex
+
+cmd="${1:-test}"
+
+# Install cargo-hack for feature flag test
+cargo install cargo-hack
+
+# Run with each feature
+# * --each-feature includes both default/no-default features
+# * --optional-deps is needed for serde feature
+cargo hack "${cmd}" --each-feature --optional-deps
+# Run with all features
+cargo "${cmd}" --all-features
+
+cargo doc --no-deps --all-features
+
+if [[ "${RUST_VERSION}" == "nightly"* ]]; then
+    # Check benchmarks
+    cargo check --benches
+
+    # Check minimal versions
+    cargo clean
+    cargo update -Zminimal-versions
+    cargo check --all-features
+fi
diff --git a/third_party/rust/bytes/ci/tsan.sh b/third_party/rust/bytes/ci/tsan.sh
new file mode 100644
index 0000000000000000000000000000000000000000..ca520bd7fd0492d1c73fdd0a12d51bfe7b2f41d4
--- /dev/null
+++ b/third_party/rust/bytes/ci/tsan.sh
@@ -0,0 +1,13 @@
+#!/bin/bash
+
+set -ex
+
+export ASAN_OPTIONS="detect_odr_violation=0 detect_leaks=0"
+
+# Run address sanitizer
+RUSTFLAGS="-Z sanitizer=address" \
+cargo test --target x86_64-unknown-linux-gnu --test test_bytes --test test_buf --test test_buf_mut
+
+# Run thread sanitizer
+RUSTFLAGS="-Z sanitizer=thread" \
+cargo -Zbuild-std test --target x86_64-unknown-linux-gnu --test test_bytes --test test_buf --test test_buf_mut
diff --git a/third_party/rust/bytes/src/buf/buf_impl.rs b/third_party/rust/bytes/src/buf/buf_impl.rs
index 843db718f88ad72056ae612bf399817a5610caa9..5cd7c686e504cf88af563ad64991e44eb3a1a10f 100644
--- a/third_party/rust/bytes/src/buf/buf_impl.rs
+++ b/third_party/rust/bytes/src/buf/buf_impl.rs
@@ -1,22 +1,23 @@
-use core::{cmp, ptr, mem};
+use core::{cmp, mem, ptr};
 
 #[cfg(feature = "std")]
 use std::io::IoSlice;
 
-use alloc::{boxed::Box};
+use alloc::boxed::Box;
 
 macro_rules! buf_get_impl {
-    ($this:ident, $typ:tt::$conv:tt) => ({
+    ($this:ident, $typ:tt::$conv:tt) => {{
         const SIZE: usize = mem::size_of::<$typ>();
-         // try to convert directly from the bytes
-         // this Option<ret> trick is to avoid keeping a borrow on self
-         // when advance() is called (mut borrow) and to call bytes() only once
-        let ret =  $this.bytes().get(..SIZE).map(|src| unsafe {
-            $typ::$conv(*(src as *const _ as *const [_; SIZE]))
-        });
+        // try to convert directly from the bytes
+        // this Option<ret> trick is to avoid keeping a borrow on self
+        // when advance() is called (mut borrow) and to call bytes() only once
+        let ret = $this
+            .bytes()
+            .get(..SIZE)
+            .map(|src| unsafe { $typ::$conv(*(src as *const _ as *const [_; SIZE])) });
 
         if let Some(ret) = ret {
-             // if the direct conversion was possible, advance and return
+            // if the direct conversion was possible, advance and return
             $this.advance(SIZE);
             return ret;
         } else {
@@ -25,8 +26,8 @@ macro_rules! buf_get_impl {
             $this.copy_to_slice(&mut buf); // (do the advance)
             return $typ::$conv(buf);
         }
-    });
-    (le => $this:ident, $typ:tt, $len_to_read:expr) => ({
+    }};
+    (le => $this:ident, $typ:tt, $len_to_read:expr) => {{
         debug_assert!(mem::size_of::<$typ>() >= $len_to_read);
 
         // The same trick as above does not improve the best case speed.
@@ -34,12 +35,12 @@ macro_rules! buf_get_impl {
         let mut buf = [0; (mem::size_of::<$typ>())];
         $this.copy_to_slice(&mut buf[..($len_to_read)]);
         return $typ::from_le_bytes(buf);
-    });
+    }};
     (be => $this:ident, $typ:tt, $len_to_read:expr) => {{
         debug_assert!(mem::size_of::<$typ>() >= $len_to_read);
 
         let mut buf = [0; (mem::size_of::<$typ>())];
-        $this.copy_to_slice(&mut buf[mem::size_of::<$typ>()-($len_to_read)..]);
+        $this.copy_to_slice(&mut buf[mem::size_of::<$typ>() - ($len_to_read)..]);
         return $typ::from_be_bytes(buf);
     }};
 }
@@ -251,8 +252,7 @@ pub trait Buf {
                 let src = self.bytes();
                 cnt = cmp::min(src.len(), dst.len() - off);
 
-                ptr::copy_nonoverlapping(
-                    src.as_ptr(), dst[off..].as_mut_ptr(), cnt);
+                ptr::copy_nonoverlapping(src.as_ptr(), dst[off..].as_mut_ptr(), cnt);
 
                 off += cnt;
             }
@@ -810,109 +810,108 @@ pub trait Buf {
 }
 
 macro_rules! deref_forward_buf {
-    () => (
-    fn remaining(&self) -> usize {
-        (**self).remaining()
-    }
-
-    fn bytes(&self) -> &[u8] {
-        (**self).bytes()
-    }
+    () => {
+        fn remaining(&self) -> usize {
+            (**self).remaining()
+        }
 
-    #[cfg(feature = "std")]
-    fn bytes_vectored<'b>(&'b self, dst: &mut [IoSlice<'b>]) -> usize {
-        (**self).bytes_vectored(dst)
-    }
+        fn bytes(&self) -> &[u8] {
+            (**self).bytes()
+        }
 
-    fn advance(&mut self, cnt: usize) {
-        (**self).advance(cnt)
-    }
+        #[cfg(feature = "std")]
+        fn bytes_vectored<'b>(&'b self, dst: &mut [IoSlice<'b>]) -> usize {
+            (**self).bytes_vectored(dst)
+        }
 
-    fn has_remaining(&self) -> bool {
-        (**self).has_remaining()
-    }
+        fn advance(&mut self, cnt: usize) {
+            (**self).advance(cnt)
+        }
 
-    fn copy_to_slice(&mut self, dst: &mut [u8]) {
-        (**self).copy_to_slice(dst)
-    }
+        fn has_remaining(&self) -> bool {
+            (**self).has_remaining()
+        }
 
-    fn get_u8(&mut self) -> u8 {
-        (**self).get_u8()
-    }
+        fn copy_to_slice(&mut self, dst: &mut [u8]) {
+            (**self).copy_to_slice(dst)
+        }
 
-    fn get_i8(&mut self) -> i8 {
-        (**self).get_i8()
-    }
+        fn get_u8(&mut self) -> u8 {
+            (**self).get_u8()
+        }
 
-    fn get_u16(&mut self) -> u16 {
-        (**self).get_u16()
-    }
+        fn get_i8(&mut self) -> i8 {
+            (**self).get_i8()
+        }
 
-    fn get_u16_le(&mut self) -> u16 {
-        (**self).get_u16_le()
-    }
+        fn get_u16(&mut self) -> u16 {
+            (**self).get_u16()
+        }
 
-    fn get_i16(&mut self) -> i16 {
-        (**self).get_i16()
-    }
+        fn get_u16_le(&mut self) -> u16 {
+            (**self).get_u16_le()
+        }
 
-    fn get_i16_le(&mut self) -> i16 {
-        (**self).get_i16_le()
-    }
+        fn get_i16(&mut self) -> i16 {
+            (**self).get_i16()
+        }
 
-    fn get_u32(&mut self) -> u32 {
-        (**self).get_u32()
-    }
+        fn get_i16_le(&mut self) -> i16 {
+            (**self).get_i16_le()
+        }
 
-    fn get_u32_le(&mut self) -> u32 {
-        (**self).get_u32_le()
-    }
+        fn get_u32(&mut self) -> u32 {
+            (**self).get_u32()
+        }
 
-    fn get_i32(&mut self) -> i32 {
-        (**self).get_i32()
-    }
+        fn get_u32_le(&mut self) -> u32 {
+            (**self).get_u32_le()
+        }
 
-    fn get_i32_le(&mut self) -> i32 {
-        (**self).get_i32_le()
-    }
+        fn get_i32(&mut self) -> i32 {
+            (**self).get_i32()
+        }
 
-    fn get_u64(&mut self) -> u64 {
-        (**self).get_u64()
-    }
+        fn get_i32_le(&mut self) -> i32 {
+            (**self).get_i32_le()
+        }
 
-    fn get_u64_le(&mut self) -> u64 {
-        (**self).get_u64_le()
-    }
+        fn get_u64(&mut self) -> u64 {
+            (**self).get_u64()
+        }
 
-    fn get_i64(&mut self) -> i64 {
-        (**self).get_i64()
-    }
+        fn get_u64_le(&mut self) -> u64 {
+            (**self).get_u64_le()
+        }
 
-    fn get_i64_le(&mut self) -> i64 {
-        (**self).get_i64_le()
-    }
+        fn get_i64(&mut self) -> i64 {
+            (**self).get_i64()
+        }
 
-    fn get_uint(&mut self, nbytes: usize) -> u64 {
-        (**self).get_uint(nbytes)
-    }
+        fn get_i64_le(&mut self) -> i64 {
+            (**self).get_i64_le()
+        }
 
-    fn get_uint_le(&mut self, nbytes: usize) -> u64 {
-        (**self).get_uint_le(nbytes)
-    }
+        fn get_uint(&mut self, nbytes: usize) -> u64 {
+            (**self).get_uint(nbytes)
+        }
 
-    fn get_int(&mut self, nbytes: usize) -> i64 {
-        (**self).get_int(nbytes)
-    }
+        fn get_uint_le(&mut self, nbytes: usize) -> u64 {
+            (**self).get_uint_le(nbytes)
+        }
 
-    fn get_int_le(&mut self, nbytes: usize) -> i64 {
-        (**self).get_int_le(nbytes)
-    }
+        fn get_int(&mut self, nbytes: usize) -> i64 {
+            (**self).get_int(nbytes)
+        }
 
-    fn to_bytes(&mut self) -> crate::Bytes {
-        (**self).to_bytes()
-    }
+        fn get_int_le(&mut self, nbytes: usize) -> i64 {
+            (**self).get_int_le(nbytes)
+        }
 
-    )
+        fn to_bytes(&mut self) -> crate::Bytes {
+            (**self).to_bytes()
+        }
+    };
 }
 
 impl<T: Buf + ?Sized> Buf for &mut T {
@@ -950,7 +949,8 @@ impl Buf for Option<[u8; 1]> {
     }
 
     fn bytes(&self) -> &[u8] {
-        self.as_ref().map(AsRef::as_ref)
+        self.as_ref()
+            .map(AsRef::as_ref)
             .unwrap_or(Default::default())
     }
 
@@ -994,7 +994,8 @@ impl<T: AsRef<[u8]>> Buf for std::io::Cursor<T> {
 
     fn advance(&mut self, cnt: usize) {
         let pos = (self.position() as usize)
-            .checked_add(cnt).expect("overflow");
+            .checked_add(cnt)
+            .expect("overflow");
 
         assert!(pos <= self.get_ref().as_ref().len());
         self.set_position(pos as u64);
diff --git a/third_party/rust/bytes/src/buf/buf_mut.rs b/third_party/rust/bytes/src/buf/buf_mut.rs
index f5ed2a771946e34379888f65b1d6d36d2376acd8..628b240a385cabc8f487fe94cdc2e87881e1ef36 100644
--- a/third_party/rust/bytes/src/buf/buf_mut.rs
+++ b/third_party/rust/bytes/src/buf/buf_mut.rs
@@ -1,9 +1,13 @@
-use core::{cmp, mem::{self, MaybeUninit}, ptr, usize};
+use core::{
+    cmp,
+    mem::{self, MaybeUninit},
+    ptr, usize,
+};
 
 #[cfg(feature = "std")]
 use std::fmt;
 
-use alloc::{vec::Vec, boxed::Box};
+use alloc::{boxed::Box, vec::Vec};
 
 /// A trait for values that provide sequential write access to bytes.
 ///
@@ -226,7 +230,10 @@ pub trait BufMut {
     /// # Panics
     ///
     /// Panics if `self` does not have enough capacity to contain `src`.
-    fn put<T: super::Buf>(&mut self, mut src: T) where Self: Sized {
+    fn put<T: super::Buf>(&mut self, mut src: T)
+    where
+        Self: Sized,
+    {
         assert!(self.remaining_mut() >= src.remaining());
 
         while src.has_remaining() {
@@ -237,14 +244,13 @@ pub trait BufMut {
                 let d = self.bytes_mut();
                 l = cmp::min(s.len(), d.len());
 
-                ptr::copy_nonoverlapping(
-                    s.as_ptr(),
-                    d.as_mut_ptr() as *mut u8,
-                    l);
+                ptr::copy_nonoverlapping(s.as_ptr(), d.as_mut_ptr() as *mut u8, l);
             }
 
             src.advance(l);
-            unsafe { self.advance_mut(l); }
+            unsafe {
+                self.advance_mut(l);
+            }
         }
     }
 
@@ -270,7 +276,12 @@ pub trait BufMut {
     fn put_slice(&mut self, src: &[u8]) {
         let mut off = 0;
 
-        assert!(self.remaining_mut() >= src.len(), "buffer overflow; remaining = {}; src = {}", self.remaining_mut(), src.len());
+        assert!(
+            self.remaining_mut() >= src.len(),
+            "buffer overflow; remaining = {}; src = {}",
+            self.remaining_mut(),
+            src.len()
+        );
 
         while off < src.len() {
             let cnt;
@@ -279,16 +290,14 @@ pub trait BufMut {
                 let dst = self.bytes_mut();
                 cnt = cmp::min(dst.len(), src.len() - off);
 
-                ptr::copy_nonoverlapping(
-                    src[off..].as_ptr(),
-                    dst.as_mut_ptr() as *mut u8,
-                    cnt);
+                ptr::copy_nonoverlapping(src[off..].as_ptr(), dst.as_mut_ptr() as *mut u8, cnt);
 
                 off += cnt;
-
             }
 
-            unsafe { self.advance_mut(cnt); }
+            unsafe {
+                self.advance_mut(cnt);
+            }
         }
     }
 
@@ -872,84 +881,84 @@ pub trait BufMut {
 }
 
 macro_rules! deref_forward_bufmut {
-    () => (
-    fn remaining_mut(&self) -> usize {
-        (**self).remaining_mut()
-    }
+    () => {
+        fn remaining_mut(&self) -> usize {
+            (**self).remaining_mut()
+        }
 
-    fn bytes_mut(&mut self) -> &mut [MaybeUninit<u8>] {
-        (**self).bytes_mut()
-    }
+        fn bytes_mut(&mut self) -> &mut [MaybeUninit<u8>] {
+            (**self).bytes_mut()
+        }
 
-    #[cfg(feature = "std")]
-    fn bytes_vectored_mut<'b>(&'b mut self, dst: &mut [IoSliceMut<'b>]) -> usize {
-        (**self).bytes_vectored_mut(dst)
-    }
+        #[cfg(feature = "std")]
+        fn bytes_vectored_mut<'b>(&'b mut self, dst: &mut [IoSliceMut<'b>]) -> usize {
+            (**self).bytes_vectored_mut(dst)
+        }
 
-    unsafe fn advance_mut(&mut self, cnt: usize) {
-        (**self).advance_mut(cnt)
-    }
+        unsafe fn advance_mut(&mut self, cnt: usize) {
+            (**self).advance_mut(cnt)
+        }
 
-    fn put_slice(&mut self, src: &[u8]) {
-        (**self).put_slice(src)
-    }
+        fn put_slice(&mut self, src: &[u8]) {
+            (**self).put_slice(src)
+        }
 
-    fn put_u8(&mut self, n: u8) {
-        (**self).put_u8(n)
-    }
+        fn put_u8(&mut self, n: u8) {
+            (**self).put_u8(n)
+        }
 
-    fn put_i8(&mut self, n: i8) {
-        (**self).put_i8(n)
-    }
+        fn put_i8(&mut self, n: i8) {
+            (**self).put_i8(n)
+        }
 
-    fn put_u16(&mut self, n: u16) {
-        (**self).put_u16(n)
-    }
+        fn put_u16(&mut self, n: u16) {
+            (**self).put_u16(n)
+        }
 
-    fn put_u16_le(&mut self, n: u16) {
-        (**self).put_u16_le(n)
-    }
+        fn put_u16_le(&mut self, n: u16) {
+            (**self).put_u16_le(n)
+        }
 
-    fn put_i16(&mut self, n: i16) {
-        (**self).put_i16(n)
-    }
+        fn put_i16(&mut self, n: i16) {
+            (**self).put_i16(n)
+        }
 
-    fn put_i16_le(&mut self, n: i16) {
-        (**self).put_i16_le(n)
-    }
+        fn put_i16_le(&mut self, n: i16) {
+            (**self).put_i16_le(n)
+        }
 
-    fn put_u32(&mut self, n: u32) {
-        (**self).put_u32(n)
-    }
+        fn put_u32(&mut self, n: u32) {
+            (**self).put_u32(n)
+        }
 
-    fn put_u32_le(&mut self, n: u32) {
-        (**self).put_u32_le(n)
-    }
+        fn put_u32_le(&mut self, n: u32) {
+            (**self).put_u32_le(n)
+        }
 
-    fn put_i32(&mut self, n: i32) {
-        (**self).put_i32(n)
-    }
+        fn put_i32(&mut self, n: i32) {
+            (**self).put_i32(n)
+        }
 
-    fn put_i32_le(&mut self, n: i32) {
-        (**self).put_i32_le(n)
-    }
+        fn put_i32_le(&mut self, n: i32) {
+            (**self).put_i32_le(n)
+        }
 
-    fn put_u64(&mut self, n: u64) {
-        (**self).put_u64(n)
-    }
+        fn put_u64(&mut self, n: u64) {
+            (**self).put_u64(n)
+        }
 
-    fn put_u64_le(&mut self, n: u64) {
-        (**self).put_u64_le(n)
-    }
+        fn put_u64_le(&mut self, n: u64) {
+            (**self).put_u64_le(n)
+        }
 
-    fn put_i64(&mut self, n: i64) {
-        (**self).put_i64(n)
-    }
+        fn put_i64(&mut self, n: i64) {
+            (**self).put_i64(n)
+        }
 
-    fn put_i64_le(&mut self, n: i64) {
-        (**self).put_i64_le(n)
-    }
-    )
+        fn put_i64_le(&mut self, n: i64) {
+            (**self).put_i64_le(n)
+        }
+    };
 }
 
 impl<T: BufMut + ?Sized> BufMut for &mut T {
@@ -990,11 +999,13 @@ impl BufMut for Vec<u8> {
     unsafe fn advance_mut(&mut self, cnt: usize) {
         let len = self.len();
         let remaining = self.capacity() - len;
-        if cnt > remaining {
-            // Reserve additional capacity, and ensure that the total length
-            // will not overflow usize.
-            self.reserve(cnt);
-        }
+
+        assert!(
+            cnt <= remaining,
+            "cannot advance past `remaining_mut`: {:?} <= {:?}",
+            cnt,
+            remaining
+        );
 
         self.set_len(len + cnt);
     }
@@ -1011,15 +1022,16 @@ impl BufMut for Vec<u8> {
         let len = self.len();
 
         let ptr = self.as_mut_ptr() as *mut MaybeUninit<u8>;
-        unsafe {
-            &mut slice::from_raw_parts_mut(ptr, cap)[len..]
-        }
+        unsafe { &mut slice::from_raw_parts_mut(ptr, cap)[len..] }
     }
 
     // Specialize these methods so they can skip checking `remaining_mut`
     // and `advance_mut`.
 
-    fn put<T: super::Buf>(&mut self, mut src: T) where Self: Sized {
+    fn put<T: super::Buf>(&mut self, mut src: T)
+    where
+        Self: Sized,
+    {
         // In case the src isn't contiguous, reserve upfront
         self.reserve(src.remaining());
 
diff --git a/third_party/rust/bytes/src/buf/ext/chain.rs b/third_party/rust/bytes/src/buf/ext/chain.rs
index a1ec597df641954af76bdfd54b8347257db046ee..e62e2f1b96b9eb10271ad22dcb37f0dc38d490f1 100644
--- a/third_party/rust/bytes/src/buf/ext/chain.rs
+++ b/third_party/rust/bytes/src/buf/ext/chain.rs
@@ -1,12 +1,12 @@
-use crate::{Buf, BufMut};
 use crate::buf::IntoIter;
+use crate::{Buf, BufMut};
 
 use core::mem::MaybeUninit;
 
-#[cfg(feature = "std")]
-use std::io::{IoSlice};
 #[cfg(feature = "std")]
 use crate::buf::IoSliceMut;
+#[cfg(feature = "std")]
+use std::io::IoSlice;
 
 /// A `Chain` sequences two buffers.
 ///
@@ -41,10 +41,7 @@ pub struct Chain<T, U> {
 impl<T, U> Chain<T, U> {
     /// Creates a new `Chain` sequencing the provided values.
     pub fn new(a: T, b: U) -> Chain<T, U> {
-        Chain {
-            a,
-            b,
-        }
+        Chain { a, b }
     }
 
     /// Gets a reference to the first underlying `Buf`.
@@ -137,8 +134,9 @@ impl<T, U> Chain<T, U> {
 }
 
 impl<T, U> Buf for Chain<T, U>
-    where T: Buf,
-          U: Buf,
+where
+    T: Buf,
+    U: Buf,
 {
     fn remaining(&self) -> usize {
         self.a.remaining() + self.b.remaining()
@@ -179,8 +177,9 @@ impl<T, U> Buf for Chain<T, U>
 }
 
 impl<T, U> BufMut for Chain<T, U>
-    where T: BufMut,
-          U: BufMut,
+where
+    T: BufMut,
+    U: BufMut,
 {
     fn remaining_mut(&self) -> usize {
         self.a.remaining_mut() + self.b.remaining_mut()
diff --git a/third_party/rust/bytes/src/buf/ext/limit.rs b/third_party/rust/bytes/src/buf/ext/limit.rs
index f86e01151ccb957232f2e720cf09e6bd43767a85..a36eceeef16e9d481446ed2a71b9e5bf8feb7b7e 100644
--- a/third_party/rust/bytes/src/buf/ext/limit.rs
+++ b/third_party/rust/bytes/src/buf/ext/limit.rs
@@ -11,10 +11,7 @@ pub struct Limit<T> {
 }
 
 pub(super) fn new<T>(inner: T, limit: usize) -> Limit<T> {
-    Limit {
-        inner,
-        limit,
-    }
+    Limit { inner, limit }
 }
 
 impl<T> Limit<T> {
diff --git a/third_party/rust/bytes/src/buf/ext/mod.rs b/third_party/rust/bytes/src/buf/ext/mod.rs
index 7b0bdab2008ed4ef69f3b201e0e4cb6e7bac1255..4a292676a213477e64a9242db7c03665b3d0ef04 100644
--- a/third_party/rust/bytes/src/buf/ext/mod.rs
+++ b/third_party/rust/bytes/src/buf/ext/mod.rs
@@ -10,9 +10,9 @@ mod take;
 #[cfg(feature = "std")]
 mod writer;
 
+pub use self::chain::Chain;
 pub use self::limit::Limit;
 pub use self::take::Take;
-pub use self::chain::Chain;
 
 #[cfg(feature = "std")]
 pub use self::{reader::Reader, writer::Writer};
@@ -27,7 +27,7 @@ pub trait BufExt: Buf {
     /// # Examples
     ///
     /// ```
-    /// use bytes::{Buf, BufMut, buf::BufExt};
+    /// use bytes::{BufMut, buf::BufExt};
     ///
     /// let mut buf = b"hello world"[..].take(5);
     /// let mut dst = vec![];
@@ -41,7 +41,8 @@ pub trait BufExt: Buf {
     /// assert_eq!(dst, b" world");
     /// ```
     fn take(self, limit: usize) -> Take<Self>
-        where Self: Sized
+    where
+        Self: Sized,
     {
         take::new(self, limit)
     }
@@ -62,7 +63,8 @@ pub trait BufExt: Buf {
     /// assert_eq!(full.bytes(), b"hello world");
     /// ```
     fn chain<U: Buf>(self, next: U) -> Chain<Self, U>
-        where Self: Sized
+    where
+        Self: Sized,
     {
         Chain::new(self, next)
     }
@@ -77,7 +79,7 @@ pub trait BufExt: Buf {
     /// # Examples
     ///
     /// ```
-    /// use bytes::{Buf, Bytes, buf::BufExt};
+    /// use bytes::{Bytes, buf::BufExt};
     /// use std::io::Read;
     ///
     /// let buf = Bytes::from("hello world");
@@ -91,7 +93,10 @@ pub trait BufExt: Buf {
     /// assert_eq!(&dst[..11], &b"hello world"[..]);
     /// ```
     #[cfg(feature = "std")]
-    fn reader(self) -> Reader<Self> where Self: Sized {
+    fn reader(self) -> Reader<Self>
+    where
+        Self: Sized,
+    {
         reader::new(self)
     }
 }
@@ -114,7 +119,8 @@ pub trait BufMutExt: BufMut {
     /// assert_eq!(dst.remaining_mut(), 10);
     /// ```
     fn limit(self, limit: usize) -> Limit<Self>
-        where Self: Sized
+    where
+        Self: Sized,
     {
         limit::new(self, limit)
     }
@@ -129,7 +135,7 @@ pub trait BufMutExt: BufMut {
     /// # Examples
     ///
     /// ```
-    /// use bytes::{BufMut, buf::BufMutExt};
+    /// use bytes::buf::BufMutExt;
     /// use std::io::Write;
     ///
     /// let mut buf = vec![].writer();
@@ -142,7 +148,10 @@ pub trait BufMutExt: BufMut {
     /// assert_eq!(*buf, b"hello world"[..]);
     /// ```
     #[cfg(feature = "std")]
-    fn writer(self) -> Writer<Self> where Self: Sized {
+    fn writer(self) -> Writer<Self>
+    where
+        Self: Sized,
+    {
         writer::new(self)
     }
 
@@ -167,7 +176,8 @@ pub trait BufMutExt: BufMut {
     /// assert_eq!(&b[..], b" world");
     /// ```
     fn chain_mut<U: BufMut>(self, next: U) -> Chain<Self, U>
-        where Self: Sized
+    where
+        Self: Sized,
     {
         Chain::new(self, next)
     }
diff --git a/third_party/rust/bytes/src/buf/ext/reader.rs b/third_party/rust/bytes/src/buf/ext/reader.rs
index e38103b1de2c0e7f41977058af801db9d531f9fd..dde3548bfe972ab15db46666c26625e2f2809aa6 100644
--- a/third_party/rust/bytes/src/buf/ext/reader.rs
+++ b/third_party/rust/bytes/src/buf/ext/reader.rs
@@ -1,4 +1,4 @@
-use crate::{Buf};
+use crate::Buf;
 
 use std::{cmp, io};
 
@@ -26,7 +26,7 @@ impl<B: Buf> Reader<B> {
     /// ```rust
     /// use bytes::buf::BufExt;
     ///
-    /// let mut buf = b"hello world".reader();
+    /// let buf = b"hello world".reader();
     ///
     /// assert_eq!(b"hello world", buf.get_ref());
     /// ```
diff --git a/third_party/rust/bytes/src/buf/ext/take.rs b/third_party/rust/bytes/src/buf/ext/take.rs
index 6fc4ffc72cf7ba7631edb4afae6c8a89483afc4d..1d84868bfb4da3096b321dbcb2c459cccde87bef 100644
--- a/third_party/rust/bytes/src/buf/ext/take.rs
+++ b/third_party/rust/bytes/src/buf/ext/take.rs
@@ -5,7 +5,7 @@ use core::cmp;
 /// A `Buf` adapter which limits the bytes read from an underlying buffer.
 ///
 /// This struct is generally created by calling `take()` on `Buf`. See
-/// documentation of [`take()`](trait.Buf.html#method.take) for more details.
+/// documentation of [`take()`](trait.BufExt.html#method.take) for more details.
 #[derive(Debug)]
 pub struct Take<T> {
     inner: T,
@@ -13,10 +13,7 @@ pub struct Take<T> {
 }
 
 pub fn new<T>(inner: T, limit: usize) -> Take<T> {
-    Take {
-        inner,
-        limit,
-    }
+    Take { inner, limit }
 }
 
 impl<T> Take<T> {
@@ -25,7 +22,7 @@ impl<T> Take<T> {
     /// # Examples
     ///
     /// ```rust
-    /// use bytes::buf::{Buf, BufMut, BufExt};
+    /// use bytes::buf::{BufMut, BufExt};
     ///
     /// let mut buf = b"hello world".take(2);
     /// let mut dst = vec![];
@@ -52,7 +49,7 @@ impl<T> Take<T> {
     /// ```rust
     /// use bytes::{Buf, buf::BufExt};
     ///
-    /// let mut buf = b"hello world".take(2);
+    /// let buf = b"hello world".take(2);
     ///
     /// assert_eq!(11, buf.get_ref().remaining());
     /// ```
@@ -113,7 +110,7 @@ impl<T> Take<T> {
     /// # Examples
     ///
     /// ```rust
-    /// use bytes::{Buf, BufMut, buf::BufExt};
+    /// use bytes::{BufMut, buf::BufExt};
     ///
     /// let mut buf = b"hello world".take(2);
     /// let mut dst = vec![];
diff --git a/third_party/rust/bytes/src/buf/ext/writer.rs b/third_party/rust/bytes/src/buf/ext/writer.rs
index 1418418e815e1645c775c9fa1998a63fe6a1fe60..a14197c8132e6336e1fc547a9a5379a51a6576a3 100644
--- a/third_party/rust/bytes/src/buf/ext/writer.rs
+++ b/third_party/rust/bytes/src/buf/ext/writer.rs
@@ -26,7 +26,7 @@ impl<B: BufMut> Writer<B> {
     /// ```rust
     /// use bytes::buf::BufMutExt;
     ///
-    /// let mut buf = Vec::with_capacity(1024).writer();
+    /// let buf = Vec::with_capacity(1024).writer();
     ///
     /// assert_eq!(1024, buf.get_ref().capacity());
     /// ```
diff --git a/third_party/rust/bytes/src/buf/iter.rs b/third_party/rust/bytes/src/buf/iter.rs
index 1af421a8d530113c1f2d41930a99accb0c722b7e..0f9bdc04fc1b945c9a2c71cf2629a000beb6d298 100644
--- a/third_party/rust/bytes/src/buf/iter.rs
+++ b/third_party/rust/bytes/src/buf/iter.rs
@@ -9,7 +9,7 @@ use crate::Buf;
 /// Basic usage:
 ///
 /// ```
-/// use bytes::{Buf, Bytes};
+/// use bytes::Bytes;
 ///
 /// let buf = Bytes::from(&b"abc"[..]);
 /// let mut iter = buf.into_iter();
@@ -33,7 +33,7 @@ impl<T> IntoIter<T> {
     /// # Examples
     ///
     /// ```
-    /// use bytes::{Buf, Bytes};
+    /// use bytes::Bytes;
     /// use bytes::buf::IntoIter;
     ///
     /// let buf = Bytes::from_static(b"abc");
@@ -47,6 +47,7 @@ impl<T> IntoIter<T> {
     pub fn new(inner: T) -> IntoIter<T> {
         IntoIter { inner }
     }
+
     /// Consumes this `IntoIter`, returning the underlying value.
     ///
     /// # Examples
@@ -109,7 +110,6 @@ impl<T> IntoIter<T> {
     }
 }
 
-
 impl<T: Buf> Iterator for IntoIter<T> {
     type Item = u8;
 
@@ -130,4 +130,4 @@ impl<T: Buf> Iterator for IntoIter<T> {
     }
 }
 
-impl<T: Buf> ExactSizeIterator for IntoIter<T> { }
+impl<T: Buf> ExactSizeIterator for IntoIter<T> {}
diff --git a/third_party/rust/bytes/src/buf/mod.rs b/third_party/rust/bytes/src/buf/mod.rs
index d4538f21ea893421d64556c0637d1e70db9f013d..1d7292c9e6eb10e38ab0d4ddac34a76b9b55b0f7 100644
--- a/third_party/rust/bytes/src/buf/mod.rs
+++ b/third_party/rust/bytes/src/buf/mod.rs
@@ -24,8 +24,7 @@ mod vec_deque;
 
 pub use self::buf_impl::Buf;
 pub use self::buf_mut::BufMut;
-pub use self::ext::{BufExt, BufMutExt};
 #[cfg(feature = "std")]
 pub use self::buf_mut::IoSliceMut;
+pub use self::ext::{BufExt, BufMutExt};
 pub use self::iter::IntoIter;
-
diff --git a/third_party/rust/bytes/src/bytes.rs b/third_party/rust/bytes/src/bytes.rs
index e2f08b57e5c69e809145b4ebf700af7370193848..79a09f3981921b81d326a1d9a38b239ea8ff7551 100644
--- a/third_party/rust/bytes/src/bytes.rs
+++ b/third_party/rust/bytes/src/bytes.rs
@@ -1,13 +1,14 @@
-use core::{cmp, fmt, hash, mem, ptr, slice, usize};
-use core::iter::{FromIterator};
+use core::iter::FromIterator;
 use core::ops::{Deref, RangeBounds};
+use core::{cmp, fmt, hash, mem, ptr, slice, usize};
 
-use alloc::{vec::Vec, string::String, boxed::Box, borrow::Borrow};
+use alloc::{borrow::Borrow, boxed::Box, string::String, vec::Vec};
 
-use crate::Buf;
 use crate::buf::IntoIter;
-use crate::debug;
+#[allow(unused)]
+use crate::loom::sync::atomic::AtomicMut;
 use crate::loom::sync::atomic::{self, AtomicPtr, AtomicUsize, Ordering};
+use crate::Buf;
 
 /// A reference counted contiguous slice of memory.
 ///
@@ -96,8 +97,18 @@ impl Bytes {
     /// assert_eq!(&b[..], b"");
     /// ```
     #[inline]
+    #[cfg(not(all(loom, test)))]
+    pub const fn new() -> Bytes {
+        // Make it a named const to work around
+        // "unsizing casts are not allowed in const fn"
+        const EMPTY: &[u8] = &[];
+        Bytes::from_static(EMPTY)
+    }
+
+    #[cfg(all(loom, test))]
     pub fn new() -> Bytes {
-        Bytes::from_static(b"")
+        const EMPTY: &[u8] = &[];
+        Bytes::from_static(EMPTY)
     }
 
     /// Creates a new `Bytes` from a static slice.
@@ -164,7 +175,6 @@ impl Bytes {
         self.len == 0
     }
 
-
     ///Creates `Bytes` instance from slice, by copying it.
     pub fn copy_from_slice(data: &[u8]) -> Self {
         data.to_vec().into()
@@ -209,14 +219,23 @@ impl Bytes {
             Bound::Unbounded => len,
         };
 
-        assert!(begin <= end);
-        assert!(end <= len);
+        assert!(
+            begin <= end,
+            "range start must not be greater than end: {:?} <= {:?}",
+            begin,
+            end,
+        );
+        assert!(
+            end <= len,
+            "range end out of bounds: {:?} <= {:?}",
+            end,
+            len,
+        );
 
         if end == begin {
             return Bytes::new();
         }
 
-
         let mut ret = self.clone();
 
         ret.len = end - begin;
@@ -251,6 +270,12 @@ impl Bytes {
     /// Requires that the given `sub` slice is in fact contained within the
     /// `Bytes` buffer; otherwise this function will panic.
     pub fn slice_ref(&self, subset: &[u8]) -> Bytes {
+        // Empty slice and empty Bytes may have their pointers reset
+        // so explicitly allow empty slice to be a subslice of any slice.
+        if subset.is_empty() {
+            return Bytes::new();
+        }
+
         let bytes_p = self.as_ptr() as usize;
         let bytes_len = self.len();
 
@@ -302,7 +327,12 @@ impl Bytes {
     /// Panics if `at > len`.
     #[must_use = "consider Bytes::truncate if you don't need the other half"]
     pub fn split_off(&mut self, at: usize) -> Bytes {
-        assert!(at <= self.len());
+        assert!(
+            at <= self.len(),
+            "split_off out of bounds: {:?} <= {:?}",
+            at,
+            self.len(),
+        );
 
         if at == self.len() {
             return Bytes::new();
@@ -346,7 +376,12 @@ impl Bytes {
     /// Panics if `at > len`.
     #[must_use = "consider Bytes::advance if you don't need the other half"]
     pub fn split_to(&mut self, at: usize) -> Bytes {
-        assert!(at <= self.len());
+        assert!(
+            at <= self.len(),
+            "split_to out of bounds: {:?} <= {:?}",
+            at,
+            self.len(),
+        );
 
         if at == self.len() {
             return mem::replace(self, Bytes::new());
@@ -356,7 +391,6 @@ impl Bytes {
             return Bytes::new();
         }
 
-
         let mut ret = self.clone();
 
         unsafe { self.inc_start(at) };
@@ -388,7 +422,16 @@ impl Bytes {
     #[inline]
     pub fn truncate(&mut self, len: usize) {
         if len < self.len {
-            self.len = len;
+            // The Vec "promotable" vtables do not store the capacity,
+            // so we cannot truncate while using this repr. We *have* to
+            // promote using `split_off` so the capacity can be stored.
+            if self.vtable as *const Vtable == &PROMOTABLE_EVEN_VTABLE
+                || self.vtable as *const Vtable == &PROMOTABLE_ODD_VTABLE
+            {
+                drop(self.split_off(len));
+            } else {
+                self.len = len;
+            }
         }
     }
 
@@ -409,7 +452,12 @@ impl Bytes {
     }
 
     #[inline]
-    pub(crate) unsafe fn with_vtable(ptr: *const u8, len: usize, data: AtomicPtr<()>, vtable: &'static Vtable) -> Bytes {
+    pub(crate) unsafe fn with_vtable(
+        ptr: *const u8,
+        len: usize,
+        data: AtomicPtr<()>,
+        vtable: &'static Vtable,
+    ) -> Bytes {
         Bytes {
             ptr,
             len,
@@ -422,15 +470,13 @@ impl Bytes {
 
     #[inline]
     fn as_slice(&self) -> &[u8] {
-        unsafe {
-            slice::from_raw_parts(self.ptr, self.len)
-        }
+        unsafe { slice::from_raw_parts(self.ptr, self.len) }
     }
 
     #[inline]
     unsafe fn inc_start(&mut self, by: usize) {
         // should already be asserted, but debug assert for tests
-        debug_assert!(self.len >= by);
+        debug_assert!(self.len >= by, "internal: inc_start out of bounds");
         self.len -= by;
         self.ptr = self.ptr.offset(by as isize);
     }
@@ -443,24 +489,14 @@ unsafe impl Sync for Bytes {}
 impl Drop for Bytes {
     #[inline]
     fn drop(&mut self) {
-        unsafe {
-            (self.vtable.drop)(&mut self.data, self.ptr, self.len)
-        }
+        unsafe { (self.vtable.drop)(&mut self.data, self.ptr, self.len) }
     }
 }
 
 impl Clone for Bytes {
     #[inline]
     fn clone(&self) -> Bytes {
-        unsafe {
-            (self.vtable.clone)(&self.data, self.ptr, self.len)
-        }
-    }
-}
-
-impl fmt::Debug for Bytes {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        fmt::Debug::fmt(&debug::BsDebug(&self.as_slice()), f)
+        unsafe { (self.vtable.clone)(&self.data, self.ptr, self.len) }
     }
 }
 
@@ -477,7 +513,13 @@ impl Buf for Bytes {
 
     #[inline]
     fn advance(&mut self, cnt: usize) {
-        assert!(cnt <= self.len(), "cannot advance past `remaining`");
+        assert!(
+            cnt <= self.len(),
+            "cannot advance past `remaining`: {:?} <= {:?}",
+            cnt,
+            self.len(),
+        );
+
         unsafe {
             self.inc_start(cnt);
         }
@@ -505,7 +547,10 @@ impl AsRef<[u8]> for Bytes {
 }
 
 impl hash::Hash for Bytes {
-    fn hash<H>(&self, state: &mut H) where H: hash::Hasher {
+    fn hash<H>(&self, state: &mut H)
+    where
+        H: hash::Hasher,
+    {
         self.as_slice().hash(state);
     }
 }
@@ -582,7 +627,7 @@ impl PartialEq<Bytes> for [u8] {
 
 impl PartialOrd<Bytes> for [u8] {
     fn partial_cmp(&self, other: &Bytes) -> Option<cmp::Ordering> {
-        other.partial_cmp(self)
+        <[u8] as PartialOrd<[u8]>>::partial_cmp(self, other)
     }
 }
 
@@ -606,7 +651,7 @@ impl PartialEq<Bytes> for str {
 
 impl PartialOrd<Bytes> for str {
     fn partial_cmp(&self, other: &Bytes) -> Option<cmp::Ordering> {
-        other.partial_cmp(self)
+        <[u8] as PartialOrd<[u8]>>::partial_cmp(self.as_bytes(), other)
     }
 }
 
@@ -630,7 +675,7 @@ impl PartialEq<Bytes> for Vec<u8> {
 
 impl PartialOrd<Bytes> for Vec<u8> {
     fn partial_cmp(&self, other: &Bytes) -> Option<cmp::Ordering> {
-        other.partial_cmp(self)
+        <[u8] as PartialOrd<[u8]>>::partial_cmp(self, other)
     }
 }
 
@@ -654,7 +699,7 @@ impl PartialEq<Bytes> for String {
 
 impl PartialOrd<Bytes> for String {
     fn partial_cmp(&self, other: &Bytes) -> Option<cmp::Ordering> {
-        other.partial_cmp(self)
+        <[u8] as PartialOrd<[u8]>>::partial_cmp(self.as_bytes(), other)
     }
 }
 
@@ -666,7 +711,7 @@ impl PartialEq<Bytes> for &[u8] {
 
 impl PartialOrd<Bytes> for &[u8] {
     fn partial_cmp(&self, other: &Bytes) -> Option<cmp::Ordering> {
-        other.partial_cmp(self)
+        <[u8] as PartialOrd<[u8]>>::partial_cmp(self, other)
     }
 }
 
@@ -678,12 +723,13 @@ impl PartialEq<Bytes> for &str {
 
 impl PartialOrd<Bytes> for &str {
     fn partial_cmp(&self, other: &Bytes) -> Option<cmp::Ordering> {
-        other.partial_cmp(self)
+        <[u8] as PartialOrd<[u8]>>::partial_cmp(self.as_bytes(), other)
     }
 }
 
 impl<'a, T: ?Sized> PartialEq<&'a T> for Bytes
-    where Bytes: PartialEq<T>
+where
+    Bytes: PartialEq<T>,
 {
     fn eq(&self, other: &&'a T) -> bool {
         *self == **other
@@ -691,7 +737,8 @@ impl<'a, T: ?Sized> PartialEq<&'a T> for Bytes
 }
 
 impl<'a, T: ?Sized> PartialOrd<&'a T> for Bytes
-    where Bytes: PartialOrd<T>
+where
+    Bytes: PartialOrd<T>,
 {
     fn partial_cmp(&self, other: &&'a T) -> Option<cmp::Ordering> {
         self.partial_cmp(&**other)
@@ -731,20 +778,23 @@ impl From<Vec<u8>> for Bytes {
         let slice = vec.into_boxed_slice();
         let len = slice.len();
         let ptr = slice.as_ptr();
-
-        assert!(
-            ptr as usize & KIND_VEC == 0,
-            "Vec pointer should not have LSB set: {:p}",
-            ptr,
-        );
         drop(Box::into_raw(slice));
 
-        let data = ptr as usize | KIND_VEC;
-        Bytes {
-            ptr,
-            len,
-            data: AtomicPtr::new(data as *mut _),
-            vtable: &SHARED_VTABLE,
+        if ptr as usize & 0x1 == 0 {
+            let data = ptr as usize | KIND_VEC;
+            Bytes {
+                ptr,
+                len,
+                data: AtomicPtr::new(data as *mut _),
+                vtable: &PROMOTABLE_EVEN_VTABLE,
+            }
+        } else {
+            Bytes {
+                ptr,
+                len,
+                data: AtomicPtr::new(ptr as *mut _),
+                vtable: &PROMOTABLE_ODD_VTABLE,
+            }
         }
     }
 }
@@ -782,24 +832,19 @@ unsafe fn static_drop(_: &mut AtomicPtr<()>, _: *const u8, _: usize) {
     // nothing to drop for &'static [u8]
 }
 
-// ===== impl SharedVtable =====
+// ===== impl PromotableVtable =====
 
-struct Shared {
-    // holds vec for drop, but otherwise doesnt access it
-    _vec: Vec<u8>,
-    ref_cnt: AtomicUsize,
-}
-
-static SHARED_VTABLE: Vtable = Vtable {
-    clone: shared_clone,
-    drop: shared_drop,
+static PROMOTABLE_EVEN_VTABLE: Vtable = Vtable {
+    clone: promotable_even_clone,
+    drop: promotable_even_drop,
 };
 
-const KIND_ARC: usize = 0b0;
-const KIND_VEC: usize = 0b1;
-const KIND_MASK: usize = 0b1;
+static PROMOTABLE_ODD_VTABLE: Vtable = Vtable {
+    clone: promotable_odd_clone,
+    drop: promotable_odd_drop,
+};
 
-unsafe fn shared_clone(data: &AtomicPtr<()>, ptr: *const u8, len: usize) -> Bytes {
+unsafe fn promotable_even_clone(data: &AtomicPtr<()>, ptr: *const u8, len: usize) -> Bytes {
     let shared = data.load(Ordering::Acquire);
     let kind = shared as usize & KIND_MASK;
 
@@ -807,38 +852,90 @@ unsafe fn shared_clone(data: &AtomicPtr<()>, ptr: *const u8, len: usize) -> Byte
         shallow_clone_arc(shared as _, ptr, len)
     } else {
         debug_assert_eq!(kind, KIND_VEC);
-        shallow_clone_vec(data, shared, ptr, len)
+        let buf = (shared as usize & !KIND_MASK) as *mut u8;
+        shallow_clone_vec(data, shared, buf, ptr, len)
     }
 }
 
-unsafe fn shared_drop(data: &mut AtomicPtr<()>, ptr: *const u8, len: usize) {
-    let shared = *data.get_mut();
-    let kind = shared as usize & KIND_MASK;
+unsafe fn promotable_even_drop(data: &mut AtomicPtr<()>, ptr: *const u8, len: usize) {
+    data.with_mut(|shared| {
+        let shared = *shared;
+        let kind = shared as usize & KIND_MASK;
+
+        if kind == KIND_ARC {
+            release_shared(shared as *mut Shared);
+        } else {
+            debug_assert_eq!(kind, KIND_VEC);
+            let buf = (shared as usize & !KIND_MASK) as *mut u8;
+            drop(rebuild_boxed_slice(buf, ptr, len));
+        }
+    });
+}
 
+unsafe fn promotable_odd_clone(data: &AtomicPtr<()>, ptr: *const u8, len: usize) -> Bytes {
+    let shared = data.load(Ordering::Acquire);
+    let kind = shared as usize & KIND_MASK;
 
     if kind == KIND_ARC {
-        release_shared(shared as *mut Shared);
+        shallow_clone_arc(shared as _, ptr, len)
     } else {
         debug_assert_eq!(kind, KIND_VEC);
-
-        drop(rebuild_vec(shared, ptr, len));
+        shallow_clone_vec(data, shared, shared as *mut u8, ptr, len)
     }
 }
 
-unsafe fn rebuild_vec(shared: *const (), offset: *const u8, len: usize) -> Vec<u8> {
-    debug_assert!(
-        shared as usize & KIND_MASK == KIND_VEC,
-        "rebuild_vec should have beeen called with KIND_VEC",
-    );
-    debug_assert!(
-        shared as usize & !KIND_MASK != 0,
-        "rebuild_vec should be called with non-null pointer: {:p}",
-        shared,
-    );
+unsafe fn promotable_odd_drop(data: &mut AtomicPtr<()>, ptr: *const u8, len: usize) {
+    data.with_mut(|shared| {
+        let shared = *shared;
+        let kind = shared as usize & KIND_MASK;
+
+        if kind == KIND_ARC {
+            release_shared(shared as *mut Shared);
+        } else {
+            debug_assert_eq!(kind, KIND_VEC);
 
-    let buf = (shared as usize & !KIND_MASK) as *mut u8;
+            drop(rebuild_boxed_slice(shared as *mut u8, ptr, len));
+        }
+    });
+}
+
+unsafe fn rebuild_boxed_slice(buf: *mut u8, offset: *const u8, len: usize) -> Box<[u8]> {
     let cap = (offset as usize - buf as usize) + len;
-    Vec::from_raw_parts(buf, cap, cap)
+    Box::from_raw(slice::from_raw_parts_mut(buf, cap))
+}
+
+// ===== impl SharedVtable =====
+
+struct Shared {
+    // holds vec for drop, but otherwise doesnt access it
+    _vec: Vec<u8>,
+    ref_cnt: AtomicUsize,
+}
+
+// Assert that the alignment of `Shared` is divisible by 2.
+// This is a necessary invariant since we depend on allocating `Shared` a
+// shared object to implicitly carry the `KIND_ARC` flag in its pointer.
+// This flag is set when the LSB is 0.
+const _: [(); 0 - mem::align_of::<Shared>() % 2] = []; // Assert that the alignment of `Shared` is divisible by 2.
+
+static SHARED_VTABLE: Vtable = Vtable {
+    clone: shared_clone,
+    drop: shared_drop,
+};
+
+const KIND_ARC: usize = 0b0;
+const KIND_VEC: usize = 0b1;
+const KIND_MASK: usize = 0b1;
+
+unsafe fn shared_clone(data: &AtomicPtr<()>, ptr: *const u8, len: usize) -> Bytes {
+    let shared = data.load(Ordering::Relaxed);
+    shallow_clone_arc(shared as _, ptr, len)
+}
+
+unsafe fn shared_drop(data: &mut AtomicPtr<()>, _ptr: *const u8, _len: usize) {
+    data.with_mut(|shared| {
+        release_shared(*shared as *mut Shared);
+    });
 }
 
 unsafe fn shallow_clone_arc(shared: *mut Shared, ptr: *const u8, len: usize) -> Bytes {
@@ -857,13 +954,17 @@ unsafe fn shallow_clone_arc(shared: *mut Shared, ptr: *const u8, len: usize) ->
 }
 
 #[cold]
-unsafe fn shallow_clone_vec(atom: &AtomicPtr<()>, ptr: *const (), offset: *const u8, len: usize) -> Bytes {
+unsafe fn shallow_clone_vec(
+    atom: &AtomicPtr<()>,
+    ptr: *const (),
+    buf: *mut u8,
+    offset: *const u8,
+    len: usize,
+) -> Bytes {
     // If  the buffer is still tracked in a `Vec<u8>`. It is time to
     // promote the vec to an `Arc`. This could potentially be called
     // concurrently, so some care must be taken.
 
-    debug_assert_eq!(ptr as usize & KIND_MASK, KIND_VEC);
-
     // First, allocate a new `Shared` instance containing the
     // `Vec` fields. It's important to note that `ptr`, `len`,
     // and `cap` cannot be mutated without having `&mut self`.
@@ -871,7 +972,7 @@ unsafe fn shallow_clone_vec(atom: &AtomicPtr<()>, ptr: *const (), offset: *const
     // updated and since the buffer hasn't been promoted to an
     // `Arc`, those three fields still are the components of the
     // vector.
-    let vec = rebuild_vec(ptr as *const (), offset, len);
+    let vec = rebuild_boxed_slice(buf, offset, len).into_vec();
     let shared = Box::new(Shared {
         _vec: vec,
         // Initialize refcount to 2. One for this reference, and one
@@ -884,7 +985,10 @@ unsafe fn shallow_clone_vec(atom: &AtomicPtr<()>, ptr: *const (), offset: *const
 
     // The pointer should be aligned, so this assert should
     // always succeed.
-    debug_assert!(0 == (shared as usize & KIND_MASK));
+    debug_assert!(
+        0 == (shared as usize & KIND_MASK),
+        "internal: Box<Shared> should have an aligned pointer",
+    );
 
     // Try compare & swapping the pointer into the `arc` field.
     // `Release` is used synchronize with other threads that
@@ -973,7 +1077,7 @@ fn _split_off_must_use() {}
 // fuzz tests
 #[cfg(all(test, loom))]
 mod fuzz {
-    use std::sync::Arc;
+    use loom::sync::Arc;
     use loom::thread;
 
     use super::Bytes;
diff --git a/third_party/rust/bytes/src/bytes_mut.rs b/third_party/rust/bytes/src/bytes_mut.rs
index 7a154443432c6d07c053915e56eb26174afdd45d..a7a8e579872d9575e7714b5e5a8d9c682562cbd7 100644
--- a/third_party/rust/bytes/src/bytes_mut.rs
+++ b/third_party/rust/bytes/src/bytes_mut.rs
@@ -1,23 +1,33 @@
-use core::{cmp, fmt, hash, isize, slice, usize};
+use core::iter::{FromIterator, Iterator};
 use core::mem::{self, ManuallyDrop};
 use core::ops::{Deref, DerefMut};
 use core::ptr::{self, NonNull};
-use core::iter::{FromIterator, Iterator};
+use core::{cmp, fmt, hash, isize, slice, usize};
 
-use alloc::{vec::Vec, string::String, boxed::Box, borrow::{Borrow, BorrowMut}};
+use alloc::{
+    borrow::{Borrow, BorrowMut},
+    boxed::Box,
+    string::String,
+    vec::Vec,
+};
 
-use crate::{Bytes, Buf, BufMut};
-use crate::bytes::Vtable;
 use crate::buf::IntoIter;
-use crate::debug;
+use crate::bytes::Vtable;
+#[allow(unused)]
+use crate::loom::sync::atomic::AtomicMut;
 use crate::loom::sync::atomic::{self, AtomicPtr, AtomicUsize, Ordering};
+use crate::{Buf, BufMut, Bytes};
 
 /// A unique reference to a contiguous slice of memory.
 ///
 /// `BytesMut` represents a unique view into a potentially shared memory region.
 /// Given the uniqueness guarantee, owners of `BytesMut` handles are able to
-/// mutate the memory. It is similar to a `Vec<u8>` but with less copies and
-/// allocations.
+/// mutate the memory.
+///
+/// `BytesMut` can be thought of as containing a `buf: Arc<Vec<u8>>`, an offset
+/// into `buf`, a slice length, and a guarantee that no other `BytesMut` for the
+/// same `buf` overlaps with its slice. That guarantee means that a write lock
+/// is not required.
 ///
 /// # Growth
 ///
@@ -108,8 +118,7 @@ impl BytesMut {
     /// Creates a new `BytesMut` with the specified capacity.
     ///
     /// The returned `BytesMut` will be able to hold at least `capacity` bytes
-    /// without reallocating. If `capacity` is under `4 * size_of::<usize>() - 1`,
-    /// then `BytesMut` will not allocate.
+    /// without reallocating.
     ///
     /// It is important to note that this function does not specify the length
     /// of the returned `BytesMut`, but only the capacity.
@@ -234,7 +243,9 @@ impl BytesMut {
                 let (off, _) = self.get_vec_pos();
                 let vec = rebuild_vec(self.ptr.as_ptr(), self.len, self.cap, off);
                 mem::forget(self);
-                vec.into()
+                let mut b: Bytes = vec.into();
+                b.advance(off);
+                b
             }
         } else {
             debug_assert_eq!(self.kind(), KIND_ARC);
@@ -243,9 +254,7 @@ impl BytesMut {
             let len = self.len;
             let data = AtomicPtr::new(self.data as _);
             mem::forget(self);
-            unsafe {
-                Bytes::with_vtable(ptr, len, data, &SHARED_VTABLE)
-            }
+            unsafe { Bytes::with_vtable(ptr, len, data, &SHARED_VTABLE) }
         }
     }
 
@@ -277,7 +286,12 @@ impl BytesMut {
     /// Panics if `at > capacity`.
     #[must_use = "consider BytesMut::truncate if you don't need the other half"]
     pub fn split_off(&mut self, at: usize) -> BytesMut {
-        assert!(at <= self.capacity());
+        assert!(
+            at <= self.capacity(),
+            "split_off out of bounds: {:?} <= {:?}",
+            at,
+            self.capacity(),
+        );
         unsafe {
             let mut other = self.shallow_clone();
             other.set_start(at);
@@ -345,7 +359,12 @@ impl BytesMut {
     /// Panics if `at > len`.
     #[must_use = "consider BytesMut::advance if you don't need the other half"]
     pub fn split_to(&mut self, at: usize) -> BytesMut {
-        assert!(at <= self.len());
+        assert!(
+            at <= self.len(),
+            "split_to out of bounds: {:?} <= {:?}",
+            at,
+            self.len(),
+        );
 
         unsafe {
             let mut other = self.shallow_clone();
@@ -377,7 +396,9 @@ impl BytesMut {
     /// [`split_off`]: #method.split_off
     pub fn truncate(&mut self, len: usize) {
         if len <= self.len() {
-            unsafe { self.set_len(len); }
+            unsafe {
+                self.set_len(len);
+            }
         }
     }
 
@@ -458,8 +479,9 @@ impl BytesMut {
     ///
     /// assert_eq!(&b[..], b"hello world");
     /// ```
+    #[inline]
     pub unsafe fn set_len(&mut self, len: usize) {
-        debug_assert!(len <= self.cap);
+        debug_assert!(len <= self.cap, "set_len out of bounds");
         self.len = len;
     }
 
@@ -541,9 +563,8 @@ impl BytesMut {
             unsafe {
                 let (off, prev) = self.get_vec_pos();
 
-                // Only reuse space if we stand to gain at least capacity/2
-                // bytes of space back
-                if off >= additional && off >= (self.cap / 2) {
+                // Only reuse space if we can satisfy the requested additional space.
+                if self.capacity() - self.len() + off >= additional {
                     // There's space - reuse it
                     //
                     // Just move the pointer back to the start after copying
@@ -558,7 +579,8 @@ impl BytesMut {
                     self.cap += off;
                 } else {
                     // No space - allocate more
-                    let mut v = ManuallyDrop::new(rebuild_vec(self.ptr.as_ptr(), self.len, self.cap, off));
+                    let mut v =
+                        ManuallyDrop::new(rebuild_vec(self.ptr.as_ptr(), self.len, self.cap, off));
                     v.reserve(additional);
 
                     // Update the info
@@ -574,7 +596,6 @@ impl BytesMut {
         debug_assert_eq!(kind, KIND_ARC);
         let shared: *mut Shared = self.data as _;
 
-
         // Reserving involves abandoning the currently shared buffer and
         // allocating a new vector with the requested capacity.
         //
@@ -618,9 +639,7 @@ impl BytesMut {
                 // check.
                 let double = v.capacity().checked_shl(1).unwrap_or(new_cap);
 
-                new_cap = cmp::max(
-                    cmp::max(double, new_cap),
-                    original_capacity);
+                new_cap = cmp::max(cmp::max(double, new_cap), original_capacity);
             } else {
                 new_cap = cmp::max(new_cap, original_capacity);
             }
@@ -643,10 +662,11 @@ impl BytesMut {
         self.len = v.len();
         self.cap = v.capacity();
     }
-    /// Appends given bytes to this object.
+
+    /// Appends given bytes to this `BytesMut`.
     ///
-    /// If this `BytesMut` object has not enough capacity, it is resized first.
-    /// So unlike `put_slice` operation, `extend_from_slice` does not panic.
+    /// If this `BytesMut` object does not have enough capacity, it is resized
+    /// first.
     ///
     /// # Examples
     ///
@@ -668,19 +688,21 @@ impl BytesMut {
             // Reserved above
             debug_assert!(dst.len() >= cnt);
 
-            ptr::copy_nonoverlapping(
-                extend.as_ptr(),
-                dst.as_mut_ptr() as *mut u8,
-                cnt);
-
+            ptr::copy_nonoverlapping(extend.as_ptr(), dst.as_mut_ptr() as *mut u8, cnt);
         }
 
-        unsafe { self.advance_mut(cnt); }
+        unsafe {
+            self.advance_mut(cnt);
+        }
     }
 
-    /// Combine splitted BytesMut objects back as contiguous.
+    /// Absorbs a `BytesMut` that was previously split off.
     ///
-    /// If `BytesMut` objects were not contiguous originally, they will be extended.
+    /// If the two `BytesMut` objects were previously contiguous, i.e., if
+    /// `other` was created by calling `split_off` on this `BytesMut`, then
+    /// this is an `O(1)` operation that just decreases a reference
+    /// count and sets a few indices. Otherwise this method degenerates to
+    /// `self.extend_from_slice(other.as_ref())`.
     ///
     /// # Examples
     ///
@@ -690,11 +712,11 @@ impl BytesMut {
     /// let mut buf = BytesMut::with_capacity(64);
     /// buf.extend_from_slice(b"aaabbbcccddd");
     ///
-    /// let splitted = buf.split_off(6);
+    /// let split = buf.split_off(6);
     /// assert_eq!(b"aaabbb", &buf[..]);
-    /// assert_eq!(b"cccddd", &splitted[..]);
+    /// assert_eq!(b"cccddd", &split[..]);
     ///
-    /// buf.unsplit(splitted);
+    /// buf.unsplit(split);
     /// assert_eq!(b"aaabbbcccddd", &buf[..]);
     /// ```
     pub fn unsplit(&mut self, other: BytesMut) {
@@ -736,16 +758,12 @@ impl BytesMut {
 
     #[inline]
     fn as_slice(&self) -> &[u8] {
-        unsafe {
-            slice::from_raw_parts(self.ptr.as_ptr(), self.len)
-        }
+        unsafe { slice::from_raw_parts(self.ptr.as_ptr(), self.len) }
     }
 
     #[inline]
     fn as_slice_mut(&mut self) -> &mut [u8] {
-        unsafe {
-            slice::from_raw_parts_mut(self.ptr.as_ptr(), self.len)
-        }
+        unsafe { slice::from_raw_parts_mut(self.ptr.as_ptr(), self.len) }
     }
 
     unsafe fn set_start(&mut self, start: usize) {
@@ -755,7 +773,7 @@ impl BytesMut {
             return;
         }
 
-        debug_assert!(start <= self.cap);
+        debug_assert!(start <= self.cap, "internal: set_start out of bounds");
 
         let kind = self.kind();
 
@@ -774,7 +792,7 @@ impl BytesMut {
                 // on 64 bit systems and will only happen on 32 bit systems
                 // when shifting past 134,217,727 bytes. As such, we don't
                 // worry too much about performance here.
-                self.promote_to_shared(/*ref_count = */1);
+                self.promote_to_shared(/*ref_count = */ 1);
             }
         }
 
@@ -794,7 +812,7 @@ impl BytesMut {
 
     unsafe fn set_end(&mut self, end: usize) {
         debug_assert_eq!(self.kind(), KIND_ARC);
-        assert!(end <= self.cap);
+        assert!(end <= self.cap, "set_end out of bounds");
 
         self.cap = end;
         self.len = cmp::min(self.len, end);
@@ -806,10 +824,10 @@ impl BytesMut {
         }
 
         let ptr = unsafe { self.ptr.as_ptr().offset(self.len as isize) };
-        if ptr == other.ptr.as_ptr() &&
-           self.kind() == KIND_ARC &&
-           other.kind() == KIND_ARC &&
-           self.data == other.data
+        if ptr == other.ptr.as_ptr()
+            && self.kind() == KIND_ARC
+            && other.kind() == KIND_ARC
+            && self.data == other.data
         {
             // Contiguous blocks, just combine directly
             self.len += other.len;
@@ -870,7 +888,7 @@ impl BytesMut {
             increment_shared(self.data);
             ptr::read(self)
         } else {
-            self.promote_to_shared(/*ref_count = */2);
+            self.promote_to_shared(/*ref_count = */ 2);
             ptr::read(self)
         }
     }
@@ -932,8 +950,15 @@ impl Buf for BytesMut {
 
     #[inline]
     fn advance(&mut self, cnt: usize) {
-        assert!(cnt <= self.remaining(), "cannot advance past `remaining`");
-        unsafe { self.set_start(cnt); }
+        assert!(
+            cnt <= self.remaining(),
+            "cannot advance past `remaining`: {:?} <= {:?}",
+            cnt,
+            self.remaining(),
+        );
+        unsafe {
+            self.set_start(cnt);
+        }
     }
 
     fn to_bytes(&mut self) -> crate::Bytes {
@@ -950,7 +975,12 @@ impl BufMut for BytesMut {
     #[inline]
     unsafe fn advance_mut(&mut self, cnt: usize) {
         let new_len = self.len() + cnt;
-        assert!(new_len <= self.cap, "new_len = {}; capacity = {}", new_len, self.cap);
+        assert!(
+            new_len <= self.cap,
+            "new_len = {}; capacity = {}",
+            new_len,
+            self.cap
+        );
         self.len = new_len;
     }
 
@@ -965,7 +995,10 @@ impl BufMut for BytesMut {
     // Specialize these methods so they can skip checking `remaining_mut`
     // and `advance_mut`.
 
-    fn put<T: crate::Buf>(&mut self, mut src: T) where Self: Sized {
+    fn put<T: crate::Buf>(&mut self, mut src: T)
+    where
+        Self: Sized,
+    {
         while src.has_remaining() {
             let s = src.bytes();
             let l = s.len();
@@ -996,6 +1029,7 @@ impl Deref for BytesMut {
 }
 
 impl AsMut<[u8]> for BytesMut {
+    #[inline]
     fn as_mut(&mut self) -> &mut [u8] {
         self.as_slice_mut()
     }
@@ -1020,6 +1054,12 @@ impl<'a> From<&'a str> for BytesMut {
     }
 }
 
+impl From<BytesMut> for Bytes {
+    fn from(src: BytesMut) -> Bytes {
+        src.freeze()
+    }
+}
+
 impl PartialEq for BytesMut {
     fn eq(&self, other: &BytesMut) -> bool {
         self.as_slice() == other.as_slice()
@@ -1038,8 +1078,7 @@ impl Ord for BytesMut {
     }
 }
 
-impl Eq for BytesMut {
-}
+impl Eq for BytesMut {}
 
 impl Default for BytesMut {
     #[inline]
@@ -1048,14 +1087,11 @@ impl Default for BytesMut {
     }
 }
 
-impl fmt::Debug for BytesMut {
-    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
-        fmt::Debug::fmt(&debug::BsDebug(&self.as_slice()), fmt)
-    }
-}
-
 impl hash::Hash for BytesMut {
-    fn hash<H>(&self, state: &mut H) where H: hash::Hasher {
+    fn hash<H>(&self, state: &mut H)
+    where
+        H: hash::Hasher,
+    {
         let s: &[u8] = self.as_ref();
         s.hash(state);
     }
@@ -1115,7 +1151,10 @@ impl<'a> IntoIterator for &'a BytesMut {
 }
 
 impl Extend<u8> for BytesMut {
-    fn extend<T>(&mut self, iter: T) where T: IntoIterator<Item = u8> {
+    fn extend<T>(&mut self, iter: T)
+    where
+        T: IntoIterator<Item = u8>,
+    {
         let iter = iter.into_iter();
 
         let (lower, _) = iter.size_hint();
@@ -1132,7 +1171,10 @@ impl Extend<u8> for BytesMut {
 }
 
 impl<'a> Extend<&'a u8> for BytesMut {
-    fn extend<T>(&mut self, iter: T) where T: IntoIterator<Item = &'a u8> {
+    fn extend<T>(&mut self, iter: T)
+    where
+        T: IntoIterator<Item = &'a u8>,
+    {
         self.extend(iter.into_iter().map(|b| *b))
     }
 }
@@ -1210,7 +1252,10 @@ impl Shared {
 
 fn original_capacity_to_repr(cap: usize) -> usize {
     let width = PTR_WIDTH - ((cap >> MIN_ORIGINAL_CAPACITY_WIDTH).leading_zeros() as usize);
-    cmp::min(width, MAX_ORIGINAL_CAPACITY_WIDTH - MIN_ORIGINAL_CAPACITY_WIDTH)
+    cmp::min(
+        width,
+        MAX_ORIGINAL_CAPACITY_WIDTH - MIN_ORIGINAL_CAPACITY_WIDTH,
+    )
 }
 
 fn original_capacity_from_repr(repr: usize) -> usize {
@@ -1301,7 +1346,7 @@ impl PartialEq<BytesMut> for [u8] {
 
 impl PartialOrd<BytesMut> for [u8] {
     fn partial_cmp(&self, other: &BytesMut) -> Option<cmp::Ordering> {
-        other.partial_cmp(self)
+        <[u8] as PartialOrd<[u8]>>::partial_cmp(self, other)
     }
 }
 
@@ -1325,7 +1370,7 @@ impl PartialEq<BytesMut> for str {
 
 impl PartialOrd<BytesMut> for str {
     fn partial_cmp(&self, other: &BytesMut) -> Option<cmp::Ordering> {
-        other.partial_cmp(self)
+        <[u8] as PartialOrd<[u8]>>::partial_cmp(self.as_bytes(), other)
     }
 }
 
@@ -1373,12 +1418,13 @@ impl PartialEq<BytesMut> for String {
 
 impl PartialOrd<BytesMut> for String {
     fn partial_cmp(&self, other: &BytesMut) -> Option<cmp::Ordering> {
-        other.partial_cmp(self)
+        <[u8] as PartialOrd<[u8]>>::partial_cmp(self.as_bytes(), other)
     }
 }
 
 impl<'a, T: ?Sized> PartialEq<&'a T> for BytesMut
-    where BytesMut: PartialEq<T>
+where
+    BytesMut: PartialEq<T>,
 {
     fn eq(&self, other: &&'a T) -> bool {
         *self == **other
@@ -1386,7 +1432,8 @@ impl<'a, T: ?Sized> PartialEq<&'a T> for BytesMut
 }
 
 impl<'a, T: ?Sized> PartialOrd<&'a T> for BytesMut
-    where BytesMut: PartialOrd<T>
+where
+    BytesMut: PartialOrd<T>,
 {
     fn partial_cmp(&self, other: &&'a T) -> Option<cmp::Ordering> {
         self.partial_cmp(*other)
@@ -1401,7 +1448,7 @@ impl PartialEq<BytesMut> for &[u8] {
 
 impl PartialOrd<BytesMut> for &[u8] {
     fn partial_cmp(&self, other: &BytesMut) -> Option<cmp::Ordering> {
-        other.partial_cmp(self)
+        <[u8] as PartialOrd<[u8]>>::partial_cmp(self, other)
     }
 }
 
@@ -1453,7 +1500,7 @@ static SHARED_VTABLE: Vtable = Vtable {
 };
 
 unsafe fn shared_v_clone(data: &AtomicPtr<()>, ptr: *const u8, len: usize) -> Bytes {
-    let shared = data.load(Ordering::Acquire) as *mut Shared;
+    let shared = data.load(Ordering::Relaxed) as *mut Shared;
     increment_shared(shared);
 
     let data = AtomicPtr::new(shared as _);
@@ -1461,8 +1508,9 @@ unsafe fn shared_v_clone(data: &AtomicPtr<()>, ptr: *const u8, len: usize) -> By
 }
 
 unsafe fn shared_v_drop(data: &mut AtomicPtr<()>, _ptr: *const u8, _len: usize) {
-    let shared = (*data.get_mut()) as *mut Shared;
-    release_shared(shared as *mut Shared);
+    data.with_mut(|shared| {
+        release_shared(*shared as *mut Shared);
+    });
 }
 
 // compile-fails
@@ -1500,11 +1548,11 @@ fn _split_must_use() {}
 // fuzz tests
 #[cfg(all(test, loom))]
 mod fuzz {
-    use std::sync::Arc;
+    use loom::sync::Arc;
     use loom::thread;
 
-    use crate::Bytes;
     use super::BytesMut;
+    use crate::Bytes;
 
     #[test]
     fn bytes_mut_cloning_frozen() {
diff --git a/third_party/rust/bytes/src/debug.rs b/third_party/rust/bytes/src/debug.rs
deleted file mode 100644
index b1a3cc81895c91b3e828a6a13ea9ec27fcdabb6a..0000000000000000000000000000000000000000
--- a/third_party/rust/bytes/src/debug.rs
+++ /dev/null
@@ -1,40 +0,0 @@
-use core::fmt;
-
-/// Alternative implementation of `fmt::Debug` for byte slice.
-///
-/// Standard `Debug` implementation for `[u8]` is comma separated
-/// list of numbers. Since large amount of byte strings are in fact
-/// ASCII strings or contain a lot of ASCII strings (e. g. HTTP),
-/// it is convenient to print strings as ASCII when possible.
-///
-/// This struct wraps `&[u8]` just to override `fmt::Debug`.
-///
-/// `BsDebug` is not a part of public API of bytes crate.
-pub struct BsDebug<'a>(pub &'a [u8]);
-
-impl fmt::Debug for BsDebug<'_> {
-    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
-        write!(fmt, "b\"")?;
-        for &c in self.0 {
-            // https://doc.rust-lang.org/reference.html#byte-escapes
-            if c == b'\n' {
-                write!(fmt, "\\n")?;
-            } else if c == b'\r' {
-                write!(fmt, "\\r")?;
-            } else if c == b'\t' {
-                write!(fmt, "\\t")?;
-            } else if c == b'\\' || c == b'"' {
-                write!(fmt, "\\{}", c as char)?;
-            } else if c == b'\0' {
-                write!(fmt, "\\0")?;
-            // ASCII printable
-            } else if c >= 0x20 && c < 0x7f {
-                write!(fmt, "{}", c as char)?;
-            } else {
-                write!(fmt, "\\x{:02x}", c)?;
-            }
-        }
-        write!(fmt, "\"")?;
-        Ok(())
-    }
-}
diff --git a/third_party/rust/bytes/src/fmt/debug.rs b/third_party/rust/bytes/src/fmt/debug.rs
new file mode 100644
index 0000000000000000000000000000000000000000..a8545514e3268d77e6c1b8581549c47a4b313e86
--- /dev/null
+++ b/third_party/rust/bytes/src/fmt/debug.rs
@@ -0,0 +1,49 @@
+use core::fmt::{Debug, Formatter, Result};
+
+use super::BytesRef;
+use crate::{Bytes, BytesMut};
+
+/// Alternative implementation of `std::fmt::Debug` for byte slice.
+///
+/// Standard `Debug` implementation for `[u8]` is comma separated
+/// list of numbers. Since large amount of byte strings are in fact
+/// ASCII strings or contain a lot of ASCII strings (e. g. HTTP),
+/// it is convenient to print strings as ASCII when possible.
+impl Debug for BytesRef<'_> {
+    fn fmt(&self, f: &mut Formatter<'_>) -> Result {
+        write!(f, "b\"")?;
+        for &b in self.0 {
+            // https://doc.rust-lang.org/reference/tokens.html#byte-escapes
+            if b == b'\n' {
+                write!(f, "\\n")?;
+            } else if b == b'\r' {
+                write!(f, "\\r")?;
+            } else if b == b'\t' {
+                write!(f, "\\t")?;
+            } else if b == b'\\' || b == b'"' {
+                write!(f, "\\{}", b as char)?;
+            } else if b == b'\0' {
+                write!(f, "\\0")?;
+            // ASCII printable
+            } else if b >= 0x20 && b < 0x7f {
+                write!(f, "{}", b as char)?;
+            } else {
+                write!(f, "\\x{:02x}", b)?;
+            }
+        }
+        write!(f, "\"")?;
+        Ok(())
+    }
+}
+
+impl Debug for Bytes {
+    fn fmt(&self, f: &mut Formatter<'_>) -> Result {
+        Debug::fmt(&BytesRef(&self.as_ref()), f)
+    }
+}
+
+impl Debug for BytesMut {
+    fn fmt(&self, f: &mut Formatter<'_>) -> Result {
+        Debug::fmt(&BytesRef(&self.as_ref()), f)
+    }
+}
diff --git a/third_party/rust/bytes/src/hex.rs b/third_party/rust/bytes/src/fmt/hex.rs
similarity index 81%
rename from third_party/rust/bytes/src/hex.rs
rename to third_party/rust/bytes/src/fmt/hex.rs
index 48ae6a42c1a8c6fb4584d5e7cf7b64d01659d56e..97a749a3368299ce7ec68f556fdeb93f55f8803c 100644
--- a/third_party/rust/bytes/src/hex.rs
+++ b/third_party/rust/bytes/src/fmt/hex.rs
@@ -1,20 +1,20 @@
-use crate::{Bytes, BytesMut};
 use core::fmt::{Formatter, LowerHex, Result, UpperHex};
 
-struct BytesRef<'a>(&'a [u8]);
+use super::BytesRef;
+use crate::{Bytes, BytesMut};
 
-impl<'a> LowerHex for BytesRef<'a> {
+impl LowerHex for BytesRef<'_> {
     fn fmt(&self, f: &mut Formatter<'_>) -> Result {
-        for b in self.0 {
+        for &b in self.0 {
             write!(f, "{:02x}", b)?;
         }
         Ok(())
     }
 }
 
-impl<'a> UpperHex for BytesRef<'a> {
+impl UpperHex for BytesRef<'_> {
     fn fmt(&self, f: &mut Formatter<'_>) -> Result {
-        for b in self.0 {
+        for &b in self.0 {
             write!(f, "{:02X}", b)?;
         }
         Ok(())
diff --git a/third_party/rust/bytes/src/fmt/mod.rs b/third_party/rust/bytes/src/fmt/mod.rs
new file mode 100644
index 0000000000000000000000000000000000000000..676d15fc21f1f0b09c38373feb960f98f2e07522
--- /dev/null
+++ b/third_party/rust/bytes/src/fmt/mod.rs
@@ -0,0 +1,5 @@
+mod debug;
+mod hex;
+
+/// `BytesRef` is not a part of public API of bytes crate.
+struct BytesRef<'a>(&'a [u8]);
diff --git a/third_party/rust/bytes/src/lib.rs b/third_party/rust/bytes/src/lib.rs
index 2df1fb3b23afcbbfeb99e7045e0e648750723a76..e375c01b1ac095757ec80335a1b20bce5933ee5e 100644
--- a/third_party/rust/bytes/src/lib.rs
+++ b/third_party/rust/bytes/src/lib.rs
@@ -1,5 +1,9 @@
-#![deny(warnings, missing_docs, missing_debug_implementations, rust_2018_idioms)]
-#![doc(html_root_url = "https://docs.rs/bytes/0.5.3")]
+#![warn(missing_docs, missing_debug_implementations, rust_2018_idioms)]
+#![doc(test(
+    no_crate_inject,
+    attr(deny(warnings, rust_2018_idioms), allow(dead_code, unused_variables))
+))]
+#![doc(html_root_url = "https://docs.rs/bytes/0.5.6")]
 #![no_std]
 
 //! Provides abstractions for working with bytes.
@@ -72,25 +76,20 @@
 //! perform a syscall, which has the potential of failing. Operations on `Buf`
 //! and `BufMut` are infallible.
 
-
 extern crate alloc;
 
 #[cfg(feature = "std")]
 extern crate std;
 
 pub mod buf;
-pub use crate::buf::{
-    Buf,
-    BufMut,
-};
+pub use crate::buf::{Buf, BufMut};
 
-mod bytes_mut;
 mod bytes;
-mod debug;
-mod hex;
+mod bytes_mut;
+mod fmt;
 mod loom;
-pub use crate::bytes_mut::BytesMut;
 pub use crate::bytes::Bytes;
+pub use crate::bytes_mut::BytesMut;
 
 // Optional Serde support
 #[cfg(feature = "serde")]
diff --git a/third_party/rust/bytes/src/loom.rs b/third_party/rust/bytes/src/loom.rs
index 80947acecc0c43905b0db5ad6f120ee0fe5791b3..1cae8812e6a25c77e8222679a7316facf0632aaa 100644
--- a/third_party/rust/bytes/src/loom.rs
+++ b/third_party/rust/bytes/src/loom.rs
@@ -2,8 +2,29 @@
 pub(crate) mod sync {
     pub(crate) mod atomic {
         pub(crate) use core::sync::atomic::{fence, AtomicPtr, AtomicUsize, Ordering};
+
+        pub(crate) trait AtomicMut<T> {
+            fn with_mut<F, R>(&mut self, f: F) -> R
+            where
+                F: FnOnce(&mut *mut T) -> R;
+        }
+
+        impl<T> AtomicMut<T> for AtomicPtr<T> {
+            fn with_mut<F, R>(&mut self, f: F) -> R
+            where
+                F: FnOnce(&mut *mut T) -> R,
+            {
+                f(self.get_mut())
+            }
+        }
     }
 }
 
 #[cfg(all(test, loom))]
-pub(crate) use ::loom::sync;
+pub(crate) mod sync {
+    pub(crate) mod atomic {
+        pub(crate) use loom::sync::atomic::{fence, AtomicPtr, AtomicUsize, Ordering};
+
+        pub(crate) trait AtomicMut<T> {}
+    }
+}
diff --git a/third_party/rust/bytes/src/serde.rs b/third_party/rust/bytes/src/serde.rs
index 11020ae7f02f25fe963690693c85e8d3fe443262..0a5bd144a960ac4d8eb771da7eea36094e088375 100644
--- a/third_party/rust/bytes/src/serde.rs
+++ b/third_party/rust/bytes/src/serde.rs
@@ -1,15 +1,16 @@
+use super::{Bytes, BytesMut};
 use alloc::string::String;
 use alloc::vec::Vec;
 use core::{cmp, fmt};
-use serde::{Serialize, Serializer, Deserialize, Deserializer, de};
-use super::{Bytes, BytesMut};
+use serde::{de, Deserialize, Deserializer, Serialize, Serializer};
 
 macro_rules! serde_impl {
-    ($ty:ident, $visitor_ty:ident, $from_slice:ident, $from_vec:ident) => (
+    ($ty:ident, $visitor_ty:ident, $from_slice:ident, $from_vec:ident) => {
         impl Serialize for $ty {
             #[inline]
             fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
-                where S: Serializer
+            where
+                S: Serializer,
             {
                 serializer.serialize_bytes(&self)
             }
@@ -26,7 +27,8 @@ macro_rules! serde_impl {
 
             #[inline]
             fn visit_seq<V>(self, mut seq: V) -> Result<Self::Value, V::Error>
-                where V: de::SeqAccess<'de>
+            where
+                V: de::SeqAccess<'de>,
             {
                 let len = cmp::min(seq.size_hint().unwrap_or(0), 4096);
                 let mut values: Vec<u8> = Vec::with_capacity(len);
@@ -40,28 +42,32 @@ macro_rules! serde_impl {
 
             #[inline]
             fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
-                where E: de::Error
+            where
+                E: de::Error,
             {
                 Ok($ty::$from_slice(v))
             }
 
             #[inline]
             fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<Self::Value, E>
-                where E: de::Error
+            where
+                E: de::Error,
             {
                 Ok($ty::$from_vec(v))
             }
 
             #[inline]
             fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
-                where E: de::Error
+            where
+                E: de::Error,
             {
                 Ok($ty::$from_slice(v.as_bytes()))
             }
 
             #[inline]
             fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
-                where E: de::Error
+            where
+                E: de::Error,
             {
                 Ok($ty::$from_vec(v.into_bytes()))
             }
@@ -70,12 +76,13 @@ macro_rules! serde_impl {
         impl<'de> Deserialize<'de> for $ty {
             #[inline]
             fn deserialize<D>(deserializer: D) -> Result<$ty, D::Error>
-                where D: Deserializer<'de>
+            where
+                D: Deserializer<'de>,
             {
                 deserializer.deserialize_byte_buf($visitor_ty)
             }
         }
-    );
+    };
 }
 
 serde_impl!(Bytes, BytesVisitor, copy_from_slice, from);
diff --git a/third_party/rust/bytes/tests/test_buf.rs b/third_party/rust/bytes/tests/test_buf.rs
index 12b75a4ad74df950993538639137186d4288e8d9..17bdd54e821afd7a3f73c81f62a21d085fca1e22 100644
--- a/third_party/rust/bytes/tests/test_buf.rs
+++ b/third_party/rust/bytes/tests/test_buf.rs
@@ -1,6 +1,7 @@
-#![deny(warnings, rust_2018_idioms)]
+#![warn(rust_2018_idioms)]
 
 use bytes::Buf;
+#[cfg(feature = "std")]
 use std::io::IoSlice;
 
 #[test]
@@ -42,6 +43,7 @@ fn test_get_u16_buffer_underflow() {
     buf.get_u16();
 }
 
+#[cfg(feature = "std")]
 #[test]
 fn test_bufs_vec() {
     let buf = &b"hello world"[..];
diff --git a/third_party/rust/bytes/tests/test_buf_mut.rs b/third_party/rust/bytes/tests/test_buf_mut.rs
index f002f7d5ffef811cb8fda49676db84adfd29f9a9..b91e2e511919c5e16a5dcab71c48030b66331aed 100644
--- a/third_party/rust/bytes/tests/test_buf_mut.rs
+++ b/third_party/rust/bytes/tests/test_buf_mut.rs
@@ -1,8 +1,10 @@
-#![deny(warnings, rust_2018_idioms)]
+#![warn(rust_2018_idioms)]
 
-use bytes::{buf::IoSliceMut, BufMut, BytesMut};
-use std::usize;
-use std::fmt::Write;
+#[cfg(feature = "std")]
+use bytes::buf::IoSliceMut;
+use bytes::{BufMut, BytesMut};
+use core::fmt::Write;
+use core::usize;
 
 #[test]
 fn test_vec_as_mut_buf() {
@@ -45,13 +47,12 @@ fn test_put_u16() {
 }
 
 #[test]
+#[should_panic(expected = "cannot advance")]
 fn test_vec_advance_mut() {
-    // Regression test for carllerche/bytes#108.
+    // Verify fix for #354
     let mut buf = Vec::with_capacity(8);
     unsafe {
         buf.advance_mut(12);
-        assert_eq!(buf.len(), 12);
-        assert!(buf.capacity() >= 12, "capacity: {}", buf.capacity());
     }
 }
 
@@ -65,6 +66,7 @@ fn test_clone() {
     assert!(buf != buf2);
 }
 
+#[cfg(feature = "std")]
 #[test]
 fn test_bufs_vec_mut() {
     let b1: &mut [u8] = &mut [];
diff --git a/third_party/rust/bytes/tests/test_bytes.rs b/third_party/rust/bytes/tests/test_bytes.rs
index b58262756675cf59235abd1cae23b0a588c41f4b..6b106a6bcdd152993fb527ff8313eb823ec3b186 100644
--- a/third_party/rust/bytes/tests/test_bytes.rs
+++ b/third_party/rust/bytes/tests/test_bytes.rs
@@ -1,6 +1,6 @@
-#![deny(warnings, rust_2018_idioms)]
+#![warn(rust_2018_idioms)]
 
-use bytes::{Bytes, BytesMut, Buf, BufMut};
+use bytes::{Buf, BufMut, Bytes, BytesMut};
 
 use std::usize;
 
@@ -44,7 +44,6 @@ fn test_layout() {
         mem::size_of::<Option<BytesMut>>(),
         "BytesMut should be same size as Option<BytesMut>",
     );
-
 }
 
 #[test]
@@ -87,13 +86,11 @@ fn fmt_write() {
     write!(a, "{}", &s[..64]).unwrap();
     assert_eq!(a, s[..64].as_bytes());
 
-
     let mut b = BytesMut::with_capacity(64);
     write!(b, "{}", &s[..32]).unwrap();
     write!(b, "{}", &s[32..64]).unwrap();
     assert_eq!(b, s[..64].as_bytes());
 
-
     let mut c = BytesMut::with_capacity(64);
     write!(c, "{}", s).unwrap();
     assert_eq!(c, s[..].as_bytes());
@@ -305,11 +302,13 @@ fn split_off_to_at_gt_len() {
 
     assert!(panic::catch_unwind(move || {
         let _ = make_bytes().split_to(5);
-    }).is_err());
+    })
+    .is_err());
 
     assert!(panic::catch_unwind(move || {
         let _ = make_bytes().split_off(5);
-    }).is_err());
+    })
+    .is_err());
 }
 
 #[test]
@@ -342,6 +341,72 @@ fn freeze_clone_unique() {
     assert_eq!(c, s);
 }
 
+#[test]
+fn freeze_after_advance() {
+    let s = &b"abcdefgh"[..];
+    let mut b = BytesMut::from(s);
+    b.advance(1);
+    assert_eq!(b, s[1..]);
+    let b = b.freeze();
+    // Verify fix for #352. Previously, freeze would ignore the start offset
+    // for BytesMuts in Vec mode.
+    assert_eq!(b, s[1..]);
+}
+
+#[test]
+fn freeze_after_advance_arc() {
+    let s = &b"abcdefgh"[..];
+    let mut b = BytesMut::from(s);
+    // Make b Arc
+    let _ = b.split_to(0);
+    b.advance(1);
+    assert_eq!(b, s[1..]);
+    let b = b.freeze();
+    assert_eq!(b, s[1..]);
+}
+
+#[test]
+fn freeze_after_split_to() {
+    let s = &b"abcdefgh"[..];
+    let mut b = BytesMut::from(s);
+    let _ = b.split_to(1);
+    assert_eq!(b, s[1..]);
+    let b = b.freeze();
+    assert_eq!(b, s[1..]);
+}
+
+#[test]
+fn freeze_after_truncate() {
+    let s = &b"abcdefgh"[..];
+    let mut b = BytesMut::from(s);
+    b.truncate(7);
+    assert_eq!(b, s[..7]);
+    let b = b.freeze();
+    assert_eq!(b, s[..7]);
+}
+
+#[test]
+fn freeze_after_truncate_arc() {
+    let s = &b"abcdefgh"[..];
+    let mut b = BytesMut::from(s);
+    // Make b Arc
+    let _ = b.split_to(0);
+    b.truncate(7);
+    assert_eq!(b, s[..7]);
+    let b = b.freeze();
+    assert_eq!(b, s[..7]);
+}
+
+#[test]
+fn freeze_after_split_off() {
+    let s = &b"abcdefgh"[..];
+    let mut b = BytesMut::from(s);
+    let _ = b.split_off(7);
+    assert_eq!(b, s[..7]);
+    let b = b.freeze();
+    assert_eq!(b, s[..7]);
+}
+
 #[test]
 fn fns_defined_for_bytes_mut() {
     let mut bytes = BytesMut::from(&b"hello world"[..]);
@@ -798,7 +863,6 @@ fn slice_ref_works() {
     test_slice_ref(&bytes, 9, 9, b"");
 }
 
-
 #[test]
 fn slice_ref_empty() {
     let bytes = Bytes::from(&b""[..]);
@@ -808,6 +872,16 @@ fn slice_ref_empty() {
     assert_eq!(&sub[..], b"");
 }
 
+#[test]
+fn slice_ref_empty_subslice() {
+    let bytes = Bytes::from(&b"abcde"[..]);
+    let subbytes = bytes.slice(0..0);
+    let slice = &subbytes[..];
+    // The `slice` object is derived from the original `bytes` object
+    // so `slice_ref` should work.
+    assert_eq!(Bytes::new(), bytes.slice_ref(slice));
+}
+
 #[test]
 #[should_panic]
 fn slice_ref_catches_not_a_subset() {
@@ -818,30 +892,19 @@ fn slice_ref_catches_not_a_subset() {
 }
 
 #[test]
-#[should_panic]
-fn slice_ref_catches_not_an_empty_subset() {
+fn slice_ref_not_an_empty_subset() {
     let bytes = Bytes::from(&b"012345678"[..]);
     let slice = &b""[0..0];
 
-    bytes.slice_ref(slice);
+    assert_eq!(Bytes::new(), bytes.slice_ref(slice));
 }
 
 #[test]
-#[should_panic]
-fn empty_slice_ref_catches_not_an_empty_subset() {
+fn empty_slice_ref_not_an_empty_subset() {
     let bytes = Bytes::new();
     let slice = &b"some other slice"[0..0];
 
-    // Protect this test against Bytes internals.
-    //
-    // This should panic *because* the slice's ptr doesn't fit in the range
-    // of the `bytes`.
-    if bytes.as_ptr() as usize == slice.as_ptr() as usize {
-        // don't panic, failing the test
-        return;
-    }
-
-    bytes.slice_ref(slice);
+    assert_eq!(Bytes::new(), bytes.slice_ref(slice));
 }
 
 #[test]
@@ -866,6 +929,22 @@ fn bytes_buf_mut_advance() {
     }
 }
 
+#[test]
+fn bytes_buf_mut_reuse_when_fully_consumed() {
+    use bytes::{Buf, BytesMut};
+    let mut buf = BytesMut::new();
+    buf.reserve(8192);
+    buf.extend_from_slice(&[0u8; 100][..]);
+
+    let p = &buf[0] as *const u8;
+    buf.advance(100);
+
+    buf.reserve(8192);
+    buf.extend_from_slice(b" ");
+
+    assert_eq!(&buf[0] as *const u8, p);
+}
+
 #[test]
 #[should_panic]
 fn bytes_reserve_overflow() {
diff --git a/third_party/rust/bytes/tests/test_bytes_odd_alloc.rs b/third_party/rust/bytes/tests/test_bytes_odd_alloc.rs
new file mode 100644
index 0000000000000000000000000000000000000000..4ce424b7c00a71902c0c5172a53c6aa02f171c04
--- /dev/null
+++ b/third_party/rust/bytes/tests/test_bytes_odd_alloc.rs
@@ -0,0 +1,67 @@
+//! Test using `Bytes` with an allocator that hands out "odd" pointers for
+//! vectors (pointers where the LSB is set).
+
+use std::alloc::{GlobalAlloc, Layout, System};
+use std::ptr;
+
+use bytes::Bytes;
+
+#[global_allocator]
+static ODD: Odd = Odd;
+
+struct Odd;
+
+unsafe impl GlobalAlloc for Odd {
+    unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
+        if layout.align() == 1 && layout.size() > 0 {
+            // Allocate slightly bigger so that we can offset the pointer by 1
+            let size = layout.size() + 1;
+            let new_layout = match Layout::from_size_align(size, 1) {
+                Ok(layout) => layout,
+                Err(_err) => return ptr::null_mut(),
+            };
+            let ptr = System.alloc(new_layout);
+            if !ptr.is_null() {
+                let ptr = ptr.offset(1);
+                ptr
+            } else {
+                ptr
+            }
+        } else {
+            System.alloc(layout)
+        }
+    }
+
+    unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {
+        if layout.align() == 1 && layout.size() > 0 {
+            let size = layout.size() + 1;
+            let new_layout = match Layout::from_size_align(size, 1) {
+                Ok(layout) => layout,
+                Err(_err) => std::process::abort(),
+            };
+            System.dealloc(ptr.offset(-1), new_layout);
+        } else {
+            System.dealloc(ptr, layout);
+        }
+    }
+}
+
+#[test]
+fn sanity_check_odd_allocator() {
+    let vec = vec![33u8; 1024];
+    let p = vec.as_ptr() as usize;
+    assert!(p & 0x1 == 0x1, "{:#b}", p);
+}
+
+#[test]
+fn test_bytes_from_vec_drop() {
+    let vec = vec![33u8; 1024];
+    let _b = Bytes::from(vec);
+}
+
+#[test]
+fn test_bytes_clone_drop() {
+    let vec = vec![33u8; 1024];
+    let b1 = Bytes::from(vec);
+    let _b2 = b1.clone();
+}
diff --git a/third_party/rust/bytes/tests/test_bytes_vec_alloc.rs b/third_party/rust/bytes/tests/test_bytes_vec_alloc.rs
new file mode 100644
index 0000000000000000000000000000000000000000..418a9cd64f89c94bd5f60a8da71e3577c33d71d4
--- /dev/null
+++ b/third_party/rust/bytes/tests/test_bytes_vec_alloc.rs
@@ -0,0 +1,79 @@
+use std::alloc::{GlobalAlloc, Layout, System};
+use std::{mem, ptr};
+
+use bytes::{Buf, Bytes};
+
+#[global_allocator]
+static LEDGER: Ledger = Ledger;
+
+struct Ledger;
+
+const USIZE_SIZE: usize = mem::size_of::<usize>();
+
+unsafe impl GlobalAlloc for Ledger {
+    unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
+        if layout.align() == 1 && layout.size() > 0 {
+            // Allocate extra space to stash a record of
+            // how much space there was.
+            let orig_size = layout.size();
+            let size = orig_size + USIZE_SIZE;
+            let new_layout = match Layout::from_size_align(size, 1) {
+                Ok(layout) => layout,
+                Err(_err) => return ptr::null_mut(),
+            };
+            let ptr = System.alloc(new_layout);
+            if !ptr.is_null() {
+                (ptr as *mut usize).write(orig_size);
+                let ptr = ptr.offset(USIZE_SIZE as isize);
+                ptr
+            } else {
+                ptr
+            }
+        } else {
+            System.alloc(layout)
+        }
+    }
+
+    unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {
+        if layout.align() == 1 && layout.size() > 0 {
+            let off_ptr = (ptr as *mut usize).offset(-1);
+            let orig_size = off_ptr.read();
+            if orig_size != layout.size() {
+                panic!(
+                    "bad dealloc: alloc size was {}, dealloc size is {}",
+                    orig_size,
+                    layout.size()
+                );
+            }
+
+            let new_layout = match Layout::from_size_align(layout.size() + USIZE_SIZE, 1) {
+                Ok(layout) => layout,
+                Err(_err) => std::process::abort(),
+            };
+            System.dealloc(off_ptr as *mut u8, new_layout);
+        } else {
+            System.dealloc(ptr, layout);
+        }
+    }
+}
+#[test]
+fn test_bytes_advance() {
+    let mut bytes = Bytes::from(vec![10, 20, 30]);
+    bytes.advance(1);
+    drop(bytes);
+}
+
+#[test]
+fn test_bytes_truncate() {
+    let mut bytes = Bytes::from(vec![10, 20, 30]);
+    bytes.truncate(2);
+    drop(bytes);
+}
+
+#[test]
+fn test_bytes_truncate_and_advance() {
+    let mut bytes = Bytes::from(vec![10, 20, 30]);
+    bytes.truncate(2);
+    bytes.advance(1);
+    drop(bytes);
+}
diff --git a/third_party/rust/bytes/tests/test_chain.rs b/third_party/rust/bytes/tests/test_chain.rs
index 332571d8b33395892dd48f283309fc357c80bb82..6dbc45d04858adc9f36d0dc3f4f7ffe13f595353 100644
--- a/third_party/rust/bytes/tests/test_chain.rs
+++ b/third_party/rust/bytes/tests/test_chain.rs
@@ -1,7 +1,8 @@
-#![deny(warnings, rust_2018_idioms)]
+#![warn(rust_2018_idioms)]
 
-use bytes::{Buf, BufMut, Bytes};
 use bytes::buf::{BufExt, BufMutExt};
+use bytes::{Buf, BufMut, Bytes};
+#[cfg(feature = "std")]
 use std::io::IoSlice;
 
 #[test]
@@ -42,6 +43,7 @@ fn iterating_two_bufs() {
     assert_eq!(res, &b"helloworld"[..]);
 }
 
+#[cfg(feature = "std")]
 #[test]
 fn vectored_read() {
     let a = Bytes::from(&b"hello"[..]);
diff --git a/third_party/rust/bytes/tests/test_debug.rs b/third_party/rust/bytes/tests/test_debug.rs
index 7528bac87b0282c68db954268244f8522221f586..08d2f254e81964cc5cd162a2bd9118ca8a4513a8 100644
--- a/third_party/rust/bytes/tests/test_debug.rs
+++ b/third_party/rust/bytes/tests/test_debug.rs
@@ -1,4 +1,4 @@
-#![deny(warnings, rust_2018_idioms)]
+#![warn(rust_2018_idioms)]
 
 use bytes::Bytes;
 
diff --git a/third_party/rust/bytes/tests/test_iter.rs b/third_party/rust/bytes/tests/test_iter.rs
index 13b86cdad4546d5485c986ed7812723a0a7d3263..a5bfddddf5e9d8acbf4a3513041819b90b7d3a1d 100644
--- a/third_party/rust/bytes/tests/test_iter.rs
+++ b/third_party/rust/bytes/tests/test_iter.rs
@@ -1,4 +1,4 @@
-#![deny(warnings, rust_2018_idioms)]
+#![warn(rust_2018_idioms)]
 
 use bytes::Bytes;
 
@@ -11,7 +11,6 @@ fn iter_len() {
     assert_eq!(iter.len(), 11);
 }
 
-
 #[test]
 fn empty_iter_len() {
     let buf = Bytes::from_static(b"");
diff --git a/third_party/rust/bytes/tests/test_reader.rs b/third_party/rust/bytes/tests/test_reader.rs
index 9c5972a96527a7d0a51b1494db14a81aec55e7ce..10b480fcc389bc5ef7150d94cf9df8c9fe612c71 100644
--- a/third_party/rust/bytes/tests/test_reader.rs
+++ b/third_party/rust/bytes/tests/test_reader.rs
@@ -1,8 +1,9 @@
-#![deny(warnings, rust_2018_idioms)]
+#![warn(rust_2018_idioms)]
+#![cfg(feature = "std")]
 
 use std::io::{BufRead, Read};
 
-use bytes::buf::{BufExt};
+use bytes::buf::BufExt;
 
 #[test]
 fn read() {
diff --git a/third_party/rust/bytes/tests/test_serde.rs b/third_party/rust/bytes/tests/test_serde.rs
index 18b135692bcdd973b664cd79be13f0818cd9a436..cf4aeffa78542677cf8f737d6ede0af9def92bad 100644
--- a/third_party/rust/bytes/tests/test_serde.rs
+++ b/third_party/rust/bytes/tests/test_serde.rs
@@ -1,7 +1,7 @@
 #![cfg(feature = "serde")]
-#![deny(warnings, rust_2018_idioms)]
+#![warn(rust_2018_idioms)]
 
-use serde_test::{Token, assert_tokens};
+use serde_test::{assert_tokens, Token};
 
 #[test]
 fn test_ser_de_empty() {
diff --git a/third_party/rust/bytes/tests/test_take.rs b/third_party/rust/bytes/tests/test_take.rs
index b9b525b1f884e89723ea6b4e7061738ec1947afc..0afb28bb4dccd097bb7a5f146429e6e61e302264 100644
--- a/third_party/rust/bytes/tests/test_take.rs
+++ b/third_party/rust/bytes/tests/test_take.rs
@@ -1,4 +1,4 @@
-#![deny(warnings, rust_2018_idioms)]
+#![warn(rust_2018_idioms)]
 
 use bytes::buf::{Buf, BufExt};