Repository: toml-rs/toml
Pull request #718 (2024-04-26 18:08:15)

chore: Update from _rust/main template


Patch:
diff --git a/.clippy.toml b/.clippy.toml
index a0467c24..1d4c5dc6 100644
--- a/.clippy.toml
+++ b/.clippy.toml
@@ -1,5 +1,4 @@
-msrv = "1.70"  # MSRV
-warn-on-all-wildcard-imports = true
+allow-print-in-tests = true
 allow-expect-in-tests = true
 allow-unwrap-in-tests = true
 allow-dbg-in-tests = true
diff --git a/.github/renovate.json5 b/.github/renovate.json5
index 4373c603..a1f3b905 100644
--- a/.github/renovate.json5
+++ b/.github/renovate.json5
@@ -3,6 +3,7 @@
     'before 5am on the first day of the month',
   ],
   semanticCommits: 'enabled',
+  commitMessageLowerCase: 'never',
   configMigration: true,
   dependencyDashboard: true,
   customManagers: [
@@ -17,29 +18,28 @@
         '^\\.github/workflows/rust-next.yml$',
       ],
       matchStrings: [
-        'MSRV.*?(?<currentValue>\\d+\\.\\d+(\\.\\d+)?)',
-        '(?<currentValue>\\d+\\.\\d+(\\.\\d+)?).*?MSRV',
+        'STABLE.*?(?<currentValue>\\d+\\.\\d+(\\.\\d+)?)',
+        '(?<currentValue>\\d+\\.\\d+(\\.\\d+)?).*?STABLE',
       ],
-      depNameTemplate: 'rust',
+      depNameTemplate: 'STABLE',
       packageNameTemplate: 'rust-lang/rust',
       datasourceTemplate: 'github-releases',
     },
   ],
   packageRules: [
     {
-      commitMessageTopic: 'MSRV',
+      commitMessageTopic: 'Rust Stable',
       matchManagers: [
         'custom.regex',
       ],
       matchPackageNames: [
-        'rust',
+        'STABLE',
       ],
-      minimumReleaseAge: '252 days',  // 6 releases * 6 weeks per release * 7 days per week
-      internalChecksFilter: 'strict',
       extractVersion: '^(?<version>\\d+\\.\\d+)',  // Drop the patch version
       schedule: [
         '* * * * *',
       ],
+      automerge: true,
     },
     // Goals:
     // - Keep version reqs low, ignoring compatible normal/build dependencies
@@ -72,6 +72,7 @@
       matchCurrentVersion: '>=1.0.0',
       matchUpdateTypes: [
         'minor',
+        'patch',
       ],
       enabled: false,
     },
@@ -99,6 +100,7 @@
       matchCurrentVersion: '>=1.0.0',
       matchUpdateTypes: [
         'minor',
+        'patch',
       ],
       automerge: true,
       groupName: 'compatible (dev)',
diff --git a/.github/settings.yml b/.github/settings.yml
index 10749c32..21f8ffb8 100644
--- a/.github/settings.yml
+++ b/.github/settings.yml
@@ -62,14 +62,18 @@ labels:
     description: "Call for participation: Help is requested to fix this issue."
     color: '#02E10C'
 
-branches:
-  - name: main
-    protection:
-      required_pull_request_reviews: null
-      required_conversation_resolution: true
-      required_status_checks:
-        # Required. Require branches to be up to date before merging.
-        strict: false
-        contexts: ["CI", "Lint Commits", "Spell Check with Typos"]
-      enforce_admins: false
-      restrictions: null
+# This serves more as documentation.
+# Branch protection API was replaced by rulesets but settings isn't updated.
+# See https://github.com/repository-settings/app/issues/825
+#
+# branches:
+#   - name: main
+#     protection:
+#       required_pull_request_reviews: null
+#       required_conversation_resolution: true
+#       required_status_checks:
+#         # Required. Require branches to be up to date before merging.
+#         strict: false
+#         contexts: ["CI", "Spell Check with Typos"]
+#       enforce_admins: false
+#       restrictions: null
diff --git a/.github/workflows/audit.yml b/.github/workflows/audit.yml
index ccee1fef..07c70eeb 100644
--- a/.github/workflows/audit.yml
+++ b/.github/workflows/audit.yml
@@ -17,6 +17,10 @@ env:
   CARGO_TERM_COLOR: always
   CLICOLOR: 1
 
+concurrency:
+  group: "${{ github.workflow }}-${{ github.ref }}"
+  cancel-in-progress: true
+
 jobs:
   security_audit:
     permissions:
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 2b886af6..95b13b4f 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -14,21 +14,27 @@ env:
   CARGO_TERM_COLOR: always
   CLICOLOR: 1
 
+concurrency:
+  group: "${{ github.workflow }}-${{ github.ref }}"
+  cancel-in-progress: true
+
 jobs:
   ci:
     permissions:
       contents: none
     name: CI
-    needs: [test, msrv, docs, rustfmt, clippy]
+    needs: [test, msrv, lockfile, docs, rustfmt, clippy]
     runs-on: ubuntu-latest
+    if: "always()"
     steps:
-      - name: Done
-        run: exit 0
+      - name: Failed
+        run: exit 1
+        if: "contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled') || contains(needs.*.result, 'skipped')"
   test:
     name: Test
     strategy:
       matrix:
-        os: ["ubuntu-latest", "windows-latest", "macos-latest"]
+        os: ["ubuntu-latest", "windows-latest", "macos-14"]
         rust: ["stable"]
     continue-on-error: ${{ matrix.rust != 'stable' }}
     runs-on: ${{ matrix.os }}
@@ -40,26 +46,13 @@ jobs:
       with:
         toolchain: ${{ matrix.rust }}
     - uses: Swatinem/rust-cache@v2
+    - uses: taiki-e/install-action@cargo-hack
     - name: Build
-      run: cargo test --no-run --workspace --all-features
-    - name: Default features
-      run: cargo test --workspace
-    - name: toml_edit (all features)
-      run: cargo test -p toml_edit --all-features
-    - name: toml_edit (no-default features)
-      run: cargo test -p toml_edit --no-default-features
-    - name: toml (preserve_order)
-      run: cargo test -p toml --features preserve_order
-    - name: toml (all features)
-      run: cargo test -p toml --all-features
-    - name: toml (parse-only)
-      run: cargo test -p toml --no-default-features --features parse
-    - name: toml (display-only)
-      run: cargo test -p toml --no-default-features --features display
-    - name: toml (no-default features)
-      run: cargo test -p toml --no-default-features
+      run: cargo test --workspace --no-run
+    - name: Test
+      run: cargo hack test --feature-powerset --workspace
   msrv:
-    name: "Check MSRV: 1.70"
+    name: "Check MSRV"
     runs-on: ubuntu-latest
     steps:
     - name: Checkout repository
@@ -67,14 +60,11 @@ jobs:
     - name: Install Rust
       uses: dtolnay/rust-toolchain@stable
       with:
-        toolchain: "1.70"  # MSRV
+        toolchain: stable
     - uses: Swatinem/rust-cache@v2
+    - uses: taiki-e/install-action@cargo-hack
     - name: Default features
-      run: cargo check --workspace --all-targets
-    - name: All features
-      run: cargo check --workspace --all-targets --all-features
-    - name: No-default features
-      run: cargo check --workspace --all-targets --no-default-features
+      run: cargo hack check --feature-powerset --locked --rust-version --ignore-private --workspace --all-targets
   lockfile:
     runs-on: ubuntu-latest
     steps:
@@ -86,7 +76,7 @@ jobs:
         toolchain: stable
     - uses: Swatinem/rust-cache@v2
     - name: "Is lockfile updated?"
-      run: cargo fetch --locked
+      run: cargo update --workspace --locked
   docs:
     name: Docs
     runs-on: ubuntu-latest
@@ -96,7 +86,7 @@ jobs:
     - name: Install Rust
       uses: dtolnay/rust-toolchain@stable
       with:
-        toolchain: stable
+        toolchain: "1.76"  # STABLE
     - uses: Swatinem/rust-cache@v2
     - name: Check documentation
       env:
@@ -111,9 +101,7 @@ jobs:
     - name: Install Rust
       uses: dtolnay/rust-toolchain@stable
       with:
-        # Not MSRV because its harder to jump between versions and people are
-        # more likely to have stable
-        toolchain: stable
+        toolchain: "1.76"  # STABLE
         components: rustfmt
     - uses: Swatinem/rust-cache@v2
     - name: Check formatting
@@ -129,13 +117,13 @@ jobs:
     - name: Install Rust
       uses: dtolnay/rust-toolchain@stable
       with:
-        toolchain: "1.70"  # MSRV
+        toolchain: "1.76"  # STABLE
         components: clippy
     - uses: Swatinem/rust-cache@v2
     - name: Install SARIF tools
-      run: cargo install clippy-sarif --version 0.3.4 --locked  # Held back due to msrv
+      run: cargo install clippy-sarif --locked
     - name: Install SARIF tools
-      run: cargo install sarif-fmt --version 0.3.4 --locked # Held back due to msrv
+      run: cargo install sarif-fmt --locked
     - name: Check
       run: >
         cargo clippy --workspace --all-features --all-targets --message-format=json -- -D warnings --allow deprecated
@@ -150,3 +138,22 @@ jobs:
         wait-for-processing: true
     - name: Report status
       run: cargo clippy --workspace --all-features --all-targets -- -D warnings --allow deprecated
+  coverage:
+    name: Coverage
+    runs-on: ubuntu-latest
+    steps:
+    - name: Checkout repository
+      uses: actions/checkout@v4
+    - name: Install Rust
+      uses: dtolnay/rust-toolchain@stable
+      with:
+        toolchain: stable
+    - uses: Swatinem/rust-cache@v2
+    - name: Install cargo-tarpaulin
+      run: cargo install cargo-tarpaulin
+    - name: Gather coverage
+      run: cargo tarpaulin --output-dir coverage --out lcov
+    - name: Publish to Coveralls
+      uses: coverallsapp/github-action@master
+      with:
+        github-token: ${{ secrets.GITHUB_TOKEN }}
diff --git a/.github/workflows/committed.yml b/.github/workflows/committed.yml
index 04625584..e7a50fbb 100644
--- a/.github/workflows/committed.yml
+++ b/.github/workflows/committed.yml
@@ -11,6 +11,10 @@ env:
   CARGO_TERM_COLOR: always
   CLICOLOR: 1
 
+concurrency:
+  group: "${{ github.workflow }}-${{ github.ref }}"
+  cancel-in-progress: true
+
 jobs:
   committed:
     name: Lint Commits
diff --git a/.github/workflows/pre-commit.yml b/.github/workflows/pre-commit.yml
index 6eb6ca19..1b000abf 100644
--- a/.github/workflows/pre-commit.yml
+++ b/.github/workflows/pre-commit.yml
@@ -12,6 +12,10 @@ env:
   CARGO_TERM_COLOR: always
   CLICOLOR: 1
 
+concurrency:
+  group: "${{ github.workflow }}-${{ github.ref }}"
+  cancel-in-progress: true
+
 jobs:
   pre-commit:
     permissions:
diff --git a/.github/workflows/rust-next.yml b/.github/workflows/rust-next.yml
index fa112e1c..1c1b7b0f 100644
--- a/.github/workflows/rust-next.yml
+++ b/.github/workflows/rust-next.yml
@@ -12,12 +12,16 @@ env:
   CARGO_TERM_COLOR: always
   CLICOLOR: 1
 
+concurrency:
+  group: "${{ github.workflow }}-${{ github.ref }}"
+  cancel-in-progress: true
+
 jobs:
   test:
     name: Test
     strategy:
       matrix:
-        os: ["ubuntu-latest", "windows-latest", "macos-latest"]
+        os: ["ubuntu-latest", "windows-latest", "macos-latest", "macos-14"]
         rust: ["stable", "beta"]
         include:
         - os: ubuntu-latest
@@ -32,24 +36,11 @@ jobs:
       with:
         toolchain: ${{ matrix.rust }}
     - uses: Swatinem/rust-cache@v2
+    - uses: taiki-e/install-action@cargo-hack
     - name: Build
-      run: cargo test --no-run --workspace --all-features
-    - name: Default features
-      run: cargo test --workspace
-    - name: toml_edit (all features)
-      run: cargo test -p toml_edit --all-features
-    - name: toml_edit (no-default features)
-      run: cargo test -p toml_edit --no-default-features
-    - name: toml (preserve_order)
-      run: cargo test -p toml --features preserve_order
-    - name: toml (all features)
-      run: cargo test -p toml --all-features
-    - name: toml (parse-only)
-      run: cargo test -p toml --no-default-features --features parse
-    - name: toml (display-only)
-      run: cargo test -p toml --no-default-features --features display
-    - name: toml (no-default features)
-      run: cargo test -p toml --no-default-features
+      run: cargo test --workspace --no-run
+    - name: Test
+      run: cargo hack test --feature-powerset --workspace
   latest:
     name: "Check latest dependencies"
     runs-on: ubuntu-latest
@@ -61,23 +52,10 @@ jobs:
       with:
         toolchain: stable
     - uses: Swatinem/rust-cache@v2
+    - uses: taiki-e/install-action@cargo-hack
     - name: Update dependencues
       run: cargo update
     - name: Build
-      run: cargo test --no-run --workspace --all-features
-    - name: Default features
-      run: cargo test --workspace
-    - name: toml_edit (all features)
-      run: cargo test -p toml_edit --all-features
-    - name: toml_edit (no-default features)
-      run: cargo test -p toml_edit --no-default-features
-    - name: toml (preserve_order)
-      run: cargo test -p toml --features preserve_order
-    - name: toml (all features)
-      run: cargo test -p toml --all-features
-    - name: toml (parse-only)
-      run: cargo test -p toml --no-default-features --features parse
-    - name: toml (display-only)
-      run: cargo test -p toml --no-default-features --features display
-    - name: toml (no-default features)
-      run: cargo test -p toml --no-default-features
+      run: cargo test --workspace --no-run
+    - name: Test
+      run: cargo hack test --feature-powerset --workspace
diff --git a/.github/workflows/spelling.yml b/.github/workflows/spelling.yml
index 12f75859..8e58d9ec 100644
--- a/.github/workflows/spelling.yml
+++ b/.github/workflows/spelling.yml
@@ -10,6 +10,10 @@ env:
   CARGO_TERM_COLOR: always
   CLICOLOR: 1
 
+concurrency:
+  group: "${{ github.workflow }}-${{ github.ref }}"
+  cancel-in-progress: true
+
 jobs:
   spelling:
     name: Spell Check with Typos
diff --git a/Cargo.toml b/Cargo.toml
index 3487dcd4..3f1b009a 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -20,5 +20,72 @@ include = [
   "tests/**/*"
 ]
 
-[profile.release]
-debug = 1
+[workspace.lints.rust]
+rust_2018_idioms = "warn"
+unreachable_pub = "warn"
+unsafe_op_in_unsafe_fn = "warn"
+unused_lifetimes = "warn"
+unused_macro_rules = "warn"
+unused_qualifications = "warn"
+
+[workspace.lints.clippy]
+bool_assert_comparison = "allow"
+branches_sharing_code = "allow"
+checked_conversions = "warn"
+collapsible_else_if = "allow"
+create_dir = "warn"
+dbg_macro = "warn"
+debug_assert_with_mut_call = "warn"
+doc_markdown = "warn"
+empty_enum = "warn"
+enum_glob_use = "warn"
+expl_impl_clone_on_copy = "warn"
+explicit_deref_methods = "warn"
+explicit_into_iter_loop = "warn"
+fallible_impl_from = "warn"
+filter_map_next = "warn"
+flat_map_option = "warn"
+float_cmp_const = "warn"
+fn_params_excessive_bools = "warn"
+from_iter_instead_of_collect = "warn"
+if_same_then_else = "allow"
+implicit_clone = "warn"
+imprecise_flops = "warn"
+inconsistent_struct_constructor = "warn"
+inefficient_to_string = "warn"
+infinite_loop = "warn"
+invalid_upcast_comparisons = "warn"
+items_after_statements = "warn"
+large_digit_groups = "warn"
+large_stack_arrays = "warn"
+large_types_passed_by_value = "warn"
+let_and_return = "allow"  # sometimes good to name what you are returning
+linkedlist = "warn"
+lossy_float_literal = "warn"
+macro_use_imports = "warn"
+match_wildcard_for_single_variants = "warn"
+mem_forget = "warn"
+mutex_integer = "warn"
+needless_continue = "warn"
+needless_for_each = "warn"
+negative_feature_names = "warn"
+path_buf_push_overwrite = "warn"
+ptr_as_ptr = "warn"
+rc_mutex = "warn"
+redundant_feature_names = "warn"
+ref_option_ref = "warn"
+rest_pat_in_fully_bound_structs = "warn"
+same_functions_in_if_condition = "warn"
+self_named_module_files = "warn"
+semicolon_if_nothing_returned = "warn"
+single_match_else = "warn"
+str_to_string = "warn"
+string_add = "warn"
+string_add_assign = "warn"
+string_lit_as_bytes = "warn"
+string_to_string = "warn"
+todo = "warn"
+trait_duplication_in_bounds = "warn"
+verbose_file_reads = "warn"
+wildcard_imports = "warn"
+zero_sized_map_values = "warn"
diff --git a/crates/benchmarks/Cargo.toml b/crates/benchmarks/Cargo.toml
index 1471cf1a..44fdd43b 100644
--- a/crates/benchmarks/Cargo.toml
+++ b/crates/benchmarks/Cargo.toml
@@ -24,3 +24,6 @@ harness = false
 [[bench]]
 name = "linear"
 harness = false
+
+[lints]
+workspace = true
diff --git a/crates/benchmarks/benches/cargo.rs b/crates/benchmarks/benches/cargo.rs
index 954135c4..79d41407 100644
--- a/crates/benchmarks/benches/cargo.rs
+++ b/crates/benchmarks/benches/cargo.rs
@@ -1,5 +1,7 @@
+#![allow(elided_lifetimes_in_paths)]
+
 mod toml_edit {
-    use super::*;
+    use super::{manifest, Data, MANIFESTS};
 
     #[divan::bench(args=MANIFESTS)]
     fn document(sample: &Data) -> ::toml_edit::DocumentMut {
@@ -13,7 +15,7 @@ mod toml_edit {
 }
 
 mod toml {
-    use super::*;
+    use super::{manifest, Data, MANIFESTS};
 
     #[divan::bench(args=MANIFESTS)]
     fn document(sample: &Data) -> ::toml::Value {
@@ -27,7 +29,7 @@ mod toml {
 }
 
 mod toml_v05 {
-    use super::*;
+    use super::{manifest, Data, MANIFESTS};
 
     #[divan::bench(args=MANIFESTS)]
     fn document(sample: &Data) -> ::toml_old::Value {
@@ -201,7 +203,7 @@ mod manifest {
 
     #[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
     #[serde(rename_all = "kebab-case")]
-    pub struct Manifest {
+    pub(crate) struct Manifest {
         package: Package,
         #[serde(default)]
         lib: Option<Lib>,
@@ -221,7 +223,7 @@ mod manifest {
 
     #[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
     #[serde(rename_all = "kebab-case")]
-    pub struct Package {
+    pub(crate) struct Package {
         name: String,
         version: String,
         #[serde(default)]
@@ -244,7 +246,7 @@ mod manifest {
 
     #[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
     #[serde(rename_all = "kebab-case")]
-    pub struct Lib {
+    pub(crate) struct Lib {
         name: String,
         #[serde(default)]
         path: Option<String>,
@@ -252,7 +254,7 @@ mod manifest {
 
     #[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
     #[serde(rename_all = "kebab-case")]
-    pub struct Bin {
+    pub(crate) struct Bin {
         name: String,
         #[serde(default)]
         test: bool,
@@ -263,14 +265,14 @@ mod manifest {
     #[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
     #[serde(rename_all = "kebab-case")]
     #[serde(untagged)]
-    pub enum Dependency {
+    pub(crate) enum Dependency {
         Version(String),
         Full(DependencyFull),
     }
 
     #[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
     #[serde(rename_all = "kebab-case")]
-    pub struct DependencyFull {
+    pub(crate) struct DependencyFull {
         #[serde(default)]
         version: Option<String>,
         #[serde(default)]
@@ -285,7 +287,7 @@ mod manifest {
 
     #[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
     #[serde(rename_all = "kebab-case")]
-    pub struct Target {
+    pub(crate) struct Target {
         #[serde(default)]
         dependencies: HashMap<String, Dependency>,
         #[serde(default)]
diff --git a/crates/benchmarks/benches/linear.rs b/crates/benchmarks/benches/linear.rs
index c66190a8..e11636af 100644
--- a/crates/benchmarks/benches/linear.rs
+++ b/crates/benchmarks/benches/linear.rs
@@ -1,14 +1,16 @@
+#![allow(elided_lifetimes_in_paths)]
+
 const NUM_ENTRIES: &[usize] = &[10, 100];
 
 mod map {
-    use super::*;
+    use super::NUM_ENTRIES;
 
     #[divan::bench(args = NUM_ENTRIES)]
     fn toml_edit(bencher: divan::Bencher, num_entries: usize) {
         bencher
             .with_inputs(|| gen(num_entries))
             .input_counter(divan::counter::BytesCount::of_str)
-            .bench_values(|sample| sample.parse::<toml_edit::DocumentMut>().unwrap())
+            .bench_values(|sample| sample.parse::<toml_edit::DocumentMut>().unwrap());
     }
 
     #[divan::bench(args = NUM_ENTRIES)]
@@ -16,7 +18,7 @@ mod map {
         bencher
             .with_inputs(|| gen(num_entries))
             .input_counter(divan::counter::BytesCount::of_str)
-            .bench_values(|sample| sample.parse::<toml::Table>().unwrap())
+            .bench_values(|sample| sample.parse::<toml::Table>().unwrap());
     }
 
     #[divan::bench(args = NUM_ENTRIES)]
@@ -24,28 +26,28 @@ mod map {
         bencher
             .with_inputs(|| gen(num_entries))
             .input_counter(divan::counter::BytesCount::of_str)
-            .bench_values(|sample| sample.parse::<toml_old::Value>().unwrap())
+            .bench_values(|sample| sample.parse::<toml_old::Value>().unwrap());
     }
 
     fn gen(num_entries: usize) -> String {
         let mut s = String::new();
         for i in 0..num_entries {
             s += &format!("[header_no_{}]\n", i);
-            s += "entry = 42\n"
+            s += "entry = 42\n";
         }
         s
     }
 }
 
 mod array {
-    use super::*;
+    use super::NUM_ENTRIES;
 
     #[divan::bench(args = NUM_ENTRIES)]
     fn toml_edit(bencher: divan::Bencher, num_entries: usize) {
         bencher
             .with_inputs(|| gen(num_entries))
             .input_counter(divan::counter::BytesCount::of_str)
-            .bench_values(|sample| sample.parse::<toml_edit::DocumentMut>().unwrap())
+            .bench_values(|sample| sample.parse::<toml_edit::DocumentMut>().unwrap());
     }
 
     #[divan::bench(args = NUM_ENTRIES)]
@@ -53,7 +55,7 @@ mod array {
         bencher
             .with_inputs(|| gen(num_entries))
             .input_counter(divan::counter::BytesCount::of_str)
-            .bench_values(|sample| sample.parse::<toml::Table>().unwrap())
+            .bench_values(|sample| sample.parse::<toml::Table>().unwrap());
     }
 
     #[divan::bench(args = NUM_ENTRIES)]
@@ -61,14 +63,14 @@ mod array {
         bencher
             .with_inputs(|| gen(num_entries))
             .input_counter(divan::counter::BytesCount::of_str)
-            .bench_values(|sample| sample.parse::<toml_old::Value>().unwrap())
+            .bench_values(|sample| sample.parse::<toml_old::Value>().unwrap());
     }
 
     fn gen(num_entries: usize) -> String {
         let mut s = String::new();
         for _ in 0..num_entries {
             s += "[[header]]\n";
-            s += "entry = 42\n"
+            s += "entry = 42\n";
         }
         s
     }
diff --git a/crates/benchmarks/examples/bench.rs b/crates/benchmarks/examples/bench.rs
index 0f7dc11c..cadcc7ab 100644
--- a/crates/benchmarks/examples/bench.rs
+++ b/crates/benchmarks/examples/bench.rs
@@ -5,17 +5,17 @@ fn main() -> Result<(), lexopt::Error> {
         Parser::Document => {
             let _doc = CARGO_MANIFEST.parse::<toml_edit::DocumentMut>().unwrap();
             #[cfg(debug_assertions)] // Don't interefere with profiling
-            dbg!(_doc);
+            drop(_doc);
         }
         Parser::De => {
             let _doc = toml::from_str::<manifest::Manifest>(CARGO_MANIFEST).unwrap();
             #[cfg(debug_assertions)] // Don't interefere with profiling
-            dbg!(_doc);
+            drop(_doc);
         }
         Parser::Table => {
             let _doc = CARGO_MANIFEST.parse::<toml::Table>().unwrap();
             #[cfg(debug_assertions)] // Don't interefere with profiling
-            dbg!(_doc);
+            drop(_doc);
         }
     }
     Ok(())
@@ -67,7 +67,7 @@ mod manifest {
 
     #[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
     #[serde(rename_all = "kebab-case")]
-    pub struct Manifest {
+    pub(crate) struct Manifest {
         package: Package,
         #[serde(default)]
         lib: Option<Lib>,
@@ -87,7 +87,7 @@ mod manifest {
 
     #[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
     #[serde(rename_all = "kebab-case")]
-    pub struct Package {
+    pub(crate) struct Package {
         name: String,
         version: String,
         #[serde(default)]
@@ -110,7 +110,7 @@ mod manifest {
 
     #[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
     #[serde(rename_all = "kebab-case")]
-    pub struct Lib {
+    pub(crate) struct Lib {
         name: String,
         #[serde(default)]
         path: Option<String>,
@@ -118,7 +118,7 @@ mod manifest {
 
     #[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
     #[serde(rename_all = "kebab-case")]
-    pub struct Bin {
+    pub(crate) struct Bin {
         name: String,
         #[serde(default)]
         test: bool,
@@ -129,14 +129,14 @@ mod manifest {
     #[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
     #[serde(rename_all = "kebab-case")]
     #[serde(untagged)]
-    pub enum Dependency {
+    pub(crate) enum Dependency {
         Version(String),
         Full(DependencyFull),
     }
 
     #[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
     #[serde(rename_all = "kebab-case")]
-    pub struct DependencyFull {
+    pub(crate) struct DependencyFull {
         #[serde(default)]
         version: Option<String>,
         #[serde(default)]
@@ -151,7 +151,7 @@ mod manifest {
 
     #[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
     #[serde(rename_all = "kebab-case")]
-    pub struct Target {
+    pub(crate) struct Target {
         #[serde(default)]
         dependencies: HashMap<String, Dependency>,
         #[serde(default)]
diff --git a/crates/serde_spanned/Cargo.toml b/crates/serde_spanned/Cargo.toml
index e1ed93da..5190b16b 100644
--- a/crates/serde_spanned/Cargo.toml
+++ b/crates/serde_spanned/Cargo.toml
@@ -32,3 +32,6 @@ serde = "1"
 serde_derive = "1"
 serde-untagged = "0.1"
 toml = { path = "../toml" }
+
+[lints]
+workspace = true
diff --git a/crates/serde_spanned/src/lib.rs b/crates/serde_spanned/src/lib.rs
index 8ff723f4..1d4acb1d 100644
--- a/crates/serde_spanned/src/lib.rs
+++ b/crates/serde_spanned/src/lib.rs
@@ -5,14 +5,15 @@
 //!
 //! [serde]: https://serde.rs/
 
-#![deny(missing_docs)]
-#![warn(rust_2018_idioms)]
+#![cfg_attr(docsrs, feature(doc_auto_cfg))]
+#![warn(missing_docs)]
 // Makes rustc abort compilation if there are any unsafe blocks in the crate.
 // Presence of this annotation is picked up by tools such as cargo-geiger
 // and lets them ensure that there is indeed no unsafe code as opposed to
 // something they couldn't detect (e.g. unsafe added via macro expansion, etc).
 #![forbid(unsafe_code)]
-#![cfg_attr(docsrs, feature(doc_auto_cfg))]
+#![warn(clippy::print_stderr)]
+#![warn(clippy::print_stdout)]
 
 mod spanned;
 pub use crate::spanned::Spanned;
diff --git a/crates/serde_spanned/src/spanned.rs b/crates/serde_spanned/src/spanned.rs
index f4042a86..7db9bced 100644
--- a/crates/serde_spanned/src/spanned.rs
+++ b/crates/serde_spanned/src/spanned.rs
@@ -204,9 +204,10 @@ where
             }
         }
 
+        static FIELDS: [&str; 3] = [START_FIELD, END_FIELD, VALUE_FIELD];
+
         let visitor = SpannedVisitor(::std::marker::PhantomData);
 
-        static FIELDS: [&str; 3] = [START_FIELD, END_FIELD, VALUE_FIELD];
         deserializer.deserialize_struct(NAME, &FIELDS, visitor)
     }
 }
diff --git a/crates/serde_toml/Cargo.toml b/crates/serde_toml/Cargo.toml
index f04d4299..df3c5a19 100644
--- a/crates/serde_toml/Cargo.toml
+++ b/crates/serde_toml/Cargo.toml
@@ -14,3 +14,6 @@ include.workspace = true
 [package.metadata.docs.rs]
 all-features = true
 rustdoc-args = ["--cfg", "docsrs"]
+
+[lints]
+workspace = true
diff --git a/crates/toml/Cargo.toml b/crates/toml/Cargo.toml
index dab14de5..cf603354 100644
--- a/crates/toml/Cargo.toml
+++ b/crates/toml/Cargo.toml
@@ -72,3 +72,6 @@ required-features = ["parse", "display"]
 [[example]]
 name = "toml2json"
 required-features = ["parse", "display"]
+
+[lints]
+workspace = true
diff --git a/crates/toml/examples/toml2json.rs b/crates/toml/examples/toml2json.rs
index 3660611c..56a912c9 100644
--- a/crates/toml/examples/toml2json.rs
+++ b/crates/toml/examples/toml2json.rs
@@ -1,7 +1,4 @@
-#![deny(warnings)]
-
 use std::env;
-use std::fs::File;
 use std::io;
 use std::io::prelude::*;
 
@@ -10,15 +7,14 @@ use toml::Value as Toml;
 
 fn main() {
     let mut args = env::args();
-    let mut input = String::new();
-    if args.len() > 1 {
+    let input = if args.len() > 1 {
         let name = args.nth(1).unwrap();
-        File::open(name)
-            .and_then(|mut f| f.read_to_string(&mut input))
-            .unwrap();
+        std::fs::read_to_string(name).unwrap()
     } else {
+        let mut input = String::new();
         io::stdin().read_to_string(&mut input).unwrap();
-    }
+        input
+    };
 
     match input.parse() {
         Ok(toml) => {
diff --git a/crates/toml/src/de.rs b/crates/toml/src/de.rs
index fae0ed3c..1a0929e8 100644
--- a/crates/toml/src/de.rs
+++ b/crates/toml/src/de.rs
@@ -57,7 +57,7 @@ impl Error {
     }
 
     pub(crate) fn add_key(&mut self, key: String) {
-        self.inner.add_key(key)
+        self.inner.add_key(key);
     }
 
     /// What went wrong
diff --git a/crates/toml/src/lib.rs b/crates/toml/src/lib.rs
index 61e6a4c7..9f59752d 100644
--- a/crates/toml/src/lib.rs
+++ b/crates/toml/src/lib.rs
@@ -140,14 +140,15 @@
 //! [`serde`]: https://serde.rs/
 //! [serde]: https://serde.rs/
 
-#![deny(missing_docs)]
-#![warn(rust_2018_idioms)]
+#![cfg_attr(docsrs, feature(doc_auto_cfg))]
 // Makes rustc abort compilation if there are any unsafe blocks in the crate.
 // Presence of this annotation is picked up by tools such as cargo-geiger
 // and lets them ensure that there is indeed no unsafe code as opposed to
 // something they couldn't detect (e.g. unsafe added via macro expansion, etc).
 #![forbid(unsafe_code)]
-#![cfg_attr(docsrs, feature(doc_auto_cfg))]
+#![warn(missing_docs)]
+#![warn(clippy::print_stderr)]
+#![warn(clippy::print_stdout)]
 
 pub mod map;
 pub mod value;
diff --git a/crates/toml/src/map.rs b/crates/toml/src/map.rs
index bd720a72..26e77160 100644
--- a/crates/toml/src/map.rs
+++ b/crates/toml/src/map.rs
@@ -70,7 +70,7 @@ impl Map<String, Value> {
     /// Clears the map, removing all values.
     #[inline]
     pub fn clear(&mut self) {
-        self.map.clear()
+        self.map.clear();
     }
 
     /// Returns a reference to the value corresponding to the key.
@@ -452,13 +452,13 @@ impl<'a> Entry<'a> {
 
 impl<'a> VacantEntry<'a> {
     /// Gets a reference to the key that would be used when inserting a value
-    /// through the VacantEntry.
+    /// through the `VacantEntry`.
     #[inline]
     pub fn key(&self) -> &String {
         self.vacant.key()
     }
 
-    /// Sets the value of the entry with the VacantEntry's key, and returns a
+    /// Sets the value of the entry with the `VacantEntry`'s key, and returns a
     /// mutable reference to it.
     #[inline]
     pub fn insert(self, value: Value) -> &'a mut Value {
@@ -518,7 +518,7 @@ impl<'a> IntoIterator for &'a Map<String, Value> {
     }
 }
 
-/// An iterator over a toml::Map's entries.
+/// An iterator over a `toml::Map`'s entries.
 pub struct Iter<'a> {
     iter: IterImpl<'a>,
 }
@@ -543,7 +543,7 @@ impl<'a> IntoIterator for &'a mut Map<String, Value> {
     }
 }
 
-/// A mutable iterator over a toml::Map's entries.
+/// A mutable iterator over a `toml::Map`'s entries.
 pub struct IterMut<'a> {
     iter: IterMutImpl<'a>,
 }
@@ -568,7 +568,7 @@ impl IntoIterator for Map<String, Value> {
     }
 }
 
-/// An owning iterator over a toml::Map's entries.
+/// An owning iterator over a `toml::Map`'s entries.
 pub struct IntoIter {
     iter: IntoIterImpl,
 }
@@ -582,7 +582,7 @@ delegate_iterator!((IntoIter) => (String, Value));
 
 //////////////////////////////////////////////////////////////////////////////
 
-/// An iterator over a toml::Map's keys.
+/// An iterator over a `toml::Map`'s keys.
 pub struct Keys<'a> {
     iter: KeysImpl<'a>,
 }
@@ -596,7 +596,7 @@ delegate_iterator!((Keys<'a>) => &'a String);
 
 //////////////////////////////////////////////////////////////////////////////
 
-/// An iterator over a toml::Map's values.
+/// An iterator over a `toml::Map`'s values.
 pub struct Values<'a> {
     iter: ValuesImpl<'a>,
 }
diff --git a/crates/toml/src/ser.rs b/crates/toml/src/ser.rs
index 0406893b..fac18bb8 100644
--- a/crates/toml/src/ser.rs
+++ b/crates/toml/src/ser.rs
@@ -750,11 +750,14 @@ impl<'d> serde::ser::Serializer for ValueSerializer<'d> {
 }
 
 #[cfg(feature = "display")]
-use internal::*;
+use internal::{
+    write_document, write_value, SerializeDocumentArray, SerializeDocumentTable,
+    SerializeValueArray, SerializeValueTable,
+};
 
 #[cfg(feature = "display")]
 mod internal {
-    use super::*;
+    use super::{Error, Serializer, ValueSerializer};
 
     use crate::fmt::DocumentFormatter;
 
@@ -911,6 +914,7 @@ mod internal {
         value: Result<toml_edit::Value, crate::edit::ser::Error>,
     ) -> Result<(), Error> {
         use std::fmt::Write;
+        use toml_edit::visit_mut::VisitMut as _;
 
         let value = value.map_err(Error::wrap)?;
         let mut table = match toml_edit::Item::Value(value).into_table() {
@@ -920,7 +924,6 @@ mod internal {
             }
         };
 
-        use toml_edit::visit_mut::VisitMut as _;
         settings.visit_table_mut(&mut table);
 
         let doc: toml_edit::DocumentMut = table.into();
diff --git a/crates/toml/src/value.rs b/crates/toml/src/value.rs
index e6f832a7..a059b3fb 100644
--- a/crates/toml/src/value.rs
+++ b/crates/toml/src/value.rs
@@ -248,7 +248,7 @@ where
 impl<'a> From<&'a str> for Value {
     #[inline]
     fn from(val: &'a str) -> Value {
-        Value::String(val.to_string())
+        Value::String(val.to_owned())
     }
 }
 
@@ -465,7 +465,7 @@ impl<'de> de::Deserialize<'de> for Value {
             }
 
             fn visit_u64<E: de::Error>(self, value: u64) -> Result<Value, E> {
-                if value <= i64::max_value() as u64 {
+                if i64::try_from(value).is_ok() {
                     Ok(Value::Integer(value as i64))
                 } else {
                     Err(de::Error::custom("u64 value was too large"))
@@ -858,7 +858,7 @@ impl<'de> serde::de::VariantAccess<'de> for MapEnumDeserializer {
     }
 }
 
-impl<'de> de::IntoDeserializer<'de, crate::de::Error> for Value {
+impl<'de> IntoDeserializer<'de, crate::de::Error> for Value {
     type Deserializer = Self;
 
     fn into_deserializer(self) -> Self {
@@ -913,7 +913,7 @@ impl ser::Serializer for ValueSerializer {
     }
 
     fn serialize_u64(self, value: u64) -> Result<Value, crate::ser::Error> {
-        if value <= i64::max_value() as u64 {
+        if i64::try_from(value).is_ok() {
             self.serialize_i64(value as i64)
         } else {
             Err(ser::Error::custom("u64 value was too large"))
@@ -1497,7 +1497,7 @@ impl ValueSerializeVariant<ValueSerializeMap> {
 }
 
 impl serde::ser::SerializeTupleVariant for ValueSerializeVariant<ValueSerializeVec> {
-    type Ok = crate::Value;
+    type Ok = Value;
     type Error = crate::ser::Error;
 
     fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<(), Self::Error>
@@ -1516,7 +1516,7 @@ impl serde::ser::SerializeTupleVariant for ValueSerializeVariant<ValueSerializeV
 }
 
 impl serde::ser::SerializeStructVariant for ValueSerializeVariant<ValueSerializeMap> {
-    type Ok = crate::Value;
+    type Ok = Value;
     type Error = crate::ser::Error;
 
     #[inline]
diff --git a/crates/toml_datetime/Cargo.toml b/crates/toml_datetime/Cargo.toml
index 45da49b5..47c8b431 100644
--- a/crates/toml_datetime/Cargo.toml
+++ b/crates/toml_datetime/Cargo.toml
@@ -27,3 +27,6 @@ pre-release-replacements = [
 
 [dependencies]
 serde = { version = "1.0.145", optional = true }
+
+[lints]
+workspace = true
diff --git a/crates/toml_datetime/src/datetime.rs b/crates/toml_datetime/src/datetime.rs
index 1b37c700..479c59fa 100644
--- a/crates/toml_datetime/src/datetime.rs
+++ b/crates/toml_datetime/src/datetime.rs
@@ -357,6 +357,7 @@ impl FromStr for Datetime {
 
                 let mut end = whole.len();
                 for (i, byte) in whole.bytes().enumerate() {
+                    #[allow(clippy::single_match_else)]
                     match byte {
                         b'0'..=b'9' => {
                             if i < 9 {
diff --git a/crates/toml_datetime/src/lib.rs b/crates/toml_datetime/src/lib.rs
index 4df40dca..14cac557 100644
--- a/crates/toml_datetime/src/lib.rs
+++ b/crates/toml_datetime/src/lib.rs
@@ -2,14 +2,15 @@
 //!
 //! [TOML]: https://github.com/toml-lang/toml
 
-#![deny(missing_docs)]
-#![warn(rust_2018_idioms)]
+#![cfg_attr(docsrs, feature(doc_auto_cfg))]
+#![warn(missing_docs)]
 // Makes rustc abort compilation if there are any unsafe blocks in the crate.
 // Presence of this annotation is picked up by tools such as cargo-geiger
 // and lets them ensure that there is indeed no unsafe code as opposed to
 // something they couldn't detect (e.g. unsafe added via macro expansion, etc).
 #![forbid(unsafe_code)]
-#![cfg_attr(docsrs, feature(doc_auto_cfg))]
+#![warn(clippy::print_stderr)]
+#![warn(clippy::print_stdout)]
 
 mod datetime;
 
diff --git a/crates/toml_edit/Cargo.toml b/crates/toml_edit/Cargo.toml
index 159463e0..fa40c5cb 100644
--- a/crates/toml_edit/Cargo.toml
+++ b/crates/toml_edit/Cargo.toml
@@ -70,10 +70,13 @@ harness = false
 
 [[test]]
 name = "invalid"
-required-features = ["parse"]
+required-features = ["parse", "display"]
 harness = false
 
 [[example]]
 name = "visit"
 required-features = ["parse", "display"]
 test = true
+
+[lints]
+workspace = true
diff --git a/crates/toml_edit/examples/visit.rs b/crates/toml_edit/examples/visit.rs
index 13024c2f..3f523346 100644
--- a/crates/toml_edit/examples/visit.rs
+++ b/crates/toml_edit/examples/visit.rs
@@ -1,8 +1,8 @@
 //! Example for how to use `VisitMut` to iterate over a table.
 
 use std::collections::BTreeSet;
-use toml_edit::visit::*;
-use toml_edit::visit_mut::*;
+use toml_edit::visit::{visit_table_like_kv, Visit};
+use toml_edit::visit_mut::{visit_table_like_kv_mut, visit_table_mut, VisitMut};
 use toml_edit::{Array, DocumentMut, InlineTable, Item, KeyMut, Table, Value};
 
 /// This models the visit state for dependency keys in a `Cargo.toml`.
@@ -159,7 +159,7 @@ impl VisitMut for NormalizeDependencyTablesVisitor {
     }
 }
 
-/// This is the input provided to visit_mut_example.
+/// This is the input provided to `visit_mut_example`.
 static INPUT: &str = r#"
 [package]
 name = "my-package"
@@ -195,7 +195,7 @@ path = "crates/cargo-test-macro"
 version = "0.4"
 "#;
 
-/// This is the output produced by visit_mut_example.
+/// This is the output produced by `visit_mut_example`.
 #[cfg(test)]
 static VISIT_MUT_OUTPUT: &str = r#"
 [package]
diff --git a/crates/toml_edit/src/array.rs b/crates/toml_edit/src/array.rs
index 4e3d4704..c1acf0bc 100644
--- a/crates/toml_edit/src/array.rs
+++ b/crates/toml_edit/src/array.rs
@@ -150,7 +150,7 @@ impl Array {
 
     /// Clears the array, removing all values. Keeps the allocated memory for reuse.
     pub fn clear(&mut self) {
-        self.values.clear()
+        self.values.clear();
     }
 
     /// Returns a reference to the value at the given index, or `None` if the index is out of
@@ -176,8 +176,8 @@ impl Array {
     /// ```
     pub fn push<V: Into<Value>>(&mut self, v: V) {
         self.value_op(v.into(), true, |items, value| {
-            items.push(Item::Value(value))
-        })
+            items.push(Item::Value(value));
+        });
     }
 
     /// Appends a new, already formatted value to the end of the array.
@@ -213,8 +213,8 @@ impl Array {
     /// ```
     pub fn insert<V: Into<Value>>(&mut self, index: usize, v: V) {
         self.value_op(v.into(), true, |items, value| {
-            items.insert(index, Item::Value(value))
-        })
+            items.insert(index, Item::Value(value));
+        });
     }
 
     /// Inserts an already formatted value at the given position within the array, shifting all
@@ -237,7 +237,7 @@ impl Array {
     /// # }
     /// ```
     pub fn insert_formatted(&mut self, index: usize, v: Value) {
-        self.values.insert(index, Item::Value(v))
+        self.values.insert(index, Item::Value(v));
     }
 
     /// Replaces the element at the given position within the array, preserving existing formatting.
@@ -352,7 +352,7 @@ impl Array {
                 (None, Some(_)) => std::cmp::Ordering::Less,
                 (Some(lhs), Some(rhs)) => compare(lhs, rhs),
             }
-        })
+        });
     }
 
     /// Sorts the array with a key extraction function.
diff --git a/crates/toml_edit/src/array_of_tables.rs b/crates/toml_edit/src/array_of_tables.rs
index bbc4c7d5..83a4ae71 100644
--- a/crates/toml_edit/src/array_of_tables.rs
+++ b/crates/toml_edit/src/array_of_tables.rs
@@ -71,7 +71,7 @@ impl ArrayOfTables {
 
     /// Removes all the tables.
     pub fn clear(&mut self) {
-        self.values.clear()
+        self.values.clear();
     }
 
     /// Returns an optional reference to the table.
diff --git a/crates/toml_edit/src/de/array.rs b/crates/toml_edit/src/de/array.rs
index adc54016..eeedd7ba 100644
--- a/crates/toml_edit/src/de/array.rs
+++ b/crates/toml_edit/src/de/array.rs
@@ -48,7 +48,7 @@ impl<'de> serde::Deserializer<'de> for ArrayDeserializer {
     }
 }
 
-impl<'de> serde::de::IntoDeserializer<'de, crate::de::Error> for ArrayDeserializer {
+impl<'de> serde::de::IntoDeserializer<'de, Error> for ArrayDeserializer {
     type Deserializer = Self;
 
     fn into_deserializer(self) -> Self::Deserializer {
diff --git a/crates/toml_edit/src/de/key.rs b/crates/toml_edit/src/de/key.rs
index a3b28256..d7ce30e4 100644
--- a/crates/toml_edit/src/de/key.rs
+++ b/crates/toml_edit/src/de/key.rs
@@ -13,7 +13,7 @@ impl KeyDeserializer {
     }
 }
 
-impl<'de> serde::de::IntoDeserializer<'de, Error> for KeyDeserializer {
+impl<'de> IntoDeserializer<'de, Error> for KeyDeserializer {
     type Deserializer = Self;
 
     fn into_deserializer(self) -> Self::Deserializer {
@@ -81,7 +81,7 @@ impl<'de> serde::de::Deserializer<'de> for KeyDeserializer {
 }
 
 impl<'de> serde::de::EnumAccess<'de> for KeyDeserializer {
-    type Error = super::Error;
+    type Error = Error;
     type Variant = UnitOnly<Self::Error>;
 
     fn variant_seed<T>(self, seed: T) -> Result<(T::Value, Self::Variant), Self::Error>
diff --git a/crates/toml_edit/src/de/mod.rs b/crates/toml_edit/src/de/mod.rs
index 739f8392..6638274b 100644
--- a/crates/toml_edit/src/de/mod.rs
+++ b/crates/toml_edit/src/de/mod.rs
@@ -39,7 +39,7 @@ impl Error {
 
     /// Add key while unwinding
     pub fn add_key(&mut self, key: String) {
-        self.inner.add_key(key)
+        self.inner.add_key(key);
     }
 
     /// What went wrong
@@ -67,7 +67,7 @@ impl serde::de::Error for Error {
 }
 
 impl std::fmt::Display for Error {
-    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
         self.inner.fmt(f)
     }
 }
@@ -106,7 +106,7 @@ where
     from_str(s)
 }
 
-/// Convert a [DocumentMut][crate::DocumentMut] into `T`.
+/// Convert a [`DocumentMut`][crate::DocumentMut] into `T`.
 pub fn from_document<T>(d: impl Into<Deserializer>) -> Result<T, Error>
 where
     T: DeserializeOwned,
@@ -264,7 +264,7 @@ impl<'de, S: Into<String>> serde::Deserializer<'de> for Deserializer<S> {
     }
 }
 
-impl<'de> serde::de::IntoDeserializer<'de, crate::de::Error> for Deserializer {
+impl<'de> serde::de::IntoDeserializer<'de, Error> for Deserializer {
     type Deserializer = Deserializer;
 
     fn into_deserializer(self) -> Self::Deserializer {
@@ -272,7 +272,7 @@ impl<'de> serde::de::IntoDeserializer<'de, crate::de::Error> for Deserializer {
     }
 }
 
-impl<'de> serde::de::IntoDeserializer<'de, crate::de::Error> for crate::DocumentMut {
+impl<'de> serde::de::IntoDeserializer<'de, Error> for crate::DocumentMut {
     type Deserializer = Deserializer;
 
     fn into_deserializer(self) -> Self::Deserializer {
@@ -280,7 +280,7 @@ impl<'de> serde::de::IntoDeserializer<'de, crate::de::Error> for crate::Document
     }
 }
 
-impl<'de> serde::de::IntoDeserializer<'de, crate::de::Error> for crate::ImDocument<String> {
+impl<'de> serde::de::IntoDeserializer<'de, Error> for crate::ImDocument<String> {
     type Deserializer = Deserializer;
 
     fn into_deserializer(self) -> Self::Deserializer {
diff --git a/crates/toml_edit/src/de/table.rs b/crates/toml_edit/src/de/table.rs
index 33aa3970..de8389c5 100644
--- a/crates/toml_edit/src/de/table.rs
+++ b/crates/toml_edit/src/de/table.rs
@@ -89,7 +89,7 @@ impl<'de> serde::Deserializer<'de> for TableDeserializer {
     }
 }
 
-impl<'de> serde::de::IntoDeserializer<'de, crate::de::Error> for TableDeserializer {
+impl<'de> IntoDeserializer<'de, Error> for TableDeserializer {
     type Deserializer = TableDeserializer;
 
     fn into_deserializer(self) -> Self::Deserializer {
diff --git a/crates/toml_edit/src/de/value.rs b/crates/toml_edit/src/de/value.rs
index ba6ce6db..28671f98 100644
--- a/crates/toml_edit/src/de/value.rs
+++ b/crates/toml_edit/src/de/value.rs
@@ -11,6 +11,8 @@ use crate::de::Error;
 /// # Example
 ///
 /// ```
+/// # #[cfg(feature = "parse")] {
+/// # #[cfg(feature = "display")] {
 /// use serde::Deserialize;
 ///
 /// #[derive(Deserialize)]
@@ -29,6 +31,8 @@ use crate::de::Error;
 /// let config = Config::deserialize(deserializer).unwrap();
 /// assert_eq!(config.title, "TOML Example");
 /// assert_eq!(config.owner.name, "Lisa");
+/// # }
+/// # }
 /// ```
 pub struct ValueDeserializer {
     input: crate::Item,
@@ -162,7 +166,7 @@ impl<'de> serde::Deserializer<'de> for ValueDeserializer {
                     e.set_span(span);
                 }
                 e
-            })?
+            })?;
         }
 
         self.deserialize_any(visitor)
@@ -219,7 +223,7 @@ impl<'de> serde::Deserializer<'de> for ValueDeserializer {
     }
 }
 
-impl<'de> serde::de::IntoDeserializer<'de, crate::de::Error> for ValueDeserializer {
+impl<'de> serde::de::IntoDeserializer<'de, Error> for ValueDeserializer {
     type Deserializer = Self;
 
     fn into_deserializer(self) -> Self::Deserializer {
@@ -227,7 +231,7 @@ impl<'de> serde::de::IntoDeserializer<'de, crate::de::Error> for ValueDeserializ
     }
 }
 
-impl<'de> serde::de::IntoDeserializer<'de, crate::de::Error> for crate::Value {
+impl<'de> serde::de::IntoDeserializer<'de, Error> for crate::Value {
     type Deserializer = ValueDeserializer;
 
     fn into_deserializer(self) -> Self::Deserializer {
diff --git a/crates/toml_edit/src/encode.rs b/crates/toml_edit/src/encode.rs
index da8f1e24..b8c1c048 100644
--- a/crates/toml_edit/src/encode.rs
+++ b/crates/toml_edit/src/encode.rs
@@ -1,7 +1,7 @@
 use std::borrow::Cow;
 use std::fmt::{Display, Formatter, Result, Write};
 
-use toml_datetime::*;
+use toml_datetime::Datetime;
 
 use crate::inline_table::DEFAULT_INLINE_KEY_DECOR;
 use crate::key::Key;
@@ -347,7 +347,7 @@ pub(crate) fn to_string_repr(
                 '\u{a}' => match style {
                     StringStyle::NewlineTriple => output.push('\n'),
                     StringStyle::OnelineSingle => output.push_str("\\n"),
-                    _ => unreachable!(),
+                    StringStyle::OnelineTriple => unreachable!(),
                 },
                 '\u{c}' => output.push_str("\\f"),
                 '\u{d}' => output.push_str("\\r"),
@@ -435,7 +435,7 @@ fn infer_style(value: &str) -> (StringStyle, bool) {
                 if found_singles > max_found_singles {
                     max_found_singles = found_singles;
                 }
-                found_singles = 0
+                found_singles = 0;
             }
             match ch {
                 '\t' => {}
diff --git a/crates/toml_edit/src/inline_table.rs b/crates/toml_edit/src/inline_table.rs
index f7f6465b..6e713241 100644
--- a/crates/toml_edit/src/inline_table.rs
+++ b/crates/toml_edit/src/inline_table.rs
@@ -270,7 +270,7 @@ impl InlineTable {
 
     /// Clears the table, removing all key-value pairs. Keeps the allocated memory for reuse.
     pub fn clear(&mut self) {
-        self.items.clear()
+        self.items.clear();
     }
 
     /// Gets the given key's corresponding entry in the Table for in-place manipulation.
@@ -568,13 +568,13 @@ impl TableLike for InlineTable {
         self.get_values()
     }
     fn fmt(&mut self) {
-        self.fmt()
+        self.fmt();
     }
     fn sort_values(&mut self) {
-        self.sort_values()
+        self.sort_values();
     }
     fn set_dotted(&mut self, yes: bool) {
-        self.set_dotted(yes)
+        self.set_dotted(yes);
     }
     fn is_dotted(&self) -> bool {
         self.is_dotted()
@@ -681,7 +681,7 @@ impl<'a> InlineOccupiedEntry<'a> {
         self.entry.get_mut().value.as_value_mut().unwrap()
     }
 
-    /// Converts the OccupiedEntry into a mutable reference to the value in the entry
+    /// Converts the `OccupiedEntry` into a mutable reference to the value in the entry
     /// with a lifetime bound to the map itself
     pub fn into_mut(self) -> &'a mut Value {
         self.entry.into_mut().value.as_value_mut().unwrap()
@@ -722,7 +722,7 @@ impl<'a> InlineVacantEntry<'a> {
         self.entry.key().as_str()
     }
 
-    /// Sets the value of the entry with the VacantEntry's key,
+    /// Sets the value of the entry with the `VacantEntry`'s key,
     /// and returns a mutable reference to it
     pub fn insert(self, value: Value) -> &'a mut Value {
         let entry = self.entry;
diff --git a/crates/toml_edit/src/item.rs b/crates/toml_edit/src/item.rs
index 2d30655f..b161e8ae 100644
--- a/crates/toml_edit/src/item.rs
+++ b/crates/toml_edit/src/item.rs
@@ -1,6 +1,6 @@
 use std::str::FromStr;
 
-use toml_datetime::*;
+use toml_datetime::Datetime;
 
 use crate::array_of_tables::ArrayOfTables;
 use crate::table::TableLike;
@@ -25,7 +25,7 @@ impl Item {
     /// returns a mutable reference to `self`.
     pub fn or_insert(&mut self, item: Item) -> &mut Item {
         if self.is_none() {
-            *self = item
+            *self = item;
         }
         self
     }
@@ -363,6 +363,7 @@ impl std::fmt::Display for Item {
 /// # Examples
 /// ```rust
 /// # #[cfg(feature = "display")] {
+/// # #[cfg(feature = "parse")] {
 /// # use snapbox::assert_eq;
 /// # use toml_edit::*;
 /// let mut table = Table::default();
@@ -378,6 +379,7 @@ impl std::fmt::Display for Item {
 /// key3 = ["hello", '\, world']
 /// "#);
 /// # }
+/// # }
 /// ```
 pub fn value<V: Into<Value>>(v: V) -> Item {
     Item::Value(v.into())
diff --git a/crates/toml_edit/src/key.rs b/crates/toml_edit/src/key.rs
index 64a9f2a6..0fc793a0 100644
--- a/crates/toml_edit/src/key.rs
+++ b/crates/toml_edit/src/key.rs
@@ -158,7 +158,7 @@ impl Key {
         self.leaf_decor.despan(input);
         self.dotted_decor.despan(input);
         if let Some(repr) = &mut self.repr {
-            repr.despan(input)
+            repr.despan(input);
         }
     }
 
@@ -359,7 +359,7 @@ impl<'k> KeyMut<'k> {
 
     /// Returns a raw representation.
     #[cfg(feature = "display")]
-    pub fn display_repr(&self) -> Cow<str> {
+    pub fn display_repr(&self) -> Cow<'_, str> {
         self.key.display_repr()
     }
 
@@ -402,7 +402,7 @@ impl<'k> KeyMut<'k> {
 
     /// Auto formats the key.
     pub fn fmt(&mut self) {
-        self.key.fmt()
+        self.key.fmt();
     }
 }
 
diff --git a/crates/toml_edit/src/lib.rs b/crates/toml_edit/src/lib.rs
index 15c9fc24..c47b902a 100644
--- a/crates/toml_edit/src/lib.rs
+++ b/crates/toml_edit/src/lib.rs
@@ -1,8 +1,3 @@
-#![deny(missing_docs)]
-// https://github.com/Marwes/combine/issues/172
-#![recursion_limit = "256"]
-#![cfg_attr(docsrs, feature(doc_auto_cfg))]
-
 //! # `toml_edit`
 //!
 //! This crate allows you to parse and modify toml
@@ -43,23 +38,27 @@
 //! By default, values are created with default formatting
 //! ```rust
 //! # #[cfg(feature = "display")] {
+//! # #[cfg(feature = "parse")] {
 //! let mut doc = toml_edit::DocumentMut::new();
 //! doc["foo"] = toml_edit::value("bar");
 //! let expected = r#"foo = "bar"
 //! "#;
 //! assert_eq!(doc.to_string(), expected);
 //! # }
+//! # }
 //! ```
 //!
 //! You can choose a custom TOML representation by parsing the value.
 //! ```rust
 //! # #[cfg(feature = "display")] {
+//! # #[cfg(feature = "parse")] {
 //! let mut doc = toml_edit::DocumentMut::new();
 //! doc["foo"] = "'bar'".parse::<toml_edit::Item>().unwrap();
 //! let expected = r#"foo = 'bar'
 //! "#;
 //! assert_eq!(doc.to_string(), expected);
 //! # }
+//! # }
 //! ```
 //!
 //! ## Limitations
@@ -70,6 +69,13 @@
 //!
 //! [`toml`]: https://docs.rs/toml/latest/toml/
 
+// https://github.com/Marwes/combine/issues/172
+#![recursion_limit = "256"]
+#![cfg_attr(docsrs, feature(doc_auto_cfg))]
+#![warn(missing_docs)]
+#![warn(clippy::print_stderr)]
+#![warn(clippy::print_stdout)]
+
 mod array;
 mod array_of_tables;
 mod document;
diff --git a/crates/toml_edit/src/parser/datetime.rs b/crates/toml_edit/src/parser/datetime.rs
index 86c5a5bc..69c8d7f3 100644
--- a/crates/toml_edit/src/parser/datetime.rs
+++ b/crates/toml_edit/src/parser/datetime.rs
@@ -4,7 +4,7 @@ use crate::parser::error::CustomError;
 use crate::parser::prelude::*;
 use crate::parser::trivia::from_utf8_unchecked;
 
-use toml_datetime::*;
+use toml_datetime::{Date, Datetime, Offset, Time};
 use winnow::combinator::alt;
 use winnow::combinator::cut_err;
 use winnow::combinator::opt;
diff --git a/crates/toml_edit/src/parser/mod.rs b/crates/toml_edit/src/parser/mod.rs
index f1bbc56a..47f57532 100644
--- a/crates/toml_edit/src/parser/mod.rs
+++ b/crates/toml_edit/src/parser/mod.rs
@@ -14,7 +14,7 @@ pub(crate) mod table;
 pub(crate) mod trivia;
 pub(crate) mod value;
 
-pub use crate::error::TomlError;
+pub(crate) use crate::error::TomlError;
 
 pub(crate) fn parse_document<S: AsRef<str>>(raw: S) -> Result<crate::ImDocument<S>, TomlError> {
     use prelude::*;
@@ -99,7 +99,7 @@ pub(crate) mod prelude {
     }
 
     #[cfg(not(feature = "unbounded"))]
-    const LIMIT: usize = 100;
+    const LIMIT: usize = 80;
 
     #[cfg(not(feature = "unbounded"))]
     impl RecursionCheck {
diff --git a/crates/toml_edit/src/parser/state.rs b/crates/toml_edit/src/parser/state.rs
index 308c87e1..2513634a 100644
--- a/crates/toml_edit/src/parser/state.rs
+++ b/crates/toml_edit/src/parser/state.rs
@@ -265,7 +265,7 @@ impl ParseState {
                     }
                     table = sweet_child_of_mine;
                 }
-                _ => unreachable!(),
+                Item::None => unreachable!(),
             }
         }
         Ok(table)
diff --git a/crates/toml_edit/src/parser/strings.rs b/crates/toml_edit/src/parser/strings.rs
index 6223e706..0478faa8 100644
--- a/crates/toml_edit/src/parser/strings.rs
+++ b/crates/toml_edit/src/parser/strings.rs
@@ -212,7 +212,7 @@ fn mlb_content<'i>(input: &mut Input<'i>) -> PResult<Cow<'i, str>> {
 
 // mlb-quotes = 1*2quotation-mark
 fn mlb_quotes<'i>(
-    mut term: impl winnow::Parser<Input<'i>, (), ContextError>,
+    mut term: impl Parser<Input<'i>, (), ContextError>,
 ) -> impl Parser<Input<'i>, &'i str, ContextError> {
     move |input: &mut Input<'i>| {
         let start = input.checkpoint();
@@ -341,7 +341,7 @@ const MLL_CHAR: (
 
 // mll-quotes = 1*2apostrophe
 fn mll_quotes<'i>(
-    mut term: impl winnow::Parser<Input<'i>, (), ContextError>,
+    mut term: impl Parser<Input<'i>, (), ContextError>,
 ) -> impl Parser<Input<'i>, &'i str, ContextError> {
     move |input: &mut Input<'i>| {
         let start = input.checkpoint();
diff --git a/crates/toml_edit/src/parser/trivia.rs b/crates/toml_edit/src/parser/trivia.rs
index 8d903a56..c62e2dec 100644
--- a/crates/toml_edit/src/parser/trivia.rs
+++ b/crates/toml_edit/src/parser/trivia.rs
@@ -15,11 +15,13 @@ pub(crate) unsafe fn from_utf8_unchecked<'b>(
     bytes: &'b [u8],
     safety_justification: &'static str,
 ) -> &'b str {
-    if cfg!(debug_assertions) {
-        // Catch problems more quickly when testing
-        std::str::from_utf8(bytes).expect(safety_justification)
-    } else {
-        std::str::from_utf8_unchecked(bytes)
+    unsafe {
+        if cfg!(debug_assertions) {
+            // Catch problems more quickly when testing
+            std::str::from_utf8(bytes).expect(safety_justification)
+        } else {
+            std::str::from_utf8_unchecked(bytes)
+        }
     }
 }
 
diff --git a/crates/toml_edit/src/parser/value.rs b/crates/toml_edit/src/parser/value.rs
index 33300ec4..f050882a 100644
--- a/crates/toml_edit/src/parser/value.rs
+++ b/crates/toml_edit/src/parser/value.rs
@@ -15,7 +15,7 @@ use crate::RawString;
 use crate::Value;
 
 // val = string / boolean / array / inline-table / date-time / float / integer
-pub(crate) fn value<'i>(check: RecursionCheck) -> impl Parser<Input<'i>, v::Value, ContextError> {
+pub(crate) fn value<'i>(check: RecursionCheck) -> impl Parser<Input<'i>, Value, ContextError> {
     move |input: &mut Input<'i>| {
         dispatch!{peek(any);
             crate::parser::strings::QUOTATION_MARK |
diff --git a/crates/toml_edit/src/raw_string.rs b/crates/toml_edit/src/raw_string.rs
index 1db73c3d..0bde3b78 100644
--- a/crates/toml_edit/src/raw_string.rs
+++ b/crates/toml_edit/src/raw_string.rs
@@ -79,7 +79,7 @@ impl RawString {
             RawStringInner::Spanned(span) => {
                 *self = Self::from(input.get(span.clone()).unwrap_or_else(|| {
                     panic!("span {:?} should be in input:\n```\n{}\n```", span, input)
-                }))
+                }));
             }
         }
     }
diff --git a/crates/toml_edit/src/repr.rs b/crates/toml_edit/src/repr.rs
index 3ae18b48..80d78c38 100644
--- a/crates/toml_edit/src/repr.rs
+++ b/crates/toml_edit/src/repr.rs
@@ -51,7 +51,7 @@ where
 
     /// Returns a raw representation.
     #[cfg(feature = "display")]
-    pub fn display_repr(&self) -> Cow<str> {
+    pub fn display_repr(&self) -> Cow<'_, str> {
         self.as_repr()
             .and_then(|r| r.as_raw().as_str())
             .map(Cow::Borrowed)
@@ -160,7 +160,7 @@ impl Repr {
     }
 
     pub(crate) fn despan(&mut self, input: &str) {
-        self.raw_value.despan(input)
+        self.raw_value.despan(input);
     }
 
     #[cfg(feature = "display")]
diff --git a/crates/toml_edit/src/ser/map.rs b/crates/toml_edit/src/ser/map.rs
index 47e56ba4..1d1d8e05 100644
--- a/crates/toml_edit/src/ser/map.rs
+++ b/crates/toml_edit/src/ser/map.rs
@@ -419,13 +419,13 @@ impl MapValueSerializer {
 impl serde::ser::Serializer for &mut MapValueSerializer {
     type Ok = crate::Value;
     type Error = Error;
-    type SerializeSeq = super::SerializeValueArray;
-    type SerializeTuple = super::SerializeValueArray;
-    type SerializeTupleStruct = super::SerializeValueArray;
-    type SerializeTupleVariant = super::SerializeTupleVariant;
-    type SerializeMap = super::SerializeMap;
-    type SerializeStruct = super::SerializeMap;
-    type SerializeStructVariant = super::SerializeStructVariant;
+    type SerializeSeq = SerializeValueArray;
+    type SerializeTuple = SerializeValueArray;
+    type SerializeTupleStruct = SerializeValueArray;
+    type SerializeTupleVariant = SerializeTupleVariant;
+    type SerializeMap = SerializeMap;
+    type SerializeStruct = SerializeMap;
+    type SerializeStructVariant = SerializeStructVariant;
 
     fn serialize_bool(self, v: bool) -> Result<Self::Ok, Self::Error> {
         ValueSerializer::new().serialize_bool(v)
@@ -585,8 +585,8 @@ impl serde::ser::Serializer for &mut MapValueSerializer {
     }
 }
 
-pub type SerializeTupleVariant = SerializeVariant<SerializeValueArray>;
-pub type SerializeStructVariant = SerializeVariant<SerializeMap>;
+pub(crate) type SerializeTupleVariant = SerializeVariant<SerializeValueArray>;
+pub(crate) type SerializeStructVariant = SerializeVariant<SerializeMap>;
 
 pub struct SerializeVariant<T> {
     variant: &'static str,
diff --git a/crates/toml_edit/src/ser/mod.rs b/crates/toml_edit/src/ser/mod.rs
index c6566d0b..7a3c4086 100644
--- a/crates/toml_edit/src/ser/mod.rs
+++ b/crates/toml_edit/src/ser/mod.rs
@@ -51,7 +51,7 @@ impl serde::ser::Error for Error {
 }
 
 impl std::fmt::Display for Error {
-    fn fmt(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
+    fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
         match self {
             Self::UnsupportedType(Some(t)) => write!(formatter, "unsupported {t} type"),
             Self::UnsupportedType(None) => write!(formatter, "unsupported rust type"),
diff --git a/crates/toml_edit/src/ser/value.rs b/crates/toml_edit/src/ser/value.rs
index 47a17a3b..06c8ca6a 100644
--- a/crates/toml_edit/src/ser/value.rs
+++ b/crates/toml_edit/src/ser/value.rs
@@ -13,6 +13,8 @@ use super::Error;
 /// # Examples
 ///
 /// ```
+/// # #[cfg(feature = "parse")] {
+/// # #[cfg(feature = "display")] {
 /// use serde::Serialize;
 ///
 /// #[derive(Serialize)]
@@ -42,6 +44,8 @@ use super::Error;
 ///     toml_edit::ser::ValueSerializer::new()
 /// ).unwrap();
 /// println!("{}", value)
+/// # }
+/// # }
 /// ```
 #[derive(Default)]
 #[non_exhaustive]
diff --git a/crates/toml_edit/src/table.rs b/crates/toml_edit/src/table.rs
index 8c890e29..2b52aec7 100644
--- a/crates/toml_edit/src/table.rs
+++ b/crates/toml_edit/src/table.rs
@@ -292,7 +292,7 @@ impl Table {
 
     /// Clears the table, removing all key-value pairs. Keeps the allocated memory for reuse.
     pub fn clear(&mut self) {
-        self.items.clear()
+        self.items.clear();
     }
 
     /// Gets the given key's corresponding entry in the Table for in-place manipulation.
@@ -632,16 +632,16 @@ impl TableLike for Table {
         self.get_values()
     }
     fn fmt(&mut self) {
-        self.fmt()
+        self.fmt();
     }
     fn sort_values(&mut self) {
-        self.sort_values()
+        self.sort_values();
     }
     fn is_dotted(&self) -> bool {
         self.is_dotted()
     }
     fn set_dotted(&mut self, yes: bool) {
-        self.set_dotted(yes)
+        self.set_dotted(yes);
     }
 
     fn key(&self, key: &str) -> Option<&'_ Key> {
@@ -742,7 +742,7 @@ impl<'a> OccupiedEntry<'a> {
         &mut self.entry.get_mut().value
     }
 
-    /// Converts the OccupiedEntry into a mutable reference to the value in the entry
+    /// Converts the `OccupiedEntry` into a mutable reference to the value in the entry
     /// with a lifetime bound to the map itself
     pub fn into_mut(self) -> &'a mut Item {
         &mut self.entry.into_mut().value
@@ -782,7 +782,7 @@ impl<'a> VacantEntry<'a> {
         self.entry.key().as_str()
     }
 
-    /// Sets the value of the entry with the VacantEntry's key,
+    /// Sets the value of the entry with the `VacantEntry`'s key,
     /// and returns a mutable reference to it
     pub fn insert(self, value: Item) -> &'a mut Item {
         let entry = self.entry;
diff --git a/crates/toml_edit/src/value.rs b/crates/toml_edit/src/value.rs
index 07d4ab63..b9232631 100644
--- a/crates/toml_edit/src/value.rs
+++ b/crates/toml_edit/src/value.rs
@@ -1,7 +1,7 @@
 use std::iter::FromIterator;
 use std::str::FromStr;
 
-use toml_datetime::*;
+use toml_datetime::{Date, Datetime, Time};
 
 use crate::key::Key;
 use crate::repr::{Decor, Formatted};
@@ -373,7 +373,7 @@ mod tests {
 
     #[test]
     fn from_iter_formatting() {
-        let features = vec!["node".to_owned(), "mouth".to_owned()];
+        let features = ["node".to_owned(), "mouth".to_owned()];
         let features: Value = features.iter().cloned().collect();
         assert_eq!(features.to_string(), r#"["node", "mouth"]"#);
     }
diff --git a/crates/toml_edit/src/visit.rs b/crates/toml_edit/src/visit.rs
index 98ffe864..ee8c9f98 100644
--- a/crates/toml_edit/src/visit.rs
+++ b/crates/toml_edit/src/visit.rs
@@ -96,7 +96,7 @@ pub trait Visit<'doc> {
     }
 
     fn visit_inline_table(&mut self, node: &'doc InlineTable) {
-        visit_inline_table(self, node)
+        visit_inline_table(self, node);
     }
 
     fn visit_table_like(&mut self, node: &'doc dyn TableLike) {
@@ -120,7 +120,7 @@ pub trait Visit<'doc> {
     }
 
     fn visit_boolean(&mut self, node: &'doc Formatted<bool>) {
-        visit_boolean(self, node)
+        visit_boolean(self, node);
     }
 
     fn visit_datetime(&mut self, node: &'doc Formatted<Datetime>) {
@@ -128,15 +128,15 @@ pub trait Visit<'doc> {
     }
 
     fn visit_float(&mut self, node: &'doc Formatted<f64>) {
-        visit_float(self, node)
+        visit_float(self, node);
     }
 
     fn visit_integer(&mut self, node: &'doc Formatted<i64>) {
-        visit_integer(self, node)
+        visit_integer(self, node);
     }
 
     fn visit_string(&mut self, node: &'doc Formatted<String>) {
-        visit_string(self, node)
+        visit_string(self, node);
     }
 }
 
@@ -163,14 +163,14 @@ pub fn visit_table<'doc, V>(v: &mut V, node: &'doc Table)
 where
     V: Visit<'doc> + ?Sized,
 {
-    v.visit_table_like(node)
+    v.visit_table_like(node);
 }
 
 pub fn visit_inline_table<'doc, V>(v: &mut V, node: &'doc InlineTable)
 where
     V: Visit<'doc> + ?Sized,
 {
-    v.visit_table_like(node)
+    v.visit_table_like(node);
 }
 
 pub fn visit_table_like<'doc, V>(v: &mut V, node: &'doc dyn TableLike)
@@ -178,7 +178,7 @@ where
     V: Visit<'doc> + ?Sized,
 {
     for (key, item) in node.iter() {
-        v.visit_table_like_kv(key, item)
+        v.visit_table_like_kv(key, item);
     }
 }
 
@@ -186,7 +186,7 @@ pub fn visit_table_like_kv<'doc, V>(v: &mut V, _key: &'doc str, node: &'doc Item
 where
     V: Visit<'doc> + ?Sized,
 {
-    v.visit_item(node)
+    v.visit_item(node);
 }
 
 pub fn visit_array<'doc, V>(v: &mut V, node: &'doc Array)
diff --git a/crates/toml_edit/src/visit_mut.rs b/crates/toml_edit/src/visit_mut.rs
index 1968477a..ebaf1e5e 100644
--- a/crates/toml_edit/src/visit_mut.rs
+++ b/crates/toml_edit/src/visit_mut.rs
@@ -111,7 +111,7 @@ pub trait VisitMut {
     }
 
     fn visit_inline_table_mut(&mut self, node: &mut InlineTable) {
-        visit_inline_table_mut(self, node)
+        visit_inline_table_mut(self, node);
     }
 
     /// [`visit_table_mut`](Self::visit_table_mut) and
@@ -137,7 +137,7 @@ pub trait VisitMut {
     }
 
     fn visit_boolean_mut(&mut self, node: &mut Formatted<bool>) {
-        visit_boolean_mut(self, node)
+        visit_boolean_mut(self, node);
     }
 
     fn visit_datetime_mut(&mut self, node: &mut Formatted<Datetime>) {
@@ -145,15 +145,15 @@ pub trait VisitMut {
     }
 
     fn visit_float_mut(&mut self, node: &mut Formatted<f64>) {
-        visit_float_mut(self, node)
+        visit_float_mut(self, node);
     }
 
     fn visit_integer_mut(&mut self, node: &mut Formatted<i64>) {
-        visit_integer_mut(self, node)
+        visit_integer_mut(self, node);
     }
 
     fn visit_string_mut(&mut self, node: &mut Formatted<String>) {
-        visit_string_mut(self, node)
+        visit_string_mut(self, node);
     }
 }
 
@@ -203,7 +203,7 @@ pub fn visit_table_like_kv_mut<V>(v: &mut V, _key: KeyMut<'_>, node: &mut Item)
 where
     V: VisitMut + ?Sized,
 {
-    v.visit_item_mut(node)
+    v.visit_item_mut(node);
 }
 
 pub fn visit_array_mut<V>(v: &mut V, node: &mut Array)
diff --git a/crates/toml_edit_fuzz/Cargo.toml b/crates/toml_edit_fuzz/Cargo.toml
index 45e90fcd..a9d425ef 100644
--- a/crates/toml_edit_fuzz/Cargo.toml
+++ b/crates/toml_edit_fuzz/Cargo.toml
@@ -19,3 +19,6 @@ toml_edit = { path = "../toml_edit" }
 name = "parse_document"
 path = "parse_document.rs"
 test = false
+
+[lints]
+workspace = true


Test patch:
diff --git a/crates/toml/tests/decoder.rs b/crates/toml/tests/decoder.rs
index 5af906f3..a963f95b 100644
--- a/crates/toml/tests/decoder.rs
+++ b/crates/toml/tests/decoder.rs
@@ -1,7 +1,7 @@
 #![cfg(all(feature = "parse", feature = "display"))]
 
 #[derive(Copy, Clone)]
-pub struct Decoder;
+pub(crate) struct Decoder;
 
 impl toml_test_harness::Decoder for Decoder {
     fn name(&self) -> &str {
diff --git a/crates/toml/tests/encoder.rs b/crates/toml/tests/encoder.rs
index e76a74a2..972aac6d 100644
--- a/crates/toml/tests/encoder.rs
+++ b/crates/toml/tests/encoder.rs
@@ -1,7 +1,7 @@
 #![cfg(all(feature = "parse", feature = "display"))]
 
 #[derive(Copy, Clone)]
-pub struct Encoder;
+pub(crate) struct Encoder;
 
 impl toml_test_harness::Encoder for Encoder {
     fn name(&self) -> &str {
diff --git a/crates/toml/tests/testsuite/de_errors.rs b/crates/toml/tests/testsuite/de_errors.rs
index 9773d928..4864a75f 100644
--- a/crates/toml/tests/testsuite/de_errors.rs
+++ b/crates/toml/tests/testsuite/de_errors.rs
@@ -29,7 +29,7 @@ enum CasedString {
     Uppercase(String),
 }
 
-impl<'de> de::Deserialize<'de> for CasedString {
+impl<'de> Deserialize<'de> for CasedString {
     fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
     where
         D: de::Deserializer<'de>,
@@ -39,7 +39,7 @@ impl<'de> de::Deserialize<'de> for CasedString {
         impl<'de> de::Visitor<'de> for CasedStringVisitor {
             type Value = CasedString;
 
-            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+            fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
                 formatter.write_str("a string")
             }
 
@@ -50,9 +50,9 @@ impl<'de> de::Deserialize<'de> for CasedString {
                 if s.is_empty() {
                     Err(de::Error::invalid_length(0, &"a non-empty string"))
                 } else if s.chars().all(|x| x.is_ascii_lowercase()) {
-                    Ok(CasedString::Lowercase(s.to_string()))
+                    Ok(CasedString::Lowercase(s.to_owned()))
                 } else if s.chars().all(|x| x.is_ascii_uppercase()) {
-                    Ok(CasedString::Uppercase(s.to_string()))
+                    Ok(CasedString::Uppercase(s.to_owned()))
                 } else {
                     Err(de::Error::invalid_value(
                         de::Unexpected::Str(s),
diff --git a/crates/toml/tests/testsuite/display.rs b/crates/toml/tests/testsuite/display.rs
index 7430fac8..c38486e9 100644
--- a/crates/toml/tests/testsuite/display.rs
+++ b/crates/toml/tests/testsuite/display.rs
@@ -3,13 +3,13 @@ use toml::Value::{Array, Boolean, Float, Integer, String, Table};
 
 macro_rules! map( ($($k:expr => $v:expr),*) => ({
     let mut _m = Map::new();
-    $(_m.insert($k.to_string(), $v);)*
+    $(_m.insert($k.to_owned(), $v);)*
     _m
 }) );
 
 #[test]
 fn simple_show() {
-    assert_eq!(String("foo".to_string()).to_string(), "\"foo\"");
+    assert_eq!(String("foo".to_owned()).to_string(), "\"foo\"");
     assert_eq!(Integer(10).to_string(), "10");
     assert_eq!(Float(10.0).to_string(), "10.0");
     assert_eq!(Float(2.4).to_string(), "2.4");
@@ -32,7 +32,7 @@ fn table() {
         map! {
              "test" => Integer(2),
              "test2" => Table(map! {
-                 "test" => String("wut".to_string())
+                 "test" => String("wut".to_owned())
              })
         }
         .to_string(),
@@ -45,7 +45,7 @@ fn table() {
         map! {
              "test" => Integer(2),
              "test2" => Table(map! {
-                 "test" => String("wut".to_string())
+                 "test" => String("wut".to_owned())
              })
         }
         .to_string(),
@@ -58,7 +58,7 @@ fn table() {
         map! {
              "test" => Integer(2),
              "test2" => Array(vec![Table(map! {
-                 "test" => String("wut".to_string())
+                 "test" => String("wut".to_owned())
              })])
         }
         .to_string(),
@@ -94,7 +94,7 @@ fn table() {
         "test" => Integer(2),
         "test2" => Array(vec![Table(map! {
             "test" => Array(vec![Array(vec![Integer(2), Integer(3)]),
-            Array(vec![String("foo".to_string()), String("bar".to_string())])])
+            Array(vec![String("foo".to_owned()), String("bar".to_owned())])])
         })])
     };
     assert_eq!(
diff --git a/crates/toml/tests/testsuite/display_tricky.rs b/crates/toml/tests/testsuite/display_tricky.rs
index 379ae913..a75e00e3 100644
--- a/crates/toml/tests/testsuite/display_tricky.rs
+++ b/crates/toml/tests/testsuite/display_tricky.rs
@@ -2,25 +2,25 @@ use serde::Deserialize;
 use serde::Serialize;
 
 #[derive(Debug, Serialize, Deserialize)]
-pub struct Recipe {
-    pub name: String,
-    pub description: Option<String>,
+pub(crate) struct Recipe {
+    pub(crate) name: String,
+    pub(crate) description: Option<String>,
     #[serde(default)]
-    pub modules: Vec<Modules>,
+    pub(crate) modules: Vec<Modules>,
     #[serde(default)]
-    pub packages: Vec<Packages>,
+    pub(crate) packages: Vec<Packages>,
 }
 
 #[derive(Debug, Serialize, Deserialize)]
-pub struct Modules {
-    pub name: String,
-    pub version: Option<String>,
+pub(crate) struct Modules {
+    pub(crate) name: String,
+    pub(crate) version: Option<String>,
 }
 
 #[derive(Debug, Serialize, Deserialize)]
-pub struct Packages {
-    pub name: String,
-    pub version: Option<String>,
+pub(crate) struct Packages {
+    pub(crate) name: String,
+    pub(crate) version: Option<String>,
 }
 
 #[test]
diff --git a/crates/toml/tests/testsuite/enum_external_deserialize.rs b/crates/toml/tests/testsuite/enum_external_deserialize.rs
index 6e0c2f76..0c1a33cb 100644
--- a/crates/toml/tests/testsuite/enum_external_deserialize.rs
+++ b/crates/toml/tests/testsuite/enum_external_deserialize.rs
@@ -189,12 +189,12 @@ mod enum_newtype {
     #[test]
     fn from_inline_table() {
         assert_eq!(
-            TheEnum::NewType("value".to_string()),
+            TheEnum::NewType("value".to_owned()),
             value_from_str(r#"{ NewType = "value" }"#).unwrap()
         );
         assert_eq!(
             Val {
-                val: TheEnum::NewType("value".to_string()),
+                val: TheEnum::NewType("value".to_owned()),
             },
             toml::from_str(r#"val = { NewType = "value" }"#).unwrap()
         );
@@ -203,12 +203,12 @@ mod enum_newtype {
     #[test]
     fn from_std_table() {
         assert_eq!(
-            TheEnum::NewType("value".to_string()),
+            TheEnum::NewType("value".to_owned()),
             toml::from_str(r#"NewType = "value""#).unwrap()
         );
         assert_eq!(
             Val {
-                val: TheEnum::NewType("value".to_string()),
+                val: TheEnum::NewType("value".to_owned()),
             },
             toml::from_str(
                 r#"[val]
@@ -283,7 +283,7 @@ mod enum_array {
                 enums: vec![
                     TheEnum::Plain,
                     TheEnum::Tuple(-123, true),
-                    TheEnum::NewType("value".to_string()),
+                    TheEnum::NewType("value".to_owned()),
                     TheEnum::Struct { value: -123 },
                 ]
             },
@@ -310,7 +310,7 @@ mod enum_array {
                 enums: vec![
                     TheEnum::Plain,
                     TheEnum::Tuple(-123, true),
-                    TheEnum::NewType("value".to_string()),
+                    TheEnum::NewType("value".to_owned()),
                     TheEnum::Struct { value: -123 },
                 ]
             },
diff --git a/crates/toml/tests/testsuite/formatting.rs b/crates/toml/tests/testsuite/formatting.rs
index 8240d1d3..195d60e3 100644
--- a/crates/toml/tests/testsuite/formatting.rs
+++ b/crates/toml/tests/testsuite/formatting.rs
@@ -4,19 +4,19 @@ use toml::to_string;
 
 #[derive(Debug, Clone, Hash, PartialEq, Eq, Serialize, Deserialize)]
 struct User {
-    pub name: String,
-    pub surname: String,
+    pub(crate) name: String,
+    pub(crate) surname: String,
 }
 
 #[derive(Debug, Clone, Hash, PartialEq, Eq, Serialize, Deserialize)]
 struct Users {
-    pub user: Vec<User>,
+    pub(crate) user: Vec<User>,
 }
 
 #[derive(Debug, Clone, Hash, PartialEq, Eq, Serialize, Deserialize)]
 struct TwoUsers {
-    pub user0: User,
-    pub user1: User,
+    pub(crate) user0: User,
+    pub(crate) user1: User,
 }
 
 #[test]
@@ -24,12 +24,12 @@ fn no_unnecessary_newlines_array() {
     assert!(!to_string(&Users {
         user: vec![
             User {
-                name: "John".to_string(),
-                surname: "Doe".to_string(),
+                name: "John".to_owned(),
+                surname: "Doe".to_owned(),
             },
             User {
-                name: "Jane".to_string(),
-                surname: "Dough".to_string(),
+                name: "Jane".to_owned(),
+                surname: "Dough".to_owned(),
             },
         ],
     })
@@ -41,12 +41,12 @@ fn no_unnecessary_newlines_array() {
 fn no_unnecessary_newlines_table() {
     assert!(!to_string(&TwoUsers {
         user0: User {
-            name: "John".to_string(),
-            surname: "Doe".to_string(),
+            name: "John".to_owned(),
+            surname: "Doe".to_owned(),
         },
         user1: User {
-            name: "Jane".to_string(),
-            surname: "Dough".to_string(),
+            name: "Jane".to_owned(),
+            surname: "Dough".to_owned(),
         },
     })
     .unwrap()
diff --git a/crates/toml/tests/testsuite/macros.rs b/crates/toml/tests/testsuite/macros.rs
index e002cd91..97e933de 100644
--- a/crates/toml/tests/testsuite/macros.rs
+++ b/crates/toml/tests/testsuite/macros.rs
@@ -8,7 +8,7 @@ macro_rules! table {
         #[allow(unused_mut)]
         let mut table = toml::value::Table::new();
         $(
-            table.insert($key.to_string(), $value.into());
+            table.insert($key.to_owned(), $value.into());
         )*
         toml::Value::Table(table)
     }};
diff --git a/crates/toml/tests/testsuite/pretty.rs b/crates/toml/tests/testsuite/pretty.rs
index 369888fb..11c44236 100644
--- a/crates/toml/tests/testsuite/pretty.rs
+++ b/crates/toml/tests/testsuite/pretty.rs
@@ -165,7 +165,7 @@ fn error_includes_key() {
 
     #[derive(Clone, Debug, serde::Deserialize, serde::Serialize, Eq, PartialEq)]
     #[serde(untagged, expecting = "expected a boolean or an integer")]
-    pub enum U32OrBool {
+    pub(crate) enum U32OrBool {
         U32(u32),
         Bool(bool),
     }
diff --git a/crates/toml/tests/testsuite/serde.rs b/crates/toml/tests/testsuite/serde.rs
index d7f8bc40..8c9092c5 100644
--- a/crates/toml/tests/testsuite/serde.rs
+++ b/crates/toml/tests/testsuite/serde.rs
@@ -62,7 +62,7 @@ macro_rules! error {
 
 macro_rules! map( ($($k:ident: $v:expr),*) => ({
     let mut _m = Map::new();
-    $(_m.insert(stringify!($k).to_string(), t!(Value::try_from($v)));)*
+    $(_m.insert(stringify!($k).to_owned(), t!(Value::try_from($v)));)*
     _m
 }) );
 
@@ -83,19 +83,19 @@ fn smoke_hyphen() {
         a_b: isize,
     }
 
-    equivalent! {
-        Foo { a_b: 2 },
-        map! { a_b: Value::Integer(2)},
-    }
-
     #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
     struct Foo2 {
         #[serde(rename = "a-b")]
         a_b: isize,
     }
 
+    equivalent! {
+        Foo { a_b: 2 },
+        map! { a_b: Value::Integer(2)},
+    }
+
     let mut m = Map::new();
-    m.insert("a-b".to_string(), Value::Integer(2));
+    m.insert("a-b".to_owned(), Value::Integer(2));
     equivalent! {
         Foo2 { a_b: 2 },
         m,
@@ -115,11 +115,11 @@ fn nested() {
     }
 
     equivalent! {
-        Foo { a: 2, b: Bar { a: "test".to_string() } },
+        Foo { a: 2, b: Bar { a: "test".to_owned() } },
         map! {
             a: Value::Integer(2),
             b: map! {
-                a: Value::String("test".to_string())
+                a: Value::String("test".to_owned())
             }
         },
     }
@@ -129,7 +129,7 @@ fn nested() {
 fn application_decode_error() {
     #[derive(PartialEq, Debug)]
     struct Range10(usize);
-    impl<'de> serde::Deserialize<'de> for Range10 {
+    impl<'de> Deserialize<'de> for Range10 {
         fn deserialize<D: Deserializer<'de>>(d: D) -> Result<Range10, D::Error> {
             let x: usize = serde::Deserialize::deserialize(d)?;
             if x > 10 {
@@ -140,7 +140,7 @@ fn application_decode_error() {
         }
     }
     let d_good = Value::Integer(5);
-    let d_bad1 = Value::String("not an isize".to_string());
+    let d_bad1 = Value::String("not an isize".to_owned());
     let d_bad2 = Value::Integer(11);
 
     assert_eq!(Range10(5), d_good.try_into().unwrap());
@@ -188,19 +188,19 @@ fn inner_structs_with_options() {
         Foo {
             a: Some(Box::new(Foo {
                 a: None,
-                b: Bar { a: "foo".to_string(), b: 4.5 },
+                b: Bar { a: "foo".to_owned(), b: 4.5 },
             })),
-            b: Bar { a: "bar".to_string(), b: 1.0 },
+            b: Bar { a: "bar".to_owned(), b: 1.0 },
         },
         map! {
             a: map! {
                 b: map! {
-                    a: Value::String("foo".to_string()),
+                    a: Value::String("foo".to_owned()),
                     b: Value::Float(4.5)
                 }
             },
             b: map! {
-                a: Value::String("bar".to_string()),
+                a: Value::String("bar".to_owned()),
                 b: Value::Float(1.0)
             }
         },
@@ -227,13 +227,13 @@ fn hashmap() {
             },
             map: {
                 let mut m = BTreeMap::new();
-                m.insert("bar".to_string(), 4);
-                m.insert("foo".to_string(), 10);
+                m.insert("bar".to_owned(), 4);
+                m.insert("foo".to_owned(), 10);
                 m
             }
         },
         map! {
-            set: Value::Array(vec![Value::String("a".to_string())]),
+            set: Value::Array(vec![Value::String("a".to_owned())]),
             map: map! {
                 bar: Value::Integer(4),
                 foo: Value::Integer(10)
@@ -272,10 +272,16 @@ fn type_errors() {
         bar: isize,
     }
 
+    #[derive(Deserialize)]
+    #[allow(dead_code)]
+    struct Bar {
+        foo: Foo,
+    }
+
     error! {
         Foo,
         map! {
-            bar: Value::String("a".to_string())
+            bar: Value::String("a".to_owned())
         },
         r#"TOML parse error at line 1, column 7
   |
@@ -286,17 +292,11 @@ invalid type: string "a", expected isize
         "invalid type: string \"a\", expected isize\nin `bar`\n"
     }
 
-    #[derive(Deserialize)]
-    #[allow(dead_code)]
-    struct Bar {
-        foo: Foo,
-    }
-
     error! {
         Bar,
         map! {
             foo: map! {
-                bar: Value::String("a".to_string())
+                bar: Value::String("a".to_owned())
             }
         },
         r#"TOML parse error at line 2, column 7
@@ -353,13 +353,13 @@ fn parse_enum() {
     }
 
     equivalent! {
-        Foo { a: E::Baz("foo".to_string()) },
-        map! { a: Value::String("foo".to_string()) },
+        Foo { a: E::Baz("foo".to_owned()) },
+        map! { a: Value::String("foo".to_owned()) },
     }
 
     equivalent! {
-        Foo { a: E::Last(Foo2 { test: "test".to_string() }) },
-        map! { a: map! { test: Value::String("test".to_string()) } },
+        Foo { a: E::Last(Foo2 { test: "test".to_owned() }) },
+        map! { a: map! { test: Value::String("test".to_owned()) } },
     }
 }
 
@@ -379,7 +379,7 @@ fn parse_enum_string() {
 
     equivalent! {
         Foo { a: Sort::Desc },
-        map! { a: Value::String("desc".to_string()) },
+        map! { a: Value::String("desc".to_owned()) },
     }
 }
 
@@ -566,10 +566,10 @@ fn map_key_unit_variants() {
 //     #[derive(Serialize, Deserialize, PartialEq, Debug)]
 //     struct Foo { a: BTreeMap<String, String> }
 //
-//     let v = Foo { a: map! { a, "foo".to_string() } };
+//     let v = Foo { a: map! { a, "foo".to_owned() } };
 //     let mut d = Decoder::new(Table(map! {
 //         a, Table(map! {
-//             a, Value::String("foo".to_string())
+//             a, Value::String("foo".to_owned())
 //         })
 //     }));
 //     assert_eq!(v, t!(Deserialize::deserialize(&mut d)));
@@ -582,9 +582,9 @@ fn map_key_unit_variants() {
 //     #[derive(Serialize, Deserialize, PartialEq, Debug)]
 //     struct Foo { a: Vec<String> }
 //
-//     let v = Foo { a: vec!["a".to_string()] };
+//     let v = Foo { a: vec!["a".to_owned()] };
 //     let mut d = Decoder::new(Table(map! {
-//         a, Array(vec![Value::String("a".to_string())])
+//         a, Array(vec![Value::String("a".to_owned())])
 //     }));
 //     assert_eq!(v, t!(Deserialize::deserialize(&mut d)));
 //
@@ -747,7 +747,7 @@ fn newtype_key() {
     #[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Clone, Serialize, Deserialize)]
     struct NewType(String);
 
-    type CustomKeyMap = std::collections::BTreeMap<NewType, u32>;
+    type CustomKeyMap = BTreeMap<NewType, u32>;
 
     equivalent! {
         [
@@ -772,16 +772,16 @@ fn table_structs_empty() {
     let text = "[bar]\n\n[baz]\n\n[bazv]\na = \"foo\"\n\n[foo]\n";
     let value: BTreeMap<String, CanBeEmpty> = toml::from_str(text).unwrap();
     let mut expected: BTreeMap<String, CanBeEmpty> = BTreeMap::new();
-    expected.insert("bar".to_string(), CanBeEmpty::default());
-    expected.insert("baz".to_string(), CanBeEmpty::default());
+    expected.insert("bar".to_owned(), CanBeEmpty::default());
+    expected.insert("baz".to_owned(), CanBeEmpty::default());
     expected.insert(
-        "bazv".to_string(),
+        "bazv".to_owned(),
         CanBeEmpty {
-            a: Some("foo".to_string()),
+            a: Some("foo".to_owned()),
             b: None,
         },
     );
-    expected.insert("foo".to_string(), CanBeEmpty::default());
+    expected.insert("foo".to_owned(), CanBeEmpty::default());
     assert_eq!(value, expected);
     snapbox::assert_eq(text, toml::to_string(&value).unwrap());
 }
@@ -830,17 +830,17 @@ fn homogeneous_tuple_struct() {
 
     equivalent! {
         map! {
-            obj: Object(vec!["foo".to_string()], vec![], vec!["bar".to_string(), "baz".to_string()])
+            obj: Object(vec!["foo".to_owned()], vec![], vec!["bar".to_owned(), "baz".to_owned()])
         },
         map! {
             obj: Value::Array(vec![
                 Value::Array(vec![
-                    Value::String("foo".to_string()),
+                    Value::String("foo".to_owned()),
                 ]),
                 Value::Array(vec![]),
                 Value::Array(vec![
-                    Value::String("bar".to_string()),
-                    Value::String("baz".to_string()),
+                    Value::String("bar".to_owned()),
+                    Value::String("baz".to_owned()),
                 ]),
             ])
         },
@@ -851,7 +851,7 @@ fn homogeneous_tuple_struct() {
 fn json_interoperability() {
     #[derive(Serialize, Deserialize)]
     struct Foo {
-        any: toml::Value,
+        any: Value,
     }
 
     let _foo: Foo = serde_json::from_str(
@@ -884,7 +884,7 @@ fn error_includes_key() {
 
     #[derive(Clone, Debug, Deserialize, Serialize, Eq, PartialEq)]
     #[serde(untagged, expecting = "expected a boolean or an integer")]
-    pub enum U32OrBool {
+    pub(crate) enum U32OrBool {
         U32(u32),
         Bool(bool),
     }
@@ -997,7 +997,7 @@ fn newline_dotted_table() {
 
     #[derive(Clone, Debug, Deserialize, Serialize, Eq, PartialEq)]
     #[serde(untagged, expecting = "expected a boolean or an integer")]
-    pub enum U32OrBool {
+    pub(crate) enum U32OrBool {
         U32(u32),
         Bool(bool),
     }
@@ -1046,7 +1046,7 @@ fn newline_mixed_tables() {
 
     #[derive(Clone, Debug, Deserialize, Serialize, Eq, PartialEq)]
     #[serde(untagged, expecting = "expected a boolean or an integer")]
-    pub enum U32OrBool {
+    pub(crate) enum U32OrBool {
         U32(u32),
         Bool(bool),
     }
@@ -1174,6 +1174,7 @@ fn table_type_enum_regression_issue_388() {
     }
 
     #[derive(Deserialize)]
+    #[allow(dead_code)]
     enum Compare {
         Gt(u32),
     }
@@ -1216,7 +1217,7 @@ fn serialize_datetime_issue_333() {
 #[test]
 fn datetime_offset_issue_496() {
     let original = "value = 1911-01-01T10:11:12-00:36\n";
-    let toml = original.parse::<toml::Table>().unwrap();
+    let toml = original.parse::<Table>().unwrap();
     let output = toml.to_string();
     snapbox::assert_eq(original, output);
 }
diff --git a/crates/toml/tests/testsuite/spanned.rs b/crates/toml/tests/testsuite/spanned.rs
index 760c73aa..a6dff1d5 100644
--- a/crates/toml/tests/testsuite/spanned.rs
+++ b/crates/toml/tests/testsuite/spanned.rs
@@ -9,7 +9,7 @@ use toml::value::Datetime;
 use toml::Spanned;
 
 /// A set of good datetimes.
-pub fn good_datetimes() -> Vec<&'static str> {
+pub(crate) fn good_datetimes() -> Vec<&'static str> {
     vec![
         "1997-09-09T09:09:09Z",
         "1997-09-09T09:09:09+09:09",
diff --git a/crates/toml/tests/testsuite/tables_last.rs b/crates/toml/tests/testsuite/tables_last.rs
index b0035579..d94f2b1f 100644
--- a/crates/toml/tests/testsuite/tables_last.rs
+++ b/crates/toml/tests/testsuite/tables_last.rs
@@ -54,11 +54,11 @@ fn vec_of_vec_issue_387() {
     }
 
     let comp1 = Component {
-        base: "b".to_string(),
+        base: "b".to_owned(),
         transform: (1.0, 0.0, 0.0, 1.0, 0.0, 0.0),
     };
     let comp2 = Component {
-        base: "c".to_string(),
+        base: "c".to_owned(),
         transform: (1.0, 0.0, 0.0, 1.0, 0.0, 0.0),
     };
     let components = vec![comp1, comp2];
@@ -68,40 +68,40 @@ fn vec_of_vec_issue_387() {
             Point {
                 x: 3.0,
                 y: 4.0,
-                pt_type: "line".to_string(),
+                pt_type: "line".to_owned(),
             },
             Point {
                 x: 5.0,
                 y: 6.0,
-                pt_type: "line".to_string(),
+                pt_type: "line".to_owned(),
             },
         ],
         vec![
             Point {
                 x: 0.0,
                 y: 0.0,
-                pt_type: "move".to_string(),
+                pt_type: "move".to_owned(),
             },
             Point {
                 x: 7.0,
                 y: 9.0,
-                pt_type: "offcurve".to_string(),
+                pt_type: "offcurve".to_owned(),
             },
             Point {
                 x: 8.0,
                 y: 10.0,
-                pt_type: "offcurve".to_string(),
+                pt_type: "offcurve".to_owned(),
             },
             Point {
                 x: 11.0,
                 y: 12.0,
-                pt_type: "curve".to_string(),
+                pt_type: "curve".to_owned(),
             },
         ],
     ];
     let g1 = Glyph {
-        contours,
         components,
+        contours,
     };
 
     let s = toml::to_string_pretty(&g1).unwrap();
@@ -149,13 +149,13 @@ fn values_before_tables_issue_403() {
     }
     toml::to_string(&C {
         a: A {
-            a: "aa".to_string(),
-            b: "ab".to_string(),
+            a: "aa".to_owned(),
+            b: "ab".to_owned(),
         },
-        b: vec!["b".to_string()],
+        b: vec!["b".to_owned()],
         c: vec![B {
-            a: "cba".to_string(),
-            b: vec!["cbb".to_string()],
+            a: "cba".to_owned(),
+            b: vec!["cbb".to_owned()],
         }],
     })
     .unwrap();
diff --git a/crates/toml_edit/tests/decoder.rs b/crates/toml_edit/tests/decoder.rs
index 6ccce135..f8cf02c7 100644
--- a/crates/toml_edit/tests/decoder.rs
+++ b/crates/toml_edit/tests/decoder.rs
@@ -1,5 +1,5 @@
 #[derive(Copy, Clone)]
-pub struct Decoder;
+pub(crate) struct Decoder;
 
 impl toml_test_harness::Decoder for Decoder {
     fn name(&self) -> &str {
diff --git a/crates/toml_edit/tests/encoder.rs b/crates/toml_edit/tests/encoder.rs
index 79f7f6c2..e325aca6 100644
--- a/crates/toml_edit/tests/encoder.rs
+++ b/crates/toml_edit/tests/encoder.rs
@@ -1,5 +1,5 @@
 #[derive(Copy, Clone)]
-pub struct Encoder;
+pub(crate) struct Encoder;
 
 impl toml_test_harness::Encoder for Encoder {
     fn name(&self) -> &str {
diff --git a/crates/toml_edit/tests/testsuite/edit.rs b/crates/toml_edit/tests/testsuite/edit.rs
index d185bac9..fcb5eb0e 100644
--- a/crates/toml_edit/tests/testsuite/edit.rs
+++ b/crates/toml_edit/tests/testsuite/edit.rs
@@ -24,7 +24,7 @@ macro_rules! as_table {
 /// Used in different `assert*!` macros in combination with `pretty_assertions` crate to make
 /// test failures to show nice diffs.
 #[derive(PartialEq, Eq)]
-struct PrettyString<'a>(pub &'a str);
+struct PrettyString<'a>(pub(crate) &'a str);
 /// Make diff to display string as multi-line string
 impl<'a> fmt::Debug for PrettyString<'a> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
@@ -509,7 +509,7 @@ fn test_set_position() {
                 let tab = as_table!(table);
                 tab.set_position(0);
                 let (_, segmented) = tab.iter_mut().next().unwrap();
-                as_table!(segmented).set_position(5)
+                as_table!(segmented).set_position(5);
             }
         }
     })
@@ -535,7 +535,7 @@ fn test_multiple_zero_positions() {
     )
     .running(|root| {
         for (_, table) in root.iter_mut() {
-            as_table!(table).set_position(0)
+            as_table!(table).set_position(0);
         }
     })
     .produces_display(
@@ -561,7 +561,7 @@ fn test_multiple_max_usize_positions() {
     )
     .running(|root| {
         for (_, table) in root.iter_mut() {
-            as_table!(table).set_position(usize::MAX)
+            as_table!(table).set_position(usize::MAX);
         }
     })
     .produces_display(
@@ -718,7 +718,7 @@ fn test_insert_into_inline_table() {
         assert!(b.is_empty());
         b.get_or_insert("hello", "world");
         assert_eq!(b.len(), 1);
-        b.fmt()
+        b.fmt();
     })
     .produces_display(
         r#"
diff --git a/crates/toml_edit/tests/testsuite/parse.rs b/crates/toml_edit/tests/testsuite/parse.rs
index 56851091..a37bbb4b 100644
--- a/crates/toml_edit/tests/testsuite/parse.rs
+++ b/crates/toml_edit/tests/testsuite/parse.rs
@@ -98,7 +98,7 @@ macro_rules! bad {
     ($toml:expr, $msg:expr) => {
         match $toml.parse::<DocumentMut>() {
             Ok(s) => panic!("parsed to: {:#?}", s),
-            Err(e) => snapbox::assert_eq($msg, e.to_string()),
+            Err(e) => assert_eq($msg, e.to_string()),
         }
     };
 }
@@ -1503,7 +1503,7 @@ clippy.exhaustive_enums = "warn"
 "###;
     let expected = input;
 
-    let manifest: toml_edit::DocumentMut = input.parse().unwrap();
+    let manifest: DocumentMut = input.parse().unwrap();
     let actual = manifest.to_string();
 
     assert_eq(expected, actual);