Upgrade rust/crates/criterion to 0.3.5 am: 4897304d0e am: 9a65a02c6f

Original change: https://android-review.googlesource.com/c/platform/external/rust/crates/criterion/+/1790948

Change-Id: I9a0ad73f14d3dfb2fef34e8a4ee1b2c6860f7e70
diff --git a/.cargo_vcs_info.json b/.cargo_vcs_info.json
index b30c393..40e1b5b 100644
--- a/.cargo_vcs_info.json
+++ b/.cargo_vcs_info.json
@@ -1,5 +1,5 @@
 {
   "git": {
-    "sha1": "1bf6f4badbddd98fc7b667d310605c5a204bc8e4"
+    "sha1": "4e773a3b8523a73e7105e11f0b2d4b545827712e"
   }
 }
diff --git a/.github/workflows/audit.yml b/.github/workflows/audit.yml
new file mode 100755
index 0000000..118008c
--- /dev/null
+++ b/.github/workflows/audit.yml
@@ -0,0 +1,14 @@
+name: Security audit
+on:
+  push:
+    paths: 
+      - '**/Cargo.toml'
+      - '**/Cargo.lock'
+jobs:
+  security_audit:
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v1
+      - uses: actions-rs/audit-check@v1
+        with:
+          token: ${{ secrets.GITHUB_TOKEN }}
diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml
new file mode 100755
index 0000000..2c39904
--- /dev/null
+++ b/.github/workflows/ci.yaml
@@ -0,0 +1,54 @@
+on:
+  push:
+    branches:
+      - master
+  pull_request:
+    branches:
+      - master
+
+name: tests
+
+jobs:
+  ci:
+    runs-on: ubuntu-latest
+    strategy:
+      matrix:
+        rust:
+          - stable
+          - beta
+          - nightly
+          - 1.46.0  # MSRV
+
+    steps:
+      - uses: actions/checkout@v2
+
+      - uses: actions-rs/toolchain@v1
+        with:
+          profile: minimal
+          toolchain: ${{ matrix.rust }}
+          override: true
+          components: rustfmt, clippy
+
+      - uses: Swatinem/rust-cache@v1
+
+      - uses: actions-rs/cargo@v1
+        with:
+          command: build
+          args: --features stable
+
+      - uses: actions-rs/cargo@v1
+        with:
+          command: test
+          args: --features stable
+
+      - uses: actions-rs/cargo@v1
+        if: ${{ matrix.rust == 'stable' }}
+        with:
+          command: fmt
+          args: --all -- --check
+
+      - uses: actions-rs/cargo@v1
+        if: ${{ matrix.rust != '1.40.0' }} # 1.40 has horrible lints.
+        with:
+          command: clippy
+          args: -- -D warnings
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100755
index d67d8fa..0000000
--- a/.travis.yml
+++ /dev/null
@@ -1,87 +0,0 @@
-sudo: false
-
-language: rust
-
-cache: cargo
-
-rust:
-  - stable
-
-os:
-  - linux
-  - osx
-
-matrix:
-  include:
-    - os: linux
-      env: GNUPLOT=yes
-      addons:
-        apt:
-          packages:
-            - gnuplot
-    - os: linux
-      env: CLIPPY=yes
-      rust: stable
-    - os: linux
-      env: RUSTFMT=yes
-      rust: stable
-    - os: linux
-      env: DOCS=yes
-    - os: linux
-      env: GNUPLOT=yes
-      rust: 1.39.0
-      addons:
-        apt:
-          packages:
-            - gnuplot
-    - os: linux
-      env: GNUPLOT=no
-      rust: nightly
-    - os: linux
-      env: GNUPLOT=yes
-      rust: nightly
-      addons:
-        apt:
-          packages:
-            - gnuplot
-    - os: osx
-      env: GNUPLOT=yes
-    - os: osx
-      env: GNUPLOT=no
-      rust: nightly
-    - os: osx
-      env: GNUPLOT=yes
-      rust: nightly
-    - os: linux
-      env: MINIMAL_VERSIONS=yes
-      rust: nightly
-
-before_script:
-  - if [ "$DOCS" = "yes" ]; then
-      pip install 'travis-cargo<0.2' --user;
-      export PATH=$HOME/.local/bin:$PATH;
-    fi
-
-before_cache:
-- find ./target/debug -maxdepth 1 -type f -delete
-- rm -rf ./target/debug/deps/criterion*
-- rm -rf ./target/debug/deps/bench*
-- rm -rf ./target/debug/.fingerprint/criterion*
-- rm -rf ./target/debug/.fingerprint/bench*
-- rm -f  ./target/.rustc_info.json
-- rm -rf ./target/criterion
-- rm -rf ~/.cargo/registry/index/
-
-install:
-  - sh ci/install.sh
-
-script:
-  - sh ci/script.sh
-
-env:
-  global:
-    - secure: "f/HaMzQu7d6ochSjE5lUjJbXYWlhbzslyTuWq+Lub/r2TTL4hVlT9koC4RT7W73V3WDrwYIqEGmwvscVffnijZRebl/PV+6WlOlYJEdAgKxGROpFGDIJGRGAc/f3s6OcJ+Hr8rmRF70fYEl45hs6J53X8s+CVRuty+r/UdilRpM="
-
-notifications:
-  email:
-    on_success: never
diff --git a/Android.bp b/Android.bp
index 5338905..2d9c741 100644
--- a/Android.bp
+++ b/Android.bp
@@ -73,53 +73,50 @@
 //   atty-0.2.14
 //   autocfg-1.0.1
 //   bitflags-1.2.1 "default"
-//   bstr-0.2.15 "default,lazy_static,regex-automata,serde,serde1,serde1-nostd,std,unicode"
-//   byteorder-1.4.3
-//   cast-0.2.3 "default,std"
+//   bstr-0.2.16 "default,lazy_static,regex-automata,serde,serde1,serde1-nostd,std,unicode"
+//   cast-0.2.7 "default,std"
 //   cfg-if-1.0.0
 //   clap-2.33.3
-//   criterion-plot-0.4.3
-//   crossbeam-channel-0.5.0 "crossbeam-utils,default,std"
-//   crossbeam-deque-0.8.0 "crossbeam-epoch,crossbeam-utils,default,std"
-//   crossbeam-epoch-0.9.3 "alloc,lazy_static,std"
-//   crossbeam-utils-0.8.3 "default,lazy_static,std"
+//   criterion-plot-0.4.4
+//   crossbeam-channel-0.5.1 "crossbeam-utils,default,std"
+//   crossbeam-deque-0.8.1 "crossbeam-epoch,crossbeam-utils,default,std"
+//   crossbeam-epoch-0.9.5 "alloc,lazy_static,std"
+//   crossbeam-utils-0.8.5 "default,lazy_static,std"
 //   csv-1.1.6
 //   csv-core-0.1.10 "default"
 //   either-1.6.1
 //   half-1.7.1
-//   itertools-0.10.0 "default,use_alloc,use_std"
-//   itertools-0.9.0 "default,use_std"
+//   itertools-0.10.1 "default,use_alloc,use_std"
 //   itoa-0.4.7 "default,std"
 //   lazy_static-1.4.0
-//   libc-0.2.92 "default,std"
-//   memchr-2.3.4 "default,std,use_std"
-//   memoffset-0.6.3 "default"
+//   libc-0.2.98 "default,std"
+//   memchr-2.4.0 "default,std"
+//   memoffset-0.6.4 "default"
 //   num-traits-0.2.14 "default,std"
 //   num_cpus-1.13.0
 //   oorandom-11.1.3
-//   plotters-0.3.0 "area_series,line_series,plotters-svg,svg_backend"
-//   plotters-backend-0.3.0
-//   plotters-svg-0.3.0
-//   proc-macro2-1.0.26 "default,proc-macro"
+//   plotters-0.3.1 "area_series,line_series,plotters-svg,svg_backend"
+//   plotters-backend-0.3.2
+//   plotters-svg-0.3.1
+//   proc-macro2-1.0.28 "default,proc-macro"
 //   quote-1.0.9 "default,proc-macro"
-//   rayon-1.5.0
-//   rayon-core-1.9.0
-//   regex-1.4.5 "std"
-//   regex-automata-0.1.9
-//   regex-syntax-0.6.23
-//   rustc_version-0.2.3
+//   rayon-1.5.1
+//   rayon-core-1.9.1
+//   regex-1.5.4 "std"
+//   regex-automata-0.1.10
+//   regex-syntax-0.6.25
+//   rustc_version-0.4.0
 //   ryu-1.0.5
 //   same-file-1.0.6
 //   scopeguard-1.1.0
-//   semver-0.9.0 "default"
-//   semver-parser-0.7.0
-//   serde-1.0.125 "default,std"
+//   semver-1.0.4 "default,std"
+//   serde-1.0.127 "default,std"
 //   serde_cbor-0.11.1 "default,std"
-//   serde_derive-1.0.125 "default"
-//   serde_json-1.0.64 "default,std"
-//   syn-1.0.68 "clone-impls,default,derive,full,parsing,printing,proc-macro,quote,visit"
+//   serde_derive-1.0.127 "default"
+//   serde_json-1.0.66 "default,std"
+//   syn-1.0.74 "clone-impls,default,derive,full,parsing,printing,proc-macro,quote,visit"
 //   textwrap-0.11.0
 //   tinytemplate-1.2.1
 //   unicode-width-0.1.8 "default"
-//   unicode-xid-0.2.1 "default"
+//   unicode-xid-0.2.2 "default"
 //   walkdir-2.3.2
diff --git a/CHANGELOG.md b/CHANGELOG.md
index a747ed8..d583c31 100755
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,7 +6,16 @@
 
 ## [Unreleased]
 
-## [0.3.4]
+## [0.3.5] - 2021-07-26
+### Fixed
+- Corrected `Criterion.toml` in the book.
+- Corrected configuration typo in the book.
+
+### Changed
+- Bump plotters dependency to always include a bug-fix.
+- MSRV bumped to 1.46.
+
+## [0.3.4] - 2021-01-24
 ### Added
 - Added support for benchmarking async functions
 - Added `with_output_color` for enabling or disabling CLI output coloring programmatically.
diff --git a/Cargo.toml b/Cargo.toml
index 2c8ce7a..26e1e10 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -13,7 +13,7 @@
 [package]
 edition = "2018"
 name = "criterion"
-version = "0.3.4"
+version = "0.3.5"
 authors = ["Jorge Aparicio <japaricious@gmail.com>", "Brook Heisler <brookheisler@gmail.com>"]
 exclude = ["book/*"]
 description = "Statistics-driven micro-benchmarking library"
@@ -47,7 +47,7 @@
 default-features = false
 
 [dependencies.criterion-plot]
-version = "0.4.3"
+version = "0.4.4"
 
 [dependencies.csv]
 version = "1.1"
@@ -71,7 +71,7 @@
 version = "11.1"
 
 [dependencies.plotters]
-version = "^0.3.0"
+version = "^0.3.1"
 features = ["svg_backend", "area_series", "line_series"]
 default-features = false
 
@@ -112,7 +112,7 @@
 [dependencies.walkdir]
 version = "2.3"
 [dev-dependencies.approx]
-version = "0.4"
+version = "0.5.0"
 
 [dev-dependencies.futures]
 version = "0.3"
@@ -120,14 +120,14 @@
 default_features = false
 
 [dev-dependencies.quickcheck]
-version = "0.9"
+version = "1.0"
 default-features = false
 
 [dev-dependencies.rand]
 version = "0.8"
 
 [dev-dependencies.tempfile]
-version = "3.1"
+version = "3.2.0"
 
 [features]
 async = ["futures"]
@@ -140,12 +140,6 @@
 default = ["cargo_bench_support"]
 html_reports = []
 real_blackbox = []
-[badges.appveyor]
-id = "4255ads9ctpupcl2"
-repository = "bheisler/criterion.rs"
-
+stable = ["async_futures", "async_smol", "async_tokio", "async_std"]
 [badges.maintenance]
 status = "passively-maintained"
-
-[badges.travis-ci]
-repository = "bheisler/criterion.rs"
diff --git a/Cargo.toml.orig b/Cargo.toml.orig
index 86a8f92..c0e33f4 100755
--- a/Cargo.toml.orig
+++ b/Cargo.toml.orig
@@ -1,59 +1,61 @@
 [package]
-authors = ["Jorge Aparicio <japaricious@gmail.com>", "Brook Heisler <brookheisler@gmail.com>"]
-name = "criterion"
-version = "0.3.4"
+authors = [
+  "Jorge Aparicio <japaricious@gmail.com>",
+  "Brook Heisler <brookheisler@gmail.com>",
+]
+name    = "criterion"
+version = "0.3.5"
 edition = "2018"
 
 description = "Statistics-driven micro-benchmarking library"
-homepage = "https://bheisler.github.io/criterion.rs/book/index.html"
-repository = "https://github.com/bheisler/criterion.rs"
-readme = "README.md"
-keywords = ["criterion", "benchmark"]
-categories = ["development-tools::profiling"]
-license = "Apache-2.0/MIT"
-exclude = ["book/*"]
+homepage    = "https://bheisler.github.io/criterion.rs/book/index.html"
+repository  = "https://github.com/bheisler/criterion.rs"
+readme      = "README.md"
+keywords    = ["criterion", "benchmark"]
+categories  = ["development-tools::profiling"]
+license     = "Apache-2.0/MIT"
+exclude     = ["book/*"]
 
 [dependencies]
-lazy_static = "1.4"
-criterion-plot = { path="plot", version="0.4.3" }
-itertools = "0.10"
-serde = "1.0"
-serde_json = "1.0"
-serde_derive = "1.0"
-serde_cbor = "0.11"
-atty = "0.2"
-clap = { version = "2.33", default-features = false }
-csv = "1.1"
-walkdir = "2.3"
-tinytemplate = "1.1"
-cast = "0.2"
-num-traits = { version = "0.2", default-features = false }
-oorandom = "11.1"
-rayon = "1.3"
-regex = { version = "1.3", default-features = false, features = ["std"] }
-futures = { version = "0.3", default_features = false, optional = true }
-smol = { version = "1.2", default-features = false, optional = true }
-tokio = { version = "1.0", default-features = false, features = ["rt"], optional = true }
-async-std = { version = "1.9", optional = true }
+lazy_static    = "1.4"
+criterion-plot = { path = "plot", version = "0.4.4" }
+itertools      = "0.10"
+serde          = "1.0"
+serde_json     = "1.0"
+serde_derive   = "1.0"
+serde_cbor     = "0.11"
+atty           = "0.2"
+clap           = { version = "2.33", default-features = false }
+csv            = "1.1"
+walkdir        = "2.3"
+tinytemplate   = "1.1"
+cast           = "0.2"
+num-traits     = { version = "0.2", default-features = false }
+oorandom       = "11.1"
+rayon          = "1.3"
+regex          = { version = "1.3", default-features = false, features = ["std"] }
+futures        = { version = "0.3", default_features = false, optional = true }
+smol           = { version = "1.2", default-features = false, optional = true }
+tokio          = { version = "1.0", default-features = false, features = ["rt"], optional = true }
+async-std      = { version = "1.9", optional = true }
 
 [dependencies.plotters]
-version = "^0.3.0"
+version          = "^0.3.1"
 default-features = false
-features = ["svg_backend", "area_series", "line_series"] 
+features         = ["svg_backend", "area_series", "line_series"]
 
 [dev-dependencies]
-tempfile = "3.1"
-approx = "0.4"
-quickcheck = { version = "0.9", default-features = false }
-rand = "0.8"
-futures = { version = "0.3", default_features = false, features = ["executor"] }
+tempfile   = "3.2.0"
+approx     = "0.5.0"
+quickcheck = { version = "1.0", default-features = false }
+rand       = "0.8"
+futures    = { version = "0.3", default_features = false, features = ["executor"] }
 
 [badges]
-travis-ci = { repository = "bheisler/criterion.rs" }
-appveyor = { repository = "bheisler/criterion.rs", id = "4255ads9ctpupcl2" }
 maintenance = { status = "passively-maintained" }
 
 [features]
+stable  = ["async_futures", "async_smol", "async_tokio", "async_std"]
 default = ["cargo_bench_support"]
 
 # Enable use of the nightly-only test::black_box function to discourage compiler optimizations.
@@ -65,9 +67,9 @@
 # These features enable built-in support for running async benchmarks on each different async 
 # runtime.
 async_futures = ["futures/executor", "async"]
-async_smol = ["smol", "async"]
-async_tokio = ["tokio", "async"]
-async_std = ["async-std", "async"]
+async_smol    = ["smol", "async"]
+async_tokio   = ["tokio", "async"]
+async_std     = ["async-std", "async"]
 
 # This feature _currently_ does nothing except disable a warning message, but in 0.4.0 it will be
 # required in order to have Criterion.rs generate its own plots (as opposed to using cargo-criterion)
@@ -86,7 +88,7 @@
 exclude = ["cargo-criterion"]
 
 [[bench]]
-name = "bench_main"
+name    = "bench_main"
 harness = false
 
 [lib]
@@ -94,4 +96,4 @@
 
 # Enable all of the async runtimes for the docs.rs output
 [package.metadata.docs.rs]
-features = ["async_futures", "async_smol", "async_std", "async_tokio"]
\ No newline at end of file
+features = ["async_futures", "async_smol", "async_std", "async_tokio"]
diff --git a/METADATA b/METADATA
index 2ca3480..7700018 100644
--- a/METADATA
+++ b/METADATA
@@ -7,13 +7,13 @@
   }
   url {
     type: ARCHIVE
-    value: "https://static.crates.io/crates/criterion/criterion-0.3.4.crate"
+    value: "https://static.crates.io/crates/criterion/criterion-0.3.5.crate"
   }
-  version: "0.3.4"
+  version: "0.3.5"
   license_type: NOTICE
   last_upgrade_date {
     year: 2021
-    month: 4
-    day: 2
+    month: 8
+    day: 9
   }
 }
diff --git a/README.md b/README.md
index bb5bbab..0d12aa9 100755
--- a/README.md
+++ b/README.md
@@ -15,8 +15,8 @@
 </div>
 
 <div align="center">
-	<a href="https://travis-ci.org/bheisler/criterion.rs">
-        <img src="https://travis-ci.org/bheisler/criterion.rs.svg?branch=master" alt="Travis-CI">
+	<a href="https://github.com/bheisler/criterion.rs/actions/workflows/ci.yaml">
+        <img src="https://img.shields.io/github/checks-status/rgeometry/rgeometry/main?label=tests&logo=github" alt="GitHub branch checks state">
     </a>
     |
     <a href="https://ci.appveyor.com/project/bheisler/criterion-rs-vt9fl">
@@ -117,9 +117,9 @@
 ### Compatibility Policy
 
 Criterion.<span></span>rs supports the last three stable minor releases of Rust. At time of
-writing, this means Rust 1.40 or later. Older versions may work, but are not tested or guaranteed.
+writing, this means Rust 1.50 or later. Older versions may work, but are not guaranteed.
 
-Currently, the oldest version of Rust believed to work is 1.39. Future versions of Criterion.<span></span>rs may
+Currently, the oldest version of Rust believed to work is 1.46. Future versions of Criterion.<span></span>rs may
 break support for such old versions, and this will not be considered a breaking change. If you
 require Criterion.<span></span>rs to work on old versions of Rust, you will need to stick to a
 specific patch version of Criterion.<span></span>rs.
diff --git a/appveyor.yml b/appveyor.yml
index c145df3..f883c86 100755
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -5,6 +5,9 @@
     - TARGET: x86_64-pc-windows-msvc
       GNUPLOT: no
 
+cache:
+  - 'C:\Users\appveyor\.cargo'
+
 install:
   - curl -sSf -o rustup-init.exe https://win.rustup.rs/
   - rustup-init.exe -y --default-host %TARGET% --default-toolchain stable
@@ -21,7 +24,8 @@
   - cargo build --release
   - cargo test --all --release
   - cargo build --benches --all --release
-  - cargo bench
+# Disable benchmarking until performance can be improved.
+#  - cargo bench
   - cargo doc --release --all --no-deps
 
 branches:
diff --git a/src/analysis/mod.rs b/src/analysis/mod.rs
index 1c072e1..5d84bef 100755
--- a/src/analysis/mod.rs
+++ b/src/analysis/mod.rs
@@ -53,10 +53,10 @@
             &criterion.baseline_directory,
             &criterion.output_directory,
         ) {
-            panic!(format!(
+            panic!(
                 "Baseline '{base}' must exist before comparison is allowed; try --save-baseline {base}",
                 base=criterion.baseline_directory,
-            ));
+            );
         }
     }
 
@@ -278,7 +278,7 @@
     )
     .0;
 
-    let point = Slope::fit(&data);
+    let point = Slope::fit(data);
     let (lb, ub) = distribution.confidence_interval(config.confidence_level);
     let se = distribution.std_dev(None);
 
diff --git a/src/benchmark_group.rs b/src/benchmark_group.rs
index ecb8258..723d01e 100755
--- a/src/benchmark_group.rs
+++ b/src/benchmark_group.rs
@@ -345,7 +345,7 @@
                     func.profile(
                         &self.criterion.measurement,
                         &id,
-                        &self.criterion,
+                        self.criterion,
                         &report_context,
                         duration,
                         input,
diff --git a/src/csv_report.rs b/src/csv_report.rs
index f30b817..3b744df 100755
--- a/src/csv_report.rs
+++ b/src/csv_report.rs
@@ -31,14 +31,14 @@
         let mut data_scaled: Vec<f64> = data.sample_times().as_ref().into();
         let unit = formatter.scale_for_machines(&mut data_scaled);
         let group = id.group_id.as_str();
-        let function = id.function_id.as_ref().map(String::as_str);
-        let value = id.value_str.as_ref().map(String::as_str);
+        let function = id.function_id.as_deref();
+        let value = id.value_str.as_deref();
         let (throughput_num, throughput_type) = match id.throughput {
             Some(Throughput::Bytes(bytes)) => (Some(format!("{}", bytes)), Some("bytes")),
             Some(Throughput::Elements(elems)) => (Some(format!("{}", elems)), Some("elements")),
             None => (None, None),
         };
-        let throughput_num = throughput_num.as_ref().map(String::as_str);
+        let throughput_num = throughput_num.as_deref();
 
         for (count, measured_value) in data.iter_counts().iter().zip(data_scaled.into_iter()) {
             let row = CsvRow {
diff --git a/src/error.rs b/src/error.rs
index c1ecf76..9b7eb17 100755
--- a/src/error.rs
+++ b/src/error.rs
@@ -5,6 +5,7 @@
 use std::io;
 use std::path::PathBuf;
 
+#[allow(clippy::enum_variant_names)]
 #[derive(Debug)]
 pub enum Error {
     AccessError {
diff --git a/src/html/mod.rs b/src/html/mod.rs
index 02ff0de..d360656 100755
--- a/src/html/mod.rs
+++ b/src/html/mod.rs
@@ -199,8 +199,8 @@
         let mut individual_links = HashMap::with_capacity(ids.len());
 
         for id in ids.iter() {
-            let function_id = id.function_id.as_ref().map(String::as_str);
-            let value = id.value_str.as_ref().map(String::as_str);
+            let function_id = id.function_id.as_deref();
+            let value = id.value_str.as_deref();
 
             let individual_link = ReportLink::individual(output_directory, id);
 
@@ -218,12 +218,12 @@
         // numerically. Otherwise sort lexicographically.
         if values.iter().all(|os| parse_opt(os).is_some()) {
             values.sort_unstable_by(|v1, v2| {
-                let num1 = parse_opt(&v1);
-                let num2 = parse_opt(&v2);
+                let num1 = parse_opt(v1);
+                let num2 = parse_opt(v2);
 
                 num1.partial_cmp(&num2).unwrap_or(Ordering::Less)
             });
-            values.dedup_by_key(|os| parse_opt(&os).unwrap());
+            values.dedup_by_key(|os| parse_opt(os).unwrap());
         } else {
             values.sort_unstable();
             values.dedup();
@@ -438,14 +438,14 @@
 
         // If all of the value strings can be parsed into a number, sort/dedupe
         // numerically. Otherwise sort lexicographically.
-        if value_strs.iter().all(|os| try_parse(&*os).is_some()) {
+        if value_strs.iter().all(|os| try_parse(*os).is_some()) {
             value_strs.sort_unstable_by(|v1, v2| {
-                let num1 = try_parse(&v1);
-                let num2 = try_parse(&v2);
+                let num1 = try_parse(v1);
+                let num2 = try_parse(v2);
 
                 num1.partial_cmp(&num2).unwrap_or(Ordering::Less)
             });
-            value_strs.dedup_by_key(|os| try_parse(&os).unwrap());
+            value_strs.dedup_by_key(|os| try_parse(os).unwrap());
         } else {
             value_strs.sort_unstable();
             value_strs.dedup();
@@ -455,7 +455,7 @@
             let samples_with_function: Vec<_> = data
                 .iter()
                 .by_ref()
-                .filter(|&&(ref id, _)| id.function_id.as_ref() == Some(&function_id))
+                .filter(|&&(id, _)| id.function_id.as_ref() == Some(function_id))
                 .collect();
 
             if samples_with_function.len() > 1 {
@@ -476,7 +476,7 @@
             let samples_with_value: Vec<_> = data
                 .iter()
                 .by_ref()
-                .filter(|&&(ref id, _)| id.value_str.as_ref() == Some(&value_str))
+                .filter(|&&(id, _)| id.value_str.as_ref() == Some(value_str))
                 .collect();
 
             if samples_with_value.len() > 1 {
@@ -497,17 +497,13 @@
         // First sort the ids/data by value.
         // If all of the value strings can be parsed into a number, sort/dedupe
         // numerically. Otherwise sort lexicographically.
-        let all_values_numeric = all_data.iter().all(|(ref id, _)| {
-            id.value_str
-                .as_ref()
-                .map(String::as_str)
-                .and_then(try_parse)
-                .is_some()
-        });
+        let all_values_numeric = all_data
+            .iter()
+            .all(|(id, _)| id.value_str.as_deref().and_then(try_parse).is_some());
         if all_values_numeric {
             all_data.sort_unstable_by(|(a, _), (b, _)| {
-                let num1 = a.value_str.as_ref().map(String::as_str).and_then(try_parse);
-                let num2 = b.value_str.as_ref().map(String::as_str).and_then(try_parse);
+                let num1 = a.value_str.as_deref().and_then(try_parse);
+                let num2 = b.value_str.as_deref().and_then(try_parse);
 
                 num1.partial_cmp(&num2).unwrap_or(Ordering::Less)
             });
@@ -577,7 +573,7 @@
             if !different_mean {
                 explanation_str = "No change in performance detected.".to_owned();
             } else {
-                let comparison = compare_to_threshold(&mean_est, comp.noise_threshold);
+                let comparison = compare_to_threshold(mean_est, comp.noise_threshold);
                 match comparison {
                     ComparisonResult::Improved => {
                         explanation_str = "Performance has improved.".to_owned();
@@ -689,7 +685,7 @@
                 fs::mkdirp(&both_dir)
             });
 
-            let comp_data = plot_data.comparison(&comp);
+            let comp_data = plot_data.comparison(comp);
 
             self.plotter.borrow_mut().pdf(plot_ctx, comp_data);
             self.plotter.borrow_mut().pdf(plot_ctx_small, comp_data);
@@ -767,12 +763,12 @@
 
         self.plotter.borrow_mut().violin(plot_ctx, formatter, data);
 
-        let value_types: Vec<_> = data.iter().map(|&&(ref id, _)| id.value_type()).collect();
+        let value_types: Vec<_> = data.iter().map(|&&(id, _)| id.value_type()).collect();
         let mut line_path = None;
 
         if value_types.iter().all(|x| x == &value_types[0]) {
             if let Some(value_type) = value_types[0] {
-                let values: Vec<_> = data.iter().map(|&&(ref id, _)| id.as_number()).collect();
+                let values: Vec<_> = data.iter().map(|&&(id, _)| id.as_number()).collect();
                 if values.iter().any(|x| x != &values[0]) {
                     self.plotter
                         .borrow_mut()
@@ -785,7 +781,7 @@
         let path_prefix = if full_summary { "../.." } else { "../../.." };
         let benchmarks = data
             .iter()
-            .map(|&&(ref id, _)| {
+            .map(|&&(id, _)| {
                 IndividualBenchmark::from_id(&report_context.output_directory, path_prefix, id)
             })
             .collect();
diff --git a/src/lib.rs b/src/lib.rs
index 7cc4070..98dcf1e 100755
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -23,9 +23,7 @@
     allow(
         clippy::just_underscores_and_digits, // Used in the stats code
         clippy::transmute_ptr_to_ptr, // Used in the stats code
-        clippy::option_as_ref_deref, // Remove when MSRV bumped above 1.40
         clippy::manual_non_exhaustive, // Remove when MSRV bumped above 1.40
-        clippy::match_like_matches_macro, // Remove when MSRV bumped above 1.42
     )
 )]
 
@@ -339,10 +337,7 @@
 }
 impl Mode {
     pub fn is_benchmark(&self) -> bool {
-        match self {
-            Mode::Benchmark => true,
-            _ => false,
-        }
+        matches!(self, Mode::Benchmark)
     }
 }
 
@@ -1515,10 +1510,7 @@
     }
 
     fn is_linear(&self) -> bool {
-        match self {
-            ActualSamplingMode::Linear => true,
-            _ => false,
-        }
+        matches!(self, ActualSamplingMode::Linear)
     }
 
     fn recommend_linear_sample_size(target_time: f64, met: f64) -> u64 {
diff --git a/src/macros.rs b/src/macros.rs
index 2ca7a7d..85d8c59 100755
--- a/src/macros.rs
+++ b/src/macros.rs
@@ -73,7 +73,7 @@
         }
     };
     ($name:ident, $( $target:path ),+ $(,)*) => {
-        criterion_group!{
+        $crate::criterion_group!{
             name = $name;
             config = $crate::Criterion::default();
             targets = $( $target ),+
diff --git a/src/plot/gnuplot_backend/mod.rs b/src/plot/gnuplot_backend/mod.rs
index e902d47..95e07ef 100755
--- a/src/plot/gnuplot_backend/mod.rs
+++ b/src/plot/gnuplot_backend/mod.rs
@@ -1,5 +1,5 @@
 use std::iter;
-use std::path::PathBuf;
+use std::path::Path;
 use std::process::Child;
 
 use crate::stats::univariate::Sample;
@@ -40,9 +40,9 @@
 const DARK_ORANGE: Color = Color::Rgb(255, 127, 0);
 const DARK_RED: Color = Color::Rgb(227, 26, 28);
 
-fn debug_script(path: &PathBuf, figure: &Figure) {
+fn debug_script(path: &Path, figure: &Figure) {
     if crate::debug_enabled() {
-        let mut script_path = path.clone();
+        let mut script_path = path.to_path_buf();
         script_path.set_extension("gnuplot");
         info!("Writing gnuplot script to {:?}", script_path);
         let result = figure.save(script_path.as_path());
diff --git a/src/plot/gnuplot_backend/pdf.rs b/src/plot/gnuplot_backend/pdf.rs
index 3ee2360..a0b85c7 100755
--- a/src/plot/gnuplot_backend/pdf.rs
+++ b/src/plot/gnuplot_backend/pdf.rs
@@ -33,7 +33,7 @@
         format!("Iterations (x 10^{})", exponent)
     };
 
-    let (xs, ys) = kde::sweep(&scaled_avg_times, KDE_POINTS, None);
+    let (xs, ys) = kde::sweep(scaled_avg_times, KDE_POINTS, None);
     let (lost, lomt, himt, hist) = avg_times.fences();
     let mut fences = [lost, lomt, himt, hist];
     let _ = formatter.scale_values(typical, &mut fences);
diff --git a/src/plot/gnuplot_backend/summary.rs b/src/plot/gnuplot_backend/summary.rs
index e944360..d57a174 100755
--- a/src/plot/gnuplot_backend/summary.rs
+++ b/src/plot/gnuplot_backend/summary.rs
@@ -83,9 +83,9 @@
     // This assumes the curves are sorted. It also assumes that the benchmark IDs all have numeric
     // values or throughputs and that value is sensible (ie. not a mix of bytes and elements
     // or whatnot)
-    for (key, group) in &all_curves.iter().group_by(|&&&(ref id, _)| &id.function_id) {
+    for (key, group) in &all_curves.iter().group_by(|&&&(id, _)| &id.function_id) {
         let mut tuples: Vec<_> = group
-            .map(|&&(ref id, ref sample)| {
+            .map(|&&(id, ref sample)| {
                 // Unwrap is fine here because it will only fail if the assumptions above are not true
                 // ie. programmer error.
                 let x = id.as_number().unwrap();
@@ -185,7 +185,7 @@
                     positions: tics(),
                     labels: all_curves
                         .iter()
-                        .map(|&&(ref id, _)| gnuplot_escape(id.as_title())),
+                        .map(|&&(id, _)| gnuplot_escape(id.as_title())),
                 })
         });
 
diff --git a/src/plot/plotters_backend/pdf.rs b/src/plot/plotters_backend/pdf.rs
index 1297b79..333893f 100755
--- a/src/plot/plotters_backend/pdf.rs
+++ b/src/plot/plotters_backend/pdf.rs
@@ -197,7 +197,7 @@
         format!("Iterations (x 10^{})", exponent)
     };
 
-    let (xs, ys) = kde::sweep(&scaled_avg_times, KDE_POINTS, None);
+    let (xs, ys) = kde::sweep(scaled_avg_times, KDE_POINTS, None);
     let (lost, lomt, himt, hist) = avg_times.fences();
     let mut fences = [lost, lomt, himt, hist];
     let _ = formatter.scale_values(typical, &mut fences);
diff --git a/src/plot/plotters_backend/summary.rs b/src/plot/plotters_backend/summary.rs
index 14f4b5e..dad8a5b 100755
--- a/src/plot/plotters_backend/summary.rs
+++ b/src/plot/plotters_backend/summary.rs
@@ -46,8 +46,8 @@
         AxisScale::Logarithmic => draw_line_comarision_figure(
             root_area,
             unit,
-            LogRange(x_range),
-            LogRange(y_range),
+            x_range.log_scale(),
+            y_range.log_scale(),
             value_type,
             series_data,
         ),
@@ -132,9 +132,9 @@
     // This assumes the curves are sorted. It also assumes that the benchmark IDs all have numeric
     // values or throughputs and that value is sensible (ie. not a mix of bytes and elements
     // or whatnot)
-    for (key, group) in &all_curves.iter().group_by(|&&&(ref id, _)| &id.function_id) {
+    for (key, group) in &all_curves.iter().group_by(|&&&(id, _)| &id.function_id) {
         let mut tuples: Vec<_> = group
-            .map(|&&(ref id, ref sample)| {
+            .map(|&&(id, ref sample)| {
                 // Unwrap is fine here because it will only fail if the assumptions above are not true
                 // ie. programmer error.
                 let x = id.as_number().unwrap();
@@ -164,7 +164,7 @@
 
     let mut kdes = all_curves
         .iter()
-        .map(|&&(ref id, ref sample)| {
+        .map(|&&(id, ref sample)| {
             let (x, mut y) = kde::sweep(Sample::new(sample), KDE_POINTS, None);
             let y_max = Sample::new(&y).max();
             for y in y.iter_mut() {
@@ -211,7 +211,7 @@
     match axis_scale {
         AxisScale::Linear => draw_violin_figure(root_area, unit, x_range, y_range, kdes),
         AxisScale::Logarithmic => {
-            draw_violin_figure(root_area, unit, LogRange(x_range), y_range, kdes)
+            draw_violin_figure(root_area, unit, x_range.log_scale(), y_range, kdes)
         }
     }
 }
diff --git a/src/report.rs b/src/report.rs
index 9148a9e..60a144a 100755
--- a/src/report.rs
+++ b/src/report.rs
@@ -609,7 +609,7 @@
             if !different_mean {
                 explanation_str = "No change in performance detected.".to_owned();
             } else {
-                let comparison = compare_to_threshold(&mean_est, comp.noise_threshold);
+                let comparison = compare_to_threshold(mean_est, comp.noise_threshold);
                 match comparison {
                     ComparisonResult::Improved => {
                         point_estimate_str = self.green(self.bold(point_estimate_str));
diff --git a/src/stats/bivariate/bootstrap.rs b/src/stats/bivariate/bootstrap.rs
index 8fe8ede..9eb7fa7 100755
--- a/src/stats/bivariate/bootstrap.rs
+++ b/src/stats/bivariate/bootstrap.rs
@@ -10,8 +10,12 @@
             use crate::stats::bivariate::Data;
 
             quickcheck! {
-                fn means(size: usize, start: usize,
-                         offset: usize, nresamples: usize) -> TestResult {
+                fn means(size: u8, start: u8,
+                         offset: u8, nresamples: u8) -> TestResult {
+                    let size = size as usize;
+                    let start = start as usize;
+                    let offset = offset as usize;
+                    let nresamples = nresamples as usize;
                     if let Some(x) = crate::stats::test::vec::<$ty>(size, start) {
                         let y = crate::stats::test::vec::<$ty>(size + offset, start + offset).unwrap();
                         let data = Data::new(&x[start..], &y[start+offset..]);
@@ -48,8 +52,12 @@
             }
 
             quickcheck! {
-                fn slope(size: usize, start: usize,
-                         offset: usize, nresamples: usize) -> TestResult {
+                fn slope(size: u8, start: u8,
+                         offset: u8, nresamples: u8) -> TestResult {
+                    let size = size as usize;
+                    let start = start as usize;
+                    let offset = offset as usize;
+                    let nresamples = nresamples as usize;
                     if let Some(x) = crate::stats::test::vec::<$ty>(size, start) {
                         let y = crate::stats::test::vec::<$ty>(size + offset, start + offset).unwrap();
                         let data = Data::new(&x[start..], &y[start+offset..]);
diff --git a/src/stats/bivariate/mod.rs b/src/stats/bivariate/mod.rs
index b233b60..d1e8df7 100755
--- a/src/stats/bivariate/mod.rs
+++ b/src/stats/bivariate/mod.rs
@@ -97,12 +97,12 @@
 
     /// Returns a view into the `X` data
     pub fn x(&self) -> &'a Sample<X> {
-        Sample::new(&self.0)
+        Sample::new(self.0)
     }
 
     /// Returns a view into the `Y` data
     pub fn y(&self) -> &'a Sample<Y> {
-        Sample::new(&self.1)
+        Sample::new(self.1)
     }
 }
 
diff --git a/src/stats/univariate/bootstrap.rs b/src/stats/univariate/bootstrap.rs
index dbb52f5..21c9140 100755
--- a/src/stats/univariate/bootstrap.rs
+++ b/src/stats/univariate/bootstrap.rs
@@ -9,7 +9,10 @@
             use crate::stats::univariate::{Sample, mixed, self};
 
             quickcheck!{
-                fn mean(size: usize, start: usize, nresamples: usize) -> TestResult {
+                fn mean(size: u8, start: u8, nresamples: u8) -> TestResult {
+                    let size = size as usize;
+                    let start = start as usize;
+                    let nresamples = nresamples as usize;
                     if let Some(v) = crate::stats::test::vec::<$ty>(size, start) {
                         let sample = Sample::new(&v[start..]);
 
@@ -38,7 +41,10 @@
             }
 
             quickcheck!{
-                fn mean_median(size: usize, start: usize, nresamples: usize) -> TestResult {
+                fn mean_median(size: u8, start: u8, nresamples: u8) -> TestResult {
+                    let size = size as usize;
+                    let start = start as usize;
+                    let nresamples = nresamples as usize;
                     if let Some(v) = crate::stats::test::vec::<$ty>(size, start) {
                         let sample = Sample::new(&v[start..]);
 
@@ -73,10 +79,15 @@
 
             quickcheck!{
                 fn mixed_two_sample(
-                    a_size: usize, a_start: usize,
-                    b_size: usize, b_start: usize,
-                    nresamples: usize
+                    a_size: u8, a_start: u8,
+                    b_size: u8, b_start: u8,
+                    nresamples: u8
                 ) -> TestResult {
+                    let a_size = a_size as usize;
+                    let b_size = b_size as usize;
+                    let a_start = a_start as usize;
+                    let b_start = b_start as usize;
+                    let nresamples = nresamples as usize;
                     if let (Some(a), Some(b)) =
                         (crate::stats::test::vec::<$ty>(a_size, a_start), crate::stats::test::vec::<$ty>(b_size, b_start))
                     {
@@ -109,10 +120,15 @@
 
             quickcheck!{
                 fn two_sample(
-                    a_size: usize, a_start: usize,
-                    b_size: usize, b_start: usize,
-                    nresamples: usize
+                    a_size: u8, a_start: u8,
+                    b_size: u8, b_start: u8,
+                    nresamples: u8
                 ) -> TestResult {
+                    let a_size = a_size as usize;
+                    let b_size = b_size as usize;
+                    let a_start = a_start as usize;
+                    let b_start = b_start as usize;
+                    let nresamples = nresamples as usize;
                     if let (Some(a), Some(b)) =
                         (crate::stats::test::vec::<$ty>(a_size, a_start), crate::stats::test::vec::<$ty>(b_size, b_start))
                     {
diff --git a/src/stats/univariate/kde/kernel.rs b/src/stats/univariate/kde/kernel.rs
index b4204f5..c3d0ff5 100755
--- a/src/stats/univariate/kde/kernel.rs
+++ b/src/stats/univariate/kde/kernel.rs
@@ -39,13 +39,15 @@
 
                 quickcheck! {
                     fn symmetric(x: $ty) -> bool {
-                        relative_eq!(Gaussian.evaluate(-x), Gaussian.evaluate(x))
+                        x.is_nan() || relative_eq!(Gaussian.evaluate(-x), Gaussian.evaluate(x))
                     }
                 }
 
                 // Any [a b] integral should be in the range [0 1]
                 quickcheck! {
                     fn integral(a: $ty, b: $ty) -> TestResult {
+                        let a = a.sin().abs(); // map the value to [0 1]
+                        let b = b.sin().abs(); // map the value to [0 1]
                         const DX: $ty = 1e-3;
 
                         if a > b {
diff --git a/src/stats/univariate/kde/mod.rs b/src/stats/univariate/kde/mod.rs
index efc27cd..9b0836d 100755
--- a/src/stats/univariate/kde/mod.rs
+++ b/src/stats/univariate/kde/mod.rs
@@ -98,7 +98,9 @@
 
             // The [-inf inf] integral of the estimated PDF should be one
             quickcheck! {
-                fn integral(size: usize, start: usize) -> TestResult {
+                fn integral(size: u8, start: u8) -> TestResult {
+                    let size = size as usize;
+                    let start = start as usize;
                     const DX: $ty = 1e-3;
 
                     if let Some(v) = crate::stats::test::vec::<$ty>(size, start) {
diff --git a/src/stats/univariate/outliers/tukey.rs b/src/stats/univariate/outliers/tukey.rs
index bfd08f1..70713ac 100755
--- a/src/stats/univariate/outliers/tukey.rs
+++ b/src/stats/univariate/outliers/tukey.rs
@@ -224,42 +224,27 @@
 impl Label {
     /// Checks if the data point has an "unusually" high value
     pub fn is_high(&self) -> bool {
-        match *self {
-            HighMild | HighSevere => true,
-            _ => false,
-        }
+        matches!(*self, HighMild | HighSevere)
     }
 
     /// Checks if the data point is labeled as a "mild" outlier
     pub fn is_mild(&self) -> bool {
-        match *self {
-            HighMild | LowMild => true,
-            _ => false,
-        }
+        matches!(*self, HighMild | LowMild)
     }
 
     /// Checks if the data point has an "unusually" low value
     pub fn is_low(&self) -> bool {
-        match *self {
-            LowMild | LowSevere => true,
-            _ => false,
-        }
+        matches!(*self, LowMild | LowSevere)
     }
 
     /// Checks if the data point is labeled as an outlier
     pub fn is_outlier(&self) -> bool {
-        match *self {
-            NotAnOutlier => false,
-            _ => true,
-        }
+        matches!(*self, NotAnOutlier)
     }
 
     /// Checks if the data point is labeled as a "severe" outlier
     pub fn is_severe(&self) -> bool {
-        match *self {
-            HighSevere | LowSevere => true,
-            _ => false,
-        }
+        matches!(*self, HighSevere | LowSevere)
     }
 }
 
diff --git a/src/stats/univariate/resamples.rs b/src/stats/univariate/resamples.rs
index 831bc7a..923669d 100755
--- a/src/stats/univariate/resamples.rs
+++ b/src/stats/univariate/resamples.rs
@@ -70,7 +70,9 @@
 
     // Check that the resample is a subset of the sample
     quickcheck! {
-        fn subset(size: usize, nresamples: usize) -> TestResult {
+        fn subset(size: u8, nresamples: u8) -> TestResult {
+            let size = size as usize;
+            let nresamples = nresamples as usize;
             if size > 1 {
                 let v: Vec<_> = (0..size).map(|i| i as f32).collect();
                 let sample = Sample::new(&v);