diff --git a/CHANGELOG.md b/CHANGELOG.md index 243213ea7..dc7650805 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,14 @@ 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 +- Annotated 11 `lading_payload` functions that intentionally panic on + invariant violations with `#[expect(clippy::expect_used, reason = "...")]`. + Covered: `block::Cache::read_at` (documented `usize`/`u64` overflow + panic), `RandomStringPool::using_handle` and + `StringListPool::using_handle` (handle-type contract), and the + `Display::fmt` impls for `Event`, `ServiceCheck`, `Count`, `Gauge`, + `Timer`, `Dist`, `Set`, `Histogram` (tag-pool handle lookups). No + runtime behavior change; the `.expect()` calls remain in place. - Replaced 6 in-function-invariant `.expect()` sites in `lading_payload` with `.unwrap_or_else(|_| unreachable!("..."))` / `.unwrap_or_else(|| unreachable!("..."))`. Covered: `usize → u32` diff --git a/lading_payload/src/block.rs b/lading_payload/src/block.rs index 62e2b0327..1684b1068 100644 --- a/lading_payload/src/block.rs +++ b/lading_payload/src/block.rs @@ -506,6 +506,10 @@ impl Cache { /// # Panics /// /// Function will panic if reads are larger than machine word bytes wide. + #[expect( + clippy::expect_used, + reason = "u64-to-usize panic on overflow is the documented contract of this function" + )] pub fn read_at(&self, offset: u64, size: usize) -> Bytes { let mut data = BytesMut::with_capacity(size); diff --git a/lading_payload/src/common/strings/random_string_pool.rs b/lading_payload/src/common/strings/random_string_pool.rs index b07bb7f2a..211df2de8 100644 --- a/lading_payload/src/common/strings/random_string_pool.rs +++ b/lading_payload/src/common/strings/random_string_pool.rs @@ -131,6 +131,10 @@ impl Pool for RandomStringPool { } #[inline] + #[expect( + clippy::expect_used, + reason = "handle was issued by this pool earlier in the call chain; a non-PosAndLength handle indicates a cross-pool programming error" + )] fn using_handle(&self, handle: Handle) -> Option<&str> { let (offset, length) = handle .as_pos_and_length() diff --git a/lading_payload/src/common/strings/string_list_pool.rs b/lading_payload/src/common/strings/string_list_pool.rs index 967eb2135..c3470db7d 100644 --- a/lading_payload/src/common/strings/string_list_pool.rs +++ b/lading_payload/src/common/strings/string_list_pool.rs @@ -417,6 +417,10 @@ impl Pool for StringListPool { Some((&self.metric_names[idx], Handle::Index(idx))) } + #[expect( + clippy::expect_used, + reason = "handle was issued by this pool earlier in the call chain; a non-Index handle indicates a cross-pool programming error" + )] fn using_handle(&self, handle: Handle) -> Option<&str> { let idx = handle .as_index() diff --git a/lading_payload/src/dogstatsd/event.rs b/lading_payload/src/dogstatsd/event.rs index e68304f35..6f46a4410 100644 --- a/lading_payload/src/dogstatsd/event.rs +++ b/lading_payload/src/dogstatsd/event.rs @@ -102,6 +102,10 @@ pub struct Event<'a> { } impl fmt::Display for Event<'_> { + #[expect( + clippy::expect_used, + reason = "tag handles were issued by self.pools at event construction; mismatched lookup indicates an internal invariant violation" + )] fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { // _e{,}:|<TEXT>|d:<TIMESTAMP>|h:<HOSTNAME>|p:<PRIORITY>|t:<ALERT_TYPE>|#<TAG_KEY_1>:<TAG_VALUE_1>,<TAG_2> write!( diff --git a/lading_payload/src/dogstatsd/metric.rs b/lading_payload/src/dogstatsd/metric.rs index 71d604460..e78470fe3 100644 --- a/lading_payload/src/dogstatsd/metric.rs +++ b/lading_payload/src/dogstatsd/metric.rs @@ -339,6 +339,10 @@ pub struct Count<'a> { } impl fmt::Display for Count<'_> { + #[expect( + clippy::expect_used, + reason = "tag handles were issued by self.pools at metric construction; mismatched lookup indicates an internal invariant violation" + )] fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { // <METRIC_NAME>:<VALUE>|d|#<TAG_KEY_1>:<TAGVALUE_1>,<TAG_2>|c:<CONTAINER_ID> // <METRIC_NAME>:<VALUE1>:<VALUE2>:<VALUE3>|d|@<SAMPLE_RATE>|#<TAG_KEY_1>:<TAG_VALUE_1>,<TAG_2> @@ -411,6 +415,10 @@ pub struct Gauge<'a> { } impl fmt::Display for Gauge<'_> { + #[expect( + clippy::expect_used, + reason = "tag handles were issued by self.pools at metric construction; mismatched lookup indicates an internal invariant violation" + )] fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { // <METRIC_NAME>:<VALUE>|d|#<TAG_KEY_1>:<TAG_VALUE_1>,<TAG_2>|c:<CONTAINER_ID> // <METRIC_NAME>:<VALUE1>:<VALUE2>:<VALUE3>|d|#<TAG_KEY_1>:<TAG_VALUE_1>,<TAG_2> @@ -479,6 +487,10 @@ pub struct Timer<'a> { } impl fmt::Display for Timer<'_> { + #[expect( + clippy::expect_used, + reason = "tag handles were issued by self.pools at metric construction; mismatched lookup indicates an internal invariant violation" + )] fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { // <METRIC_NAME>:<VALUE>|d|#<TAG_KEY_1>:<TAG_VALUE_1>,<TAG_2>|c:<CONTAINER_ID> // <METRIC_NAME>:<VALUE1>:<VALUE2>:<VALUE3>|d|@<SAMPLE_RATE>|#<TAG_KEY_1>:<TAG_VALUE_1>,<TAG_2> @@ -547,6 +559,10 @@ pub struct Dist<'a> { } impl fmt::Display for Dist<'_> { + #[expect( + clippy::expect_used, + reason = "tag handles were issued by self.pools at metric construction; mismatched lookup indicates an internal invariant violation" + )] fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { // <METRIC_NAME>:<VALUE>|d|#<TAG_KEY_1>:<TAG_VALUE_1>,<TAG_2>|c:<CONTAINER_ID> // <METRIC_NAME>:<VALUE1>:<VALUE2>:<VALUE3>|d|@<SAMPLE_RATE>|#<TAG_KEY_1>:<TAG_VALUE_1>,<TAG_2> @@ -613,6 +629,10 @@ pub struct Set<'a> { } impl fmt::Display for Set<'_> { + #[expect( + clippy::expect_used, + reason = "tag handles were issued by self.pools at metric construction; mismatched lookup indicates an internal invariant violation" + )] fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { // <METRIC_NAME>:<VALUE>|s|#<TAG_KEY_1>:<TAG_VALUE_1>,<TAG_2>|c:<CONTAINER_ID> let name = &self.name; @@ -674,6 +694,10 @@ pub struct Histogram<'a> { } impl fmt::Display for Histogram<'_> { + #[expect( + clippy::expect_used, + reason = "tag handles were issued by self.pools at metric construction; mismatched lookup indicates an internal invariant violation" + )] fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { // <METRIC_NAME>:<VALUE>|h|#<TAG_KEY_1>:<TAG_VALUE_1>,<TAG_2>|c:<CONTAINER_ID> // <METRIC_NAME>:<VALUE1>:<VALUE2>:<VALUE3>|h|@<SAMPLE_RATE>|#<TAG_KEY_1>:<TAG_VALUE_1>,<TAG_2> diff --git a/lading_payload/src/dogstatsd/service_check.rs b/lading_payload/src/dogstatsd/service_check.rs index 1cae4a3de..7df116bdd 100644 --- a/lading_payload/src/dogstatsd/service_check.rs +++ b/lading_payload/src/dogstatsd/service_check.rs @@ -71,6 +71,10 @@ pub struct ServiceCheck<'a> { } impl fmt::Display for ServiceCheck<'_> { + #[expect( + clippy::expect_used, + reason = "tag handles were issued by self.pools at service-check construction; mismatched lookup indicates an internal invariant violation" + )] fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { // _sc|<NAME>|<STATUS>|d:<TIMESTAMP>|h:<HOSTNAME>|#<TAG_KEY_1>:<TAG_VALUE_1>,<TAG_2>|m:<SERVICE_CHECK_MESSAGE> write!(