Upgrade rust/crates/bytes to 0.5.5

Change-Id: Ide2810cb2888de2899fd55127a81c685a5a037b6
diff --git a/.cargo_vcs_info.json b/.cargo_vcs_info.json
index c9be272..b532ea5 100644
--- a/.cargo_vcs_info.json
+++ b/.cargo_vcs_info.json
@@ -1,5 +1,5 @@
 {
   "git": {
-    "sha1": "fe6e67386451715c5d609c90a41e98ef80f0e1d1"
+    "sha1": "008d3e508e2247dbfbf5a73918e2fe999a4e9158"
   }
 }
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
new file mode 100644
index 0000000..164ec13
--- /dev/null
+++ b/.github/workflows/ci.yml
@@ -0,0 +1,163 @@
+name: CI
+
+on:
+  pull_request:
+    branches:
+      - master
+  push:
+    branches:
+      - master
+
+env:
+  RUSTFLAGS: -Dwarnings
+  RUST_BACKTRACE: 1
+
+defaults:
+  run:
+    shell: bash
+
+jobs:
+  # Check formatting
+  rustfmt:
+    name: rustfmt
+    runs-on: ubuntu-latest
+    steps:
+    - uses: actions/checkout@v2
+    - name: Install Rust
+      run: rustup update stable && rustup default stable
+    - name: Check formatting
+      run: cargo fmt --all -- --check
+
+  # TODO
+  # # Apply clippy lints
+  # clippy:
+  #   name: clippy
+  #   runs-on: ubuntu-latest
+  #   steps:
+  #   - uses: actions/checkout@v2
+  #   - name: Apply clippy lints
+  #     run: cargo clippy --all-features
+
+  # 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.
+  minrust:
+    name: minrust
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v2
+      - name: Install Rust
+        run: rustup update 1.39.0 && rustup default 1.39.0
+      - name: Check
+        run: . ci/test-stable.sh check
+
+  # Stable
+  stable:
+    name: stable
+    strategy:
+      matrix:
+        os:
+          - ubuntu-latest
+          - macos-latest
+          - windows-latest
+    runs-on: ${{ matrix.os }}
+    steps:
+      - uses: actions/checkout@v2
+      - name: Install Rust
+        run: rustup update stable && rustup default stable
+      - name: Test
+        run: . ci/test-stable.sh test
+
+  # Nightly
+  nightly:
+    name: nightly
+    env:
+      # Pin nightly to avoid being impacted by breakage
+      RUST_VERSION: nightly-2019-09-25
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v2
+      - name: Install Rust
+        run: rustup update $RUST_VERSION && rustup default $RUST_VERSION
+      - name: Test
+        run: . ci/test-stable.sh test
+
+  # Run tests on some extra platforms
+  cross:
+    name: cross
+    strategy:
+      matrix:
+        target:
+          - i686-unknown-linux-gnu
+          - armv7-unknown-linux-gnueabihf
+          - powerpc-unknown-linux-gnu
+          - powerpc64-unknown-linux-gnu
+          - wasm32-unknown-unknown
+    runs-on: ubuntu-16.04
+    steps:
+      - uses: actions/checkout@v2
+      - name: Install Rust
+        run: rustup update stable && rustup default stable
+      - name: cross build --target ${{ matrix.target }}
+        run: |
+          cargo install cross
+          cross build --target ${{ matrix.target }}
+        if: matrix.target != 'wasm32-unknown-unknown'
+      # WASM support
+      - name: cargo build --target ${{ matrix.target }}
+        run: |
+          rustup target add ${{ matrix.target }}
+          cargo build --target ${{ matrix.target }}
+        if: matrix.target == 'wasm32-unknown-unknown'
+
+  # Sanitizers
+  tsan:
+    name: tsan
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v2
+      - name: Install Rust
+        run: rustup update nightly && rustup default nightly
+      - name: TSAN / MSAN
+        run: . ci/tsan.sh
+
+  # Loom
+  loom:
+    name: loom
+    env:
+      # Pin nightly to avoid being impacted by breakage
+      RUST_VERSION: nightly-2020-05-19
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v2
+      - name: Install Rust
+        run: rustup update $RUST_VERSION && rustup default $RUST_VERSION
+      - name: Loom tests
+        run: RUSTFLAGS="--cfg loom -Dwarnings" cargo test --lib
+
+  publish_docs:
+    name: Publish Documentation
+    needs:
+      - rustfmt
+      # - clippy
+      - stable
+      - nightly
+      - minrust
+      - cross
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v2
+      - name: Install Rust
+        run: rustup update stable && rustup default stable
+      - name: Build documentation
+        run: cargo doc --no-deps --all-features
+      - name: Publish documentation
+        run: |
+          cd target/doc
+          git init
+          git add .
+          git -c user.name='ci' -c user.email='ci' commit -m 'Deploy Bytes API documentation'
+          git push -f -q https://git:${{ secrets.github_token }}@github.com/${{ github.repository }} HEAD:gh-pages
+        if: github.event_name == 'push' && github.event.ref == 'refs/heads/master' && github.repository == 'tokio-rs/bytes'
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 21a51ab..5e6a032 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,12 @@
+# 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
diff --git a/Cargo.toml b/Cargo.toml
index 6a4393f..0f7775a 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -13,7 +13,7 @@
 [package]
 edition = "2018"
 name = "bytes"
-version = "0.5.4"
+version = "0.5.5"
 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,13 +23,15 @@
 license = "MIT"
 repository = "https://github.com/tokio-rs/bytes"
 [dependencies.serde]
-version = "1.0"
+version = "1.0.60"
+features = ["alloc"]
 optional = true
+default-features = false
 [dev-dependencies.serde_test]
 version = "1.0"
 
 [features]
 default = ["std"]
 std = []
-[target."cfg(not(windows))".dev-dependencies.loom]
-version = "0.2.13"
+[target."cfg(loom)".dependencies.loom]
+version = "0.3"
diff --git a/Cargo.toml.orig b/Cargo.toml.orig
index 257e788..69b7361 100644
--- a/Cargo.toml.orig
+++ b/Cargo.toml.orig
@@ -6,7 +6,7 @@
 # - Update CHANGELOG.md.
 # - Update doc URL.
 # - Create "v0.5.x" git tag.
-version = "0.5.4"
+version = "0.5.5"
 license = "MIT"
 authors = [
     "Carl Lerche <me@carllerche.com>",
@@ -25,12 +25,10 @@
 std = []
 
 [dependencies]
-serde = { version = "1.0", optional = true }
+serde = { version = "1.0.60", optional = true, default-features = false, features = ["alloc"] }
 
 [dev-dependencies]
 serde_test = "1.0"
 
-# loom is currently not compiling on windows.
-# See: https://github.com/Xudong-Huang/generator-rs/issues/19
-[target.'cfg(not(windows))'.dev-dependencies]
-loom = "0.2.13"
+[target.'cfg(loom)'.dependencies]
+loom = "0.3"
diff --git a/METADATA b/METADATA
index e6f674c..2dd2690 100644
--- a/METADATA
+++ b/METADATA
@@ -9,11 +9,11 @@
     type: GIT
     value: "https://github.com/tokio-rs/bytes"
   }
-  version: "0.5.4"
+  version: "0.5.5"
   license_type: NOTICE
   last_upgrade_date {
     year: 2020
-    month: 6
-    day: 3
+    month: 7
+    day: 10
   }
 }
diff --git a/README.md b/README.md
index afc2ed2..73c43ab 100644
--- a/README.md
+++ b/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 @@
 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/azure-pipelines.yml b/azure-pipelines.yml
deleted file mode 100644
index 18b5974..0000000
--- a/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/benches/buf.rs b/benches/buf.rs
index 0c9a1d9..8f14aec 100644
--- a/benches/buf.rs
+++ b/benches/buf.rs
@@ -3,8 +3,8 @@
 
 extern crate test;
 
-use test::Bencher;
 use bytes::Buf;
+use test::Bencher;
 
 /// Dummy Buf implementation
 struct TestBuf {
diff --git a/benches/bytes.rs b/benches/bytes.rs
index 9c36e60..1741ba0 100644
--- a/benches/bytes.rs
+++ b/benches/bytes.rs
@@ -3,8 +3,8 @@
 
 extern crate test;
 
-use test::Bencher;
 use bytes::Bytes;
+use test::Bencher;
 
 #[bench]
 fn deref_unique(b: &mut Bencher) {
@@ -42,7 +42,8 @@
 
 #[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/benches/bytes_mut.rs b/benches/bytes_mut.rs
index ded1d14..8e0226c 100644
--- a/benches/bytes_mut.rs
+++ b/benches/bytes_mut.rs
@@ -3,8 +3,8 @@
 
 extern crate test;
 
-use test::Bencher;
 use bytes::{BufMut, BytesMut};
+use test::Bencher;
 
 #[bench]
 fn alloc_small(b: &mut Bencher) {
@@ -29,7 +29,6 @@
     })
 }
 
-
 #[bench]
 fn deref_unique(b: &mut Bencher) {
     let mut buf = BytesMut::with_capacity(4096);
@@ -92,7 +91,9 @@
 
 #[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 @@
     b.iter(|| {
         let _ = write!(buf, "{}", s);
         test::black_box(&buf);
-        unsafe { buf.set_len(0); }
+        unsafe {
+            buf.set_len(0);
+        }
     })
 }
 
@@ -152,7 +155,9 @@
             buf.extend(&data);
         }
         test::black_box(&buf);
-        unsafe { buf.set_len(0); }
+        unsafe {
+            buf.set_len(0);
+        }
     });
 }
 
@@ -169,7 +174,9 @@
             buf.put_slice(&data);
         }
         test::black_box(&buf);
-        unsafe { buf.set_len(0); }
+        unsafe {
+            buf.set_len(0);
+        }
     });
 }
 
@@ -184,7 +191,9 @@
             buf.put_u8(b'x');
         }
         test::black_box(&buf);
-        unsafe { buf.set_len(0); }
+        unsafe {
+            buf.set_len(0);
+        }
     });
 }
 
@@ -199,7 +208,9 @@
             buf.put_slice(&data);
         }
         test::black_box(&buf);
-        unsafe { buf.set_len(0); }
+        unsafe {
+            buf.set_len(0);
+        }
     });
 }
 
@@ -214,7 +225,9 @@
             buf.put_u8(b'x');
         }
         test::black_box(&buf);
-        unsafe { buf.set_len(0); }
+        unsafe {
+            buf.set_len(0);
+        }
     });
 }
 
@@ -229,7 +242,9 @@
             buf.extend_from_slice(&data);
         }
         test::black_box(&buf);
-        unsafe { buf.set_len(0); }
+        unsafe {
+            buf.set_len(0);
+        }
     });
 }
 
@@ -244,6 +259,8 @@
             buf.push(b'x');
         }
         test::black_box(&buf);
-        unsafe { buf.set_len(0); }
+        unsafe {
+            buf.set_len(0);
+        }
     });
 }
diff --git a/ci/azure-cross-compile.yml b/ci/azure-cross-compile.yml
deleted file mode 100644
index be46ca3..0000000
--- a/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/ci/azure-deploy-docs.yml b/ci/azure-deploy-docs.yml
deleted file mode 100644
index 52ac48f..0000000
--- a/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/ci/azure-install-rust.yml b/ci/azure-install-rust.yml
deleted file mode 100644
index 0217659..0000000
--- a/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/ci/azure-loom.yml b/ci/azure-loom.yml
deleted file mode 100644
index 1db9c3a..0000000
--- a/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/ci/azure-test-stable.yml b/ci/azure-test-stable.yml
deleted file mode 100644
index e543eee..0000000
--- a/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/ci/azure-tsan.yml b/ci/azure-tsan.yml
deleted file mode 100644
index 198b187..0000000
--- a/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/ci/test-stable.sh b/ci/test-stable.sh
new file mode 100644
index 0000000..01a32f5
--- /dev/null
+++ b/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/ci/tsan.sh b/ci/tsan.sh
new file mode 100644
index 0000000..7e5b3be
--- /dev/null
+++ b/ci/tsan.sh
@@ -0,0 +1,15 @@
+#!/bin/bash
+
+set -ex
+
+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
diff --git a/src/buf/buf_impl.rs b/src/buf/buf_impl.rs
index 843db71..5cd7c68 100644
--- a/src/buf/buf_impl.rs
+++ b/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 @@
             $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 @@
         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 @@
                 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 @@
 }
 
 macro_rules! deref_forward_buf {
-    () => (
-    fn remaining(&self) -> usize {
-        (**self).remaining()
-    }
+    () => {
+        fn remaining(&self) -> usize {
+            (**self).remaining()
+        }
 
-    fn bytes(&self) -> &[u8] {
-        (**self).bytes()
-    }
+        fn bytes(&self) -> &[u8] {
+            (**self).bytes()
+        }
 
-    #[cfg(feature = "std")]
-    fn bytes_vectored<'b>(&'b self, dst: &mut [IoSlice<'b>]) -> usize {
-        (**self).bytes_vectored(dst)
-    }
+        #[cfg(feature = "std")]
+        fn bytes_vectored<'b>(&'b self, dst: &mut [IoSlice<'b>]) -> usize {
+            (**self).bytes_vectored(dst)
+        }
 
-    fn advance(&mut self, cnt: usize) {
-        (**self).advance(cnt)
-    }
+        fn advance(&mut self, cnt: usize) {
+            (**self).advance(cnt)
+        }
 
-    fn has_remaining(&self) -> bool {
-        (**self).has_remaining()
-    }
+        fn has_remaining(&self) -> bool {
+            (**self).has_remaining()
+        }
 
-    fn copy_to_slice(&mut self, dst: &mut [u8]) {
-        (**self).copy_to_slice(dst)
-    }
+        fn copy_to_slice(&mut self, dst: &mut [u8]) {
+            (**self).copy_to_slice(dst)
+        }
 
-    fn get_u8(&mut self) -> u8 {
-        (**self).get_u8()
-    }
+        fn get_u8(&mut self) -> u8 {
+            (**self).get_u8()
+        }
 
-    fn get_i8(&mut self) -> i8 {
-        (**self).get_i8()
-    }
+        fn get_i8(&mut self) -> i8 {
+            (**self).get_i8()
+        }
 
-    fn get_u16(&mut self) -> u16 {
-        (**self).get_u16()
-    }
+        fn get_u16(&mut self) -> u16 {
+            (**self).get_u16()
+        }
 
-    fn get_u16_le(&mut self) -> u16 {
-        (**self).get_u16_le()
-    }
+        fn get_u16_le(&mut self) -> u16 {
+            (**self).get_u16_le()
+        }
 
-    fn get_i16(&mut self) -> i16 {
-        (**self).get_i16()
-    }
+        fn get_i16(&mut self) -> i16 {
+            (**self).get_i16()
+        }
 
-    fn get_i16_le(&mut self) -> i16 {
-        (**self).get_i16_le()
-    }
+        fn get_i16_le(&mut self) -> i16 {
+            (**self).get_i16_le()
+        }
 
-    fn get_u32(&mut self) -> u32 {
-        (**self).get_u32()
-    }
+        fn get_u32(&mut self) -> u32 {
+            (**self).get_u32()
+        }
 
-    fn get_u32_le(&mut self) -> u32 {
-        (**self).get_u32_le()
-    }
+        fn get_u32_le(&mut self) -> u32 {
+            (**self).get_u32_le()
+        }
 
-    fn get_i32(&mut self) -> i32 {
-        (**self).get_i32()
-    }
+        fn get_i32(&mut self) -> i32 {
+            (**self).get_i32()
+        }
 
-    fn get_i32_le(&mut self) -> i32 {
-        (**self).get_i32_le()
-    }
+        fn get_i32_le(&mut self) -> i32 {
+            (**self).get_i32_le()
+        }
 
-    fn get_u64(&mut self) -> u64 {
-        (**self).get_u64()
-    }
+        fn get_u64(&mut self) -> u64 {
+            (**self).get_u64()
+        }
 
-    fn get_u64_le(&mut self) -> u64 {
-        (**self).get_u64_le()
-    }
+        fn get_u64_le(&mut self) -> u64 {
+            (**self).get_u64_le()
+        }
 
-    fn get_i64(&mut self) -> i64 {
-        (**self).get_i64()
-    }
+        fn get_i64(&mut self) -> i64 {
+            (**self).get_i64()
+        }
 
-    fn get_i64_le(&mut self) -> i64 {
-        (**self).get_i64_le()
-    }
+        fn get_i64_le(&mut self) -> i64 {
+            (**self).get_i64_le()
+        }
 
-    fn get_uint(&mut self, nbytes: usize) -> u64 {
-        (**self).get_uint(nbytes)
-    }
+        fn get_uint(&mut self, nbytes: usize) -> u64 {
+            (**self).get_uint(nbytes)
+        }
 
-    fn get_uint_le(&mut self, nbytes: usize) -> u64 {
-        (**self).get_uint_le(nbytes)
-    }
+        fn get_uint_le(&mut self, nbytes: usize) -> u64 {
+            (**self).get_uint_le(nbytes)
+        }
 
-    fn get_int(&mut self, nbytes: usize) -> i64 {
-        (**self).get_int(nbytes)
-    }
+        fn get_int(&mut self, nbytes: usize) -> i64 {
+            (**self).get_int(nbytes)
+        }
 
-    fn get_int_le(&mut self, nbytes: usize) -> i64 {
-        (**self).get_int_le(nbytes)
-    }
+        fn get_int_le(&mut self, nbytes: usize) -> i64 {
+            (**self).get_int_le(nbytes)
+        }
 
-    fn to_bytes(&mut self) -> crate::Bytes {
-        (**self).to_bytes()
-    }
-
-    )
+        fn to_bytes(&mut self) -> crate::Bytes {
+            (**self).to_bytes()
+        }
+    };
 }
 
 impl<T: Buf + ?Sized> Buf for &mut T {
@@ -950,7 +949,8 @@
     }
 
     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 @@
 
     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/src/buf/buf_mut.rs b/src/buf/buf_mut.rs
index f5ed2a7..628b240 100644
--- a/src/buf/buf_mut.rs
+++ b/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 @@
     /// # 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 @@
                 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 @@
     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 @@
                 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 @@
 }
 
 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 @@
     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 @@
         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/src/buf/ext/chain.rs b/src/buf/ext/chain.rs
index a1ec597..e62e2f1 100644
--- a/src/buf/ext/chain.rs
+++ b/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 @@
 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> 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> 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/src/buf/ext/limit.rs b/src/buf/ext/limit.rs
index f86e011..a36ecee 100644
--- a/src/buf/ext/limit.rs
+++ b/src/buf/ext/limit.rs
@@ -11,10 +11,7 @@
 }
 
 pub(super) fn new<T>(inner: T, limit: usize) -> Limit<T> {
-    Limit {
-        inner,
-        limit,
-    }
+    Limit { inner, limit }
 }
 
 impl<T> Limit<T> {
diff --git a/src/buf/ext/mod.rs b/src/buf/ext/mod.rs
index 7b0bdab..4a29267 100644
--- a/src/buf/ext/mod.rs
+++ b/src/buf/ext/mod.rs
@@ -10,9 +10,9 @@
 #[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 @@
     /// # 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 @@
     /// 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 @@
     /// 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 @@
     /// # 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 @@
     /// 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 @@
     /// 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 @@
     /// # Examples
     ///
     /// ```
-    /// use bytes::{BufMut, buf::BufMutExt};
+    /// use bytes::buf::BufMutExt;
     /// use std::io::Write;
     ///
     /// let mut buf = vec![].writer();
@@ -142,7 +148,10 @@
     /// 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 @@
     /// 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/src/buf/ext/reader.rs b/src/buf/ext/reader.rs
index e38103b..dde3548 100644
--- a/src/buf/ext/reader.rs
+++ b/src/buf/ext/reader.rs
@@ -1,4 +1,4 @@
-use crate::{Buf};
+use crate::Buf;
 
 use std::{cmp, io};
 
@@ -26,7 +26,7 @@
     /// ```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/src/buf/ext/take.rs b/src/buf/ext/take.rs
index 6fc4ffc..1d84868 100644
--- a/src/buf/ext/take.rs
+++ b/src/buf/ext/take.rs
@@ -5,7 +5,7 @@
 /// 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 fn new<T>(inner: T, limit: usize) -> Take<T> {
-    Take {
-        inner,
-        limit,
-    }
+    Take { inner, limit }
 }
 
 impl<T> Take<T> {
@@ -25,7 +22,7 @@
     /// # 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 @@
     /// ```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 @@
     /// # 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/src/buf/ext/writer.rs b/src/buf/ext/writer.rs
index 1418418..a14197c 100644
--- a/src/buf/ext/writer.rs
+++ b/src/buf/ext/writer.rs
@@ -26,7 +26,7 @@
     /// ```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/src/buf/iter.rs b/src/buf/iter.rs
index 1af421a..0f9bdc0 100644
--- a/src/buf/iter.rs
+++ b/src/buf/iter.rs
@@ -9,7 +9,7 @@
 /// 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 @@
     /// # Examples
     ///
     /// ```
-    /// use bytes::{Buf, Bytes};
+    /// use bytes::Bytes;
     /// use bytes::buf::IntoIter;
     ///
     /// let buf = Bytes::from_static(b"abc");
@@ -47,6 +47,7 @@
     pub fn new(inner: T) -> IntoIter<T> {
         IntoIter { inner }
     }
+
     /// Consumes this `IntoIter`, returning the underlying value.
     ///
     /// # Examples
@@ -109,7 +110,6 @@
     }
 }
 
-
 impl<T: Buf> Iterator for IntoIter<T> {
     type Item = u8;
 
@@ -130,4 +130,4 @@
     }
 }
 
-impl<T: Buf> ExactSizeIterator for IntoIter<T> { }
+impl<T: Buf> ExactSizeIterator for IntoIter<T> {}
diff --git a/src/buf/mod.rs b/src/buf/mod.rs
index d4538f2..1d7292c 100644
--- a/src/buf/mod.rs
+++ b/src/buf/mod.rs
@@ -24,8 +24,7 @@
 
 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/src/bytes.rs b/src/bytes.rs
index 380b1c6..08bc9b3 100644
--- a/src/bytes.rs
+++ b/src/bytes.rs
@@ -1,12 +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;
+#[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.
 ///
@@ -173,7 +175,6 @@
         self.len == 0
     }
 
-
     ///Creates `Bytes` instance from slice, by copying it.
     pub fn copy_from_slice(data: &[u8]) -> Self {
         data.to_vec().into()
@@ -235,7 +236,6 @@
             return Bytes::new();
         }
 
-
         let mut ret = self.clone();
 
         ret.len = end - begin;
@@ -391,7 +391,6 @@
             return Bytes::new();
         }
 
-
         let mut ret = self.clone();
 
         unsafe { self.inc_start(at) };
@@ -426,8 +425,9 @@
             // 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 {
+            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;
@@ -452,7 +452,12 @@
     }
 
     #[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,
@@ -465,9 +470,7 @@
 
     #[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]
@@ -486,18 +489,14 @@
 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)
-        }
+        unsafe { (self.vtable.clone)(&self.data, self.ptr, self.len) }
     }
 }
 
@@ -548,7 +547,10 @@
 }
 
 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);
     }
 }
@@ -726,7 +728,8 @@
 }
 
 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
@@ -734,7 +737,8 @@
 }
 
 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)
@@ -854,16 +858,18 @@
 }
 
 unsafe fn promotable_even_drop(data: &mut AtomicPtr<()>, ptr: *const u8, len: usize) {
-    let shared = *data.get_mut();
-    let kind = shared as usize & KIND_MASK;
+    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));
-    }
+        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 {
@@ -879,16 +885,18 @@
 }
 
 unsafe fn promotable_odd_drop(data: &mut AtomicPtr<()>, ptr: *const u8, len: usize) {
-    let shared = *data.get_mut();
-    let kind = shared as usize & KIND_MASK;
+    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);
+        if kind == KIND_ARC {
+            release_shared(shared as *mut Shared);
+        } else {
+            debug_assert_eq!(kind, KIND_VEC);
 
-        drop(rebuild_boxed_slice(shared as *mut u8, ptr, len));
-    }
+            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]> {
@@ -925,8 +933,9 @@
 }
 
 unsafe fn shared_drop(data: &mut AtomicPtr<()>, _ptr: *const u8, _len: usize) {
-    let shared = *data.get_mut();
-    release_shared(shared as *mut Shared);
+    data.with_mut(|shared| {
+        release_shared(*shared as *mut Shared);
+    });
 }
 
 unsafe fn shallow_clone_arc(shared: *mut Shared, ptr: *const u8, len: usize) -> Bytes {
@@ -945,7 +954,13 @@
 }
 
 #[cold]
-unsafe fn shallow_clone_vec(atom: &AtomicPtr<()>, ptr: *const (), buf: *mut u8, 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.
@@ -1062,7 +1077,7 @@
 // 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/src/bytes_mut.rs b/src/bytes_mut.rs
index dc4e4b1..4d0585e 100644
--- a/src/bytes_mut.rs
+++ b/src/bytes_mut.rs
@@ -1,15 +1,22 @@
-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::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.
 ///
@@ -107,8 +114,7 @@
     /// 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.
@@ -233,7 +239,9 @@
                 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);
@@ -242,9 +250,7 @@
             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) }
         }
     }
 
@@ -386,7 +392,9 @@
     /// [`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);
+            }
         }
     }
 
@@ -567,7 +575,8 @@
                     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
@@ -583,7 +592,6 @@
         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.
         //
@@ -627,9 +635,7 @@
                 // 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);
             }
@@ -678,14 +684,12 @@
             // 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);
+        }
     }
 
     /// Absorbs a `BytesMut` that was previously split off.
@@ -750,16 +754,12 @@
 
     #[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) {
@@ -788,7 +788,7 @@
                 // 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);
             }
         }
 
@@ -820,10 +820,10 @@
         }
 
         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;
@@ -884,7 +884,7 @@
             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)
         }
     }
@@ -952,7 +952,9 @@
             cnt,
             self.remaining(),
         );
-        unsafe { self.set_start(cnt); }
+        unsafe {
+            self.set_start(cnt);
+        }
     }
 
     fn to_bytes(&mut self) -> crate::Bytes {
@@ -969,7 +971,12 @@
     #[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;
     }
 
@@ -984,7 +991,10 @@
     // 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();
@@ -1063,8 +1073,7 @@
     }
 }
 
-impl Eq for BytesMut {
-}
+impl Eq for BytesMut {}
 
 impl Default for BytesMut {
     #[inline]
@@ -1074,7 +1083,10 @@
 }
 
 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);
     }
@@ -1134,7 +1146,10 @@
 }
 
 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();
@@ -1151,7 +1166,10 @@
 }
 
 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))
     }
 }
@@ -1229,7 +1247,10 @@
 
 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 {
@@ -1397,7 +1418,8 @@
 }
 
 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
@@ -1405,7 +1427,8 @@
 }
 
 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)
@@ -1480,8 +1503,9 @@
 }
 
 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
@@ -1519,11 +1543,11 @@
 // 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/src/fmt/debug.rs b/src/fmt/debug.rs
index f6a08b8..a854551 100644
--- a/src/fmt/debug.rs
+++ b/src/fmt/debug.rs
@@ -1,7 +1,7 @@
 use core::fmt::{Debug, Formatter, Result};
 
-use crate::{Bytes, BytesMut};
 use super::BytesRef;
+use crate::{Bytes, BytesMut};
 
 /// Alternative implementation of `std::fmt::Debug` for byte slice.
 ///
diff --git a/src/fmt/hex.rs b/src/fmt/hex.rs
index 09170ae..97a749a 100644
--- a/src/fmt/hex.rs
+++ b/src/fmt/hex.rs
@@ -1,7 +1,7 @@
 use core::fmt::{Formatter, LowerHex, Result, UpperHex};
 
-use crate::{Bytes, BytesMut};
 use super::BytesRef;
+use crate::{Bytes, BytesMut};
 
 impl LowerHex for BytesRef<'_> {
     fn fmt(&self, f: &mut Formatter<'_>) -> Result {
diff --git a/src/lib.rs b/src/lib.rs
index a61e347..accbf71 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -1,5 +1,14 @@
-#![deny(warnings, missing_docs, missing_debug_implementations, rust_2018_idioms)]
-#![doc(html_root_url = "https://docs.rs/bytes/0.5.4")]
+#![deny(
+    warnings,
+    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.5")]
 #![no_std]
 
 //! Provides abstractions for working with bytes.
@@ -72,24 +81,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 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/src/loom.rs b/src/loom.rs
index 80947ac..1cae881 100644
--- a/src/loom.rs
+++ b/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/src/serde.rs b/src/serde.rs
index 11020ae..0a5bd14 100644
--- a/src/serde.rs
+++ b/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 @@
 
             #[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 @@
 
             #[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 @@
         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/tests/test_buf.rs b/tests/test_buf.rs
index 12b75a4..26b95ae 100644
--- a/tests/test_buf.rs
+++ b/tests/test_buf.rs
@@ -1,6 +1,7 @@
 #![deny(warnings, rust_2018_idioms)]
 
 use bytes::Buf;
+#[cfg(feature = "std")]
 use std::io::IoSlice;
 
 #[test]
@@ -42,6 +43,7 @@
     buf.get_u16();
 }
 
+#[cfg(feature = "std")]
 #[test]
 fn test_bufs_vec() {
     let buf = &b"hello world"[..];
diff --git a/tests/test_buf_mut.rs b/tests/test_buf_mut.rs
index f002f7d..c70e209 100644
--- a/tests/test_buf_mut.rs
+++ b/tests/test_buf_mut.rs
@@ -1,8 +1,10 @@
 #![deny(warnings, 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 @@
 }
 
 #[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 @@
     assert!(buf != buf2);
 }
 
+#[cfg(feature = "std")]
 #[test]
 fn test_bufs_vec_mut() {
     let b1: &mut [u8] = &mut [];
diff --git a/tests/test_bytes.rs b/tests/test_bytes.rs
index 40fcae4..106fa6f 100644
--- a/tests/test_bytes.rs
+++ b/tests/test_bytes.rs
@@ -1,6 +1,6 @@
 #![deny(warnings, rust_2018_idioms)]
 
-use bytes::{Bytes, BytesMut, Buf, BufMut};
+use bytes::{Buf, BufMut, Bytes, BytesMut};
 
 use std::usize;
 
@@ -44,7 +44,6 @@
         mem::size_of::<Option<BytesMut>>(),
         "BytesMut should be same size as Option<BytesMut>",
     );
-
 }
 
 #[test]
@@ -87,13 +86,11 @@
     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 @@
 
     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]
@@ -343,6 +342,72 @@
 }
 
 #[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 @@
     test_slice_ref(&bytes, 9, 9, b"");
 }
 
-
 #[test]
 fn slice_ref_empty() {
     let bytes = Bytes::from(&b""[..]);
diff --git a/tests/test_bytes_vec_alloc.rs b/tests/test_bytes_vec_alloc.rs
index dc007cf..418a9cd 100644
--- a/tests/test_bytes_vec_alloc.rs
+++ b/tests/test_bytes_vec_alloc.rs
@@ -39,7 +39,11 @@
             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());
+                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) {
diff --git a/tests/test_chain.rs b/tests/test_chain.rs
index 332571d..82de7fc 100644
--- a/tests/test_chain.rs
+++ b/tests/test_chain.rs
@@ -1,7 +1,8 @@
 #![deny(warnings, 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 @@
     assert_eq!(res, &b"helloworld"[..]);
 }
 
+#[cfg(feature = "std")]
 #[test]
 fn vectored_read() {
     let a = Bytes::from(&b"hello"[..]);
diff --git a/tests/test_iter.rs b/tests/test_iter.rs
index 13b86cd..2302a69 100644
--- a/tests/test_iter.rs
+++ b/tests/test_iter.rs
@@ -11,7 +11,6 @@
     assert_eq!(iter.len(), 11);
 }
 
-
 #[test]
 fn empty_iter_len() {
     let buf = Bytes::from_static(b"");
diff --git a/tests/test_reader.rs b/tests/test_reader.rs
index 9c5972a..b5da2c9 100644
--- a/tests/test_reader.rs
+++ b/tests/test_reader.rs
@@ -1,8 +1,9 @@
 #![deny(warnings, 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/tests/test_serde.rs b/tests/test_serde.rs
index 18b1356..36b87f2 100644
--- a/tests/test_serde.rs
+++ b/tests/test_serde.rs
@@ -1,7 +1,7 @@
 #![cfg(feature = "serde")]
 #![deny(warnings, rust_2018_idioms)]
 
-use serde_test::{Token, assert_tokens};
+use serde_test::{assert_tokens, Token};
 
 #[test]
 fn test_ser_de_empty() {