From 061660ed9e9abe257012d2f1a4453d9a995aac88 Mon Sep 17 00:00:00 2001 From: Geoffrey Oxberry Date: Thu, 21 May 2026 21:10:56 +0000 Subject: [PATCH] chore(clippy): forbid .expect() in production code Adds `clippy::expect_used = "deny"` to the workspace lint set, mirroring the existing `unwrap_used` policy. Configures `allow-expect-in-tests = true` in clippy.toml so `#[cfg(test)]` modules remain free to use `.expect()`. Pre-existing production `.expect()` sites are quarantined behind a transitional `#![allow(clippy::expect_used)]` at the crate root of the four affected library crates (lading, lading_capture, lading_payload, lading_throttle). The lint fires immediately on new sites in any other location. Cleanup PRs will remove each crate's quarantine atomically with its violations. Benches in lading_payload/benches/ get a permanent crate-root allow because each bench is a separate crate root and clippy has no `allow-expect-in-benches` knob to mirror the in-tests one. Co-Authored-By: Claude Opus 4.7 (1M context) --- CHANGELOG.md | 9 +++++++++ Cargo.toml | 1 + clippy.toml | 5 ++++- lading/src/bin/captool/main.rs | 3 +++ lading/src/bin/lading.rs | 4 ++++ lading/src/bin/payloadtool.rs | 3 +++ lading/src/lib.rs | 3 +++ lading_capture/src/bin/fuzz_capture_harness.rs | 3 +++ lading_capture/src/lib.rs | 4 ++++ lading_payload/benches/apache_common.rs | 4 ++++ lading_payload/benches/ascii.rs | 4 ++++ lading_payload/benches/block.rs | 4 ++++ lading_payload/benches/datadog_logs.rs | 4 ++++ lading_payload/benches/dogstatsd.rs | 4 ++++ lading_payload/benches/fluent.rs | 4 ++++ lading_payload/benches/json.rs | 4 ++++ lading_payload/benches/opentelemetry_log.rs | 4 ++++ lading_payload/benches/opentelemetry_metric.rs | 4 ++++ lading_payload/benches/opentelemetry_traces.rs | 4 ++++ lading_payload/benches/splunk_hec.rs | 4 ++++ lading_payload/benches/syslog.rs | 4 ++++ lading_payload/benches/templated_json.rs | 4 ++++ lading_payload/benches/trace_agent.rs | 4 ++++ lading_payload/src/lib.rs | 3 +++ lading_throttle/src/lib.rs | 3 +++ 25 files changed, 96 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 68a680e27..155d0ff87 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,15 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## Unreleased +- Added `clippy::expect_used = "deny"` to the workspace-level lint set, + mirroring the existing `clippy::unwrap_used` policy, and set + `allow-expect-in-tests = true` in `clippy.toml`. Production `.expect()` + calls are now denied in library crates while `#[cfg(test)]` code is + unaffected. Crates with pre-existing production `.expect()` sites + (`lading`, `lading_capture`, `lading_payload`, `lading_throttle`) carry + a transitional `#![allow(clippy::expect_used)]` quarantine at their + crate roots; this allow will be removed crate-by-crate as the sites are + cleaned up. - Updated to rand 0.10.x - `dogstatsd` generator now supports configurable pools for the `|c:` (container ID), `|e:` (external data), and `|card:` (cardinality) origin detection diff --git a/Cargo.toml b/Cargo.toml index 677f879de..59dc3b83f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -77,6 +77,7 @@ perf = "deny" suspicious = "deny" complexity = "deny" unwrap_used = "deny" +expect_used = "deny" mod_module_files = "deny" dbg_macro = "deny" print_stdout = "deny" diff --git a/clippy.toml b/clippy.toml index 1b3396338..09175b8a4 100644 --- a/clippy.toml +++ b/clippy.toml @@ -1,8 +1,11 @@ # https://rust-lang.github.io/rust-clippy/master/index.html#doc_markdown doc-valid-idents = ["OpenTelemetry", "gRPC", ".."] -# Allow unwrap() and print!/println! in test code without per-module suppressions +# Allow unwrap()/expect() and print!/println! in test code without per-module +# suppressions. `allow-expect-in-tests` mirrors `allow-unwrap-in-tests`; the +# corresponding `clippy::expect_used` lint is set in the workspace Cargo.toml. allow-unwrap-in-tests = true +allow-expect-in-tests = true allow-print-in-tests = true # https://rust-lang.github.io/rust-clippy/master/index.html#disallowed_types diff --git a/lading/src/bin/captool/main.rs b/lading/src/bin/captool/main.rs index 62371ea5f..23c39a396 100644 --- a/lading/src/bin/captool/main.rs +++ b/lading/src/bin/captool/main.rs @@ -1,6 +1,9 @@ //! Capture analysis tool for lading capture files. #![expect(clippy::print_stdout)] +// Quarantine: workspace denies `clippy::expect_used`, but this binary still has +// production `.expect()` sites awaiting cleanup. Remove once cleaned up. +#![allow(clippy::expect_used)] mod analyze; diff --git a/lading/src/bin/lading.rs b/lading/src/bin/lading.rs index 6161fac55..932af5f5f 100644 --- a/lading/src/bin/lading.rs +++ b/lading/src/bin/lading.rs @@ -1,5 +1,9 @@ //! Main lading binary for load testing. +// Quarantine: workspace denies `clippy::expect_used`, but this binary still has +// production `.expect()` sites awaiting cleanup. Remove once cleaned up. +#![allow(clippy::expect_used)] + use std::{ env, fmt::{self, Display}, diff --git a/lading/src/bin/payloadtool.rs b/lading/src/bin/payloadtool.rs index 0e90d2a9b..77e12b289 100644 --- a/lading/src/bin/payloadtool.rs +++ b/lading/src/bin/payloadtool.rs @@ -2,6 +2,9 @@ #![expect(clippy::print_stdout)] #![expect(clippy::print_stderr)] +// Quarantine: workspace denies `clippy::expect_used`, but this binary still has +// production `.expect()` sites awaiting cleanup. Remove once cleaned up. +#![allow(clippy::expect_used)] /// Memory allocation tracking for payloadtool statistics. /// diff --git a/lading/src/lib.rs b/lading/src/lib.rs index f301d63ee..4c1aac577 100644 --- a/lading/src/lib.rs +++ b/lading/src/lib.rs @@ -8,6 +8,9 @@ #![deny(clippy::cargo)] #![expect(clippy::cast_precision_loss)] #![expect(clippy::multiple_crate_versions)] +// Quarantine: workspace denies `clippy::expect_used`, but this crate still has +// production `.expect()` sites awaiting cleanup. Remove once cleaned up. +#![allow(clippy::expect_used)] use http_body_util::BodyExt; diff --git a/lading_capture/src/bin/fuzz_capture_harness.rs b/lading_capture/src/bin/fuzz_capture_harness.rs index fc007a648..1331da56d 100644 --- a/lading_capture/src/bin/fuzz_capture_harness.rs +++ b/lading_capture/src/bin/fuzz_capture_harness.rs @@ -7,6 +7,9 @@ #![expect(clippy::print_stderr)] #![allow(clippy::cast_precision_loss)] +// Quarantine: workspace denies `clippy::expect_used`, but this binary still has +// production `.expect()` sites awaiting cleanup. Remove once cleaned up. +#![allow(clippy::expect_used)] use anyhow::{Context, Result}; use arbitrary::Arbitrary; diff --git a/lading_capture/src/lib.rs b/lading_capture/src/lib.rs index a3ad883e1..c0a1b4c5a 100644 --- a/lading_capture/src/lib.rs +++ b/lading_capture/src/lib.rs @@ -1,5 +1,9 @@ //! Crate regarding Lading's 'capture' files +// Quarantine: workspace denies `clippy::expect_used`, but this crate still has +// production `.expect()` sites awaiting cleanup. Remove once cleaned up. +#![allow(clippy::expect_used)] + use std::time::Instant; use manager::HISTORICAL_SENDER; diff --git a/lading_payload/benches/apache_common.rs b/lading_payload/benches/apache_common.rs index 48efbecb7..9e0b2bd5a 100644 --- a/lading_payload/benches/apache_common.rs +++ b/lading_payload/benches/apache_common.rs @@ -1,5 +1,9 @@ //! Benchmarks for Apache Common log payload generation. +// `.expect()` is permitted in benches; workspace denies `clippy::expect_used` +// for production code. +#![allow(clippy::expect_used)] + use criterion::{BatchSize, BenchmarkId, Criterion, Throughput, criterion_group, criterion_main}; use lading_payload::{Serialize, apache_common}; use rand::{SeedableRng, rngs::SmallRng}; diff --git a/lading_payload/benches/ascii.rs b/lading_payload/benches/ascii.rs index aec42b66f..9bd20dbdc 100644 --- a/lading_payload/benches/ascii.rs +++ b/lading_payload/benches/ascii.rs @@ -3,6 +3,10 @@ //! Paired with SMP regression experiments in `experiments/regression/cases/http_ascii_*`. //! If throughput sizes here change, update the corresponding SMP experiments and vice versa. +// `.expect()` is permitted in benches; workspace denies `clippy::expect_used` +// for production code. +#![allow(clippy::expect_used)] + use criterion::{BatchSize, BenchmarkId, Criterion, Throughput, criterion_group, criterion_main}; use lading_payload::{Serialize, ascii}; use rand::{SeedableRng, rngs::SmallRng}; diff --git a/lading_payload/benches/block.rs b/lading_payload/benches/block.rs index 53c880dd6..6fca9a537 100644 --- a/lading_payload/benches/block.rs +++ b/lading_payload/benches/block.rs @@ -1,5 +1,9 @@ //! Benchmarks for Block Cache operations. +// `.expect()` is permitted in benches; workspace denies `clippy::expect_used` +// for production code. +#![allow(clippy::expect_used)] + use criterion::{BenchmarkId, Criterion, Throughput, criterion_group, criterion_main}; use lading_payload::Config; use lading_payload::block::Cache; diff --git a/lading_payload/benches/datadog_logs.rs b/lading_payload/benches/datadog_logs.rs index 848176bc5..6cab87057 100644 --- a/lading_payload/benches/datadog_logs.rs +++ b/lading_payload/benches/datadog_logs.rs @@ -1,5 +1,9 @@ //! Benchmarks for Datadog Logs payload generation. +// `.expect()` is permitted in benches; workspace denies `clippy::expect_used` +// for production code. +#![allow(clippy::expect_used)] + use criterion::{BatchSize, BenchmarkId, Criterion, Throughput, criterion_group, criterion_main}; use lading_payload::{DatadogLog, Serialize}; use rand::{SeedableRng, rngs::SmallRng}; diff --git a/lading_payload/benches/dogstatsd.rs b/lading_payload/benches/dogstatsd.rs index cdbf6ab7f..be6379852 100644 --- a/lading_payload/benches/dogstatsd.rs +++ b/lading_payload/benches/dogstatsd.rs @@ -1,5 +1,9 @@ //! Benchmarks for `DogStatsD` payload generation. +// `.expect()` is permitted in benches; workspace denies `clippy::expect_used` +// for production code. +#![allow(clippy::expect_used)] + use criterion::{BatchSize, BenchmarkId, Criterion, Throughput, criterion_group, criterion_main}; use lading_payload::{Serialize, dogstatsd}; use rand::{SeedableRng, rngs::SmallRng}; diff --git a/lading_payload/benches/fluent.rs b/lading_payload/benches/fluent.rs index e94a313c2..964c4ebe0 100644 --- a/lading_payload/benches/fluent.rs +++ b/lading_payload/benches/fluent.rs @@ -1,5 +1,9 @@ //! Benchmarks for Fluent payload generation. +// `.expect()` is permitted in benches; workspace denies `clippy::expect_used` +// for production code. +#![allow(clippy::expect_used)] + use criterion::{BatchSize, BenchmarkId, Criterion, Throughput, criterion_group, criterion_main}; use lading_payload::{Fluent, Serialize}; use rand::{SeedableRng, rngs::SmallRng}; diff --git a/lading_payload/benches/json.rs b/lading_payload/benches/json.rs index f50002399..03dd1b6b2 100644 --- a/lading_payload/benches/json.rs +++ b/lading_payload/benches/json.rs @@ -1,5 +1,9 @@ //! Benchmarks for JSON payload generation. +// `.expect()` is permitted in benches; workspace denies `clippy::expect_used` +// for production code. +#![allow(clippy::expect_used)] + use criterion::{BatchSize, BenchmarkId, Criterion, Throughput, criterion_group, criterion_main}; use lading_payload::{Json, Serialize}; use rand::{SeedableRng, rngs::SmallRng}; diff --git a/lading_payload/benches/opentelemetry_log.rs b/lading_payload/benches/opentelemetry_log.rs index 5091a9beb..c0389862f 100644 --- a/lading_payload/benches/opentelemetry_log.rs +++ b/lading_payload/benches/opentelemetry_log.rs @@ -1,5 +1,9 @@ //! Benchmarks for OpenTelemetry log payload generation. +// `.expect()` is permitted in benches; workspace denies `clippy::expect_used` +// for production code. +#![allow(clippy::expect_used)] + use criterion::{BatchSize, BenchmarkId, Criterion, Throughput, criterion_group, criterion_main}; use lading_payload::{OpentelemetryLogs, Serialize, opentelemetry::log::Config}; use rand::{SeedableRng, rngs::SmallRng}; diff --git a/lading_payload/benches/opentelemetry_metric.rs b/lading_payload/benches/opentelemetry_metric.rs index 587ebeb3a..126ed5775 100644 --- a/lading_payload/benches/opentelemetry_metric.rs +++ b/lading_payload/benches/opentelemetry_metric.rs @@ -1,5 +1,9 @@ //! Benchmarks for OpenTelemetry metric payload generation. +// `.expect()` is permitted in benches; workspace denies `clippy::expect_used` +// for production code. +#![allow(clippy::expect_used)] + use criterion::{BatchSize, BenchmarkId, Criterion, Throughput, criterion_group, criterion_main}; use lading_payload::common::config::ConfRange; use lading_payload::{ diff --git a/lading_payload/benches/opentelemetry_traces.rs b/lading_payload/benches/opentelemetry_traces.rs index 818055638..9e3a7ed53 100644 --- a/lading_payload/benches/opentelemetry_traces.rs +++ b/lading_payload/benches/opentelemetry_traces.rs @@ -1,5 +1,9 @@ //! Benchmarks for OpenTelemetry trace payload generation. +// `.expect()` is permitted in benches; workspace denies `clippy::expect_used` +// for production code. +#![allow(clippy::expect_used)] + use criterion::{BatchSize, BenchmarkId, Criterion, Throughput, criterion_group, criterion_main}; use lading_payload::opentelemetry::trace::{ AttributeConfig, AttributeValueConfig, Config, DatabaseServiceConfig, GrpcServiceConfig, diff --git a/lading_payload/benches/splunk_hec.rs b/lading_payload/benches/splunk_hec.rs index f6c6f332c..720bf8f6c 100644 --- a/lading_payload/benches/splunk_hec.rs +++ b/lading_payload/benches/splunk_hec.rs @@ -1,5 +1,9 @@ //! Benchmarks for Splunk HEC payload generation. +// `.expect()` is permitted in benches; workspace denies `clippy::expect_used` +// for production code. +#![allow(clippy::expect_used)] + use criterion::{BatchSize, BenchmarkId, Criterion, Throughput, criterion_group, criterion_main}; use lading_payload::{Serialize, SplunkHec}; use rand::{SeedableRng, rngs::SmallRng}; diff --git a/lading_payload/benches/syslog.rs b/lading_payload/benches/syslog.rs index 10b51d9e9..eccd6805f 100644 --- a/lading_payload/benches/syslog.rs +++ b/lading_payload/benches/syslog.rs @@ -1,5 +1,9 @@ //! Benchmarks for Syslog 5424 payload generation. +// `.expect()` is permitted in benches; workspace denies `clippy::expect_used` +// for production code. +#![allow(clippy::expect_used)] + use criterion::{BatchSize, BenchmarkId, Criterion, Throughput, criterion_group, criterion_main}; use lading_payload::{Serialize, Syslog5424}; use rand::{SeedableRng, rngs::SmallRng}; diff --git a/lading_payload/benches/templated_json.rs b/lading_payload/benches/templated_json.rs index 5c0f0c0a1..b815513d4 100644 --- a/lading_payload/benches/templated_json.rs +++ b/lading_payload/benches/templated_json.rs @@ -9,6 +9,10 @@ //! which exercises every `ValueGenerator` tag so the numbers reflect realistic //! template complexity. +// `.expect()` is permitted in benches; workspace denies `clippy::expect_used` +// for production code. +#![allow(clippy::expect_used)] + use std::path::Path; use std::time::Duration; diff --git a/lading_payload/benches/trace_agent.rs b/lading_payload/benches/trace_agent.rs index 3915977da..1025e236f 100644 --- a/lading_payload/benches/trace_agent.rs +++ b/lading_payload/benches/trace_agent.rs @@ -1,5 +1,9 @@ //! Benchmarks for Datadog trace agent payload generation. +// `.expect()` is permitted in benches; workspace denies `clippy::expect_used` +// for production code. +#![allow(clippy::expect_used)] + use criterion::{BatchSize, BenchmarkId, Criterion, Throughput, criterion_group, criterion_main}; use lading_payload::{Serialize, trace_agent::v04}; use rand::{SeedableRng, rngs::SmallRng}; diff --git a/lading_payload/src/lib.rs b/lading_payload/src/lib.rs index b6ef8fbe6..3f412a84f 100644 --- a/lading_payload/src/lib.rs +++ b/lading_payload/src/lib.rs @@ -5,6 +5,9 @@ #![deny(clippy::cargo)] #![allow(clippy::cast_precision_loss)] #![allow(clippy::multiple_crate_versions)] +// Quarantine: workspace denies `clippy::expect_used`, but this crate still has +// production `.expect()` sites awaiting cleanup. Remove once cleaned up. +#![allow(clippy::expect_used)] use std::{ io::{self, Write}, diff --git a/lading_throttle/src/lib.rs b/lading_throttle/src/lib.rs index 493a0907e..c1e22c340 100644 --- a/lading_throttle/src/lib.rs +++ b/lading_throttle/src/lib.rs @@ -6,6 +6,9 @@ #![deny(clippy::cargo)] #![allow(clippy::cast_precision_loss)] #![allow(clippy::multiple_crate_versions)] +// Quarantine: workspace denies `clippy::expect_used`, but this crate still has +// production `.expect()` sites awaiting cleanup. Remove once cleaned up. +#![allow(clippy::expect_used)] use async_trait::async_trait; use serde::{Deserialize, Serialize};