From 4ec219393a48eff84c8c08b854d50a454b8f422c Mon Sep 17 00:00:00 2001 From: Samuel Tardieu Date: Wed, 14 May 2025 23:17:56 +0200 Subject: [PATCH] Fix size computation when element is a slice In this case, a dereference is needed before using `mem::size_of_val()`. --- clippy_lints/src/manual_slice_size_calculation.rs | 6 +++++- tests/ui/manual_slice_size_calculation.fixed | 13 +++++++++++++ tests/ui/manual_slice_size_calculation.rs | 13 +++++++++++++ tests/ui/manual_slice_size_calculation.stderr | 8 +++++++- 4 files changed, 38 insertions(+), 2 deletions(-) diff --git a/clippy_lints/src/manual_slice_size_calculation.rs b/clippy_lints/src/manual_slice_size_calculation.rs index 2dad0fa4925e..b6a4f44b0e49 100644 --- a/clippy_lints/src/manual_slice_size_calculation.rs +++ b/clippy_lints/src/manual_slice_size_calculation.rs @@ -49,7 +49,11 @@ impl<'tcx> LateLintPass<'tcx> for ManualSliceSizeCalculation { { let ctxt = expr.span.ctxt(); let mut app = Applicability::MachineApplicable; - let deref = "*".repeat(refs_count - 1); + let deref = if refs_count > 0 { + "*".repeat(refs_count - 1) + } else { + "&".into() + }; let val_name = snippet_with_context(cx, receiver.span, ctxt, "slice", &mut app).0; let Some(sugg) = std_or_core(cx) else { return }; diff --git a/tests/ui/manual_slice_size_calculation.fixed b/tests/ui/manual_slice_size_calculation.fixed index 294d1e1506de..9df5a2ac5cd5 100644 --- a/tests/ui/manual_slice_size_calculation.fixed +++ b/tests/ui/manual_slice_size_calculation.fixed @@ -64,3 +64,16 @@ const fn _const(s_i32: &[i32]) { // True negative: let _ = s_i32.len() * size_of::(); // Ok, can't use size_of_val in const } + +fn issue_14802() { + struct IcedSlice { + dst: [u8], + } + + impl IcedSlice { + fn get_len(&self) -> usize { + std::mem::size_of_val(&self.dst) + //~^ manual_slice_size_calculation + } + } +} diff --git a/tests/ui/manual_slice_size_calculation.rs b/tests/ui/manual_slice_size_calculation.rs index ae5225663139..db14d891c80b 100644 --- a/tests/ui/manual_slice_size_calculation.rs +++ b/tests/ui/manual_slice_size_calculation.rs @@ -64,3 +64,16 @@ const fn _const(s_i32: &[i32]) { // True negative: let _ = s_i32.len() * size_of::(); // Ok, can't use size_of_val in const } + +fn issue_14802() { + struct IcedSlice { + dst: [u8], + } + + impl IcedSlice { + fn get_len(&self) -> usize { + self.dst.len() * size_of::() + //~^ manual_slice_size_calculation + } + } +} diff --git a/tests/ui/manual_slice_size_calculation.stderr b/tests/ui/manual_slice_size_calculation.stderr index f07e97a1c863..00eb32b3e1c3 100644 --- a/tests/ui/manual_slice_size_calculation.stderr +++ b/tests/ui/manual_slice_size_calculation.stderr @@ -55,5 +55,11 @@ error: manual slice size calculation LL | let _ = external!(&[1u64][..]).len() * size_of::(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::mem::size_of_val(external!(&[1u64][..]))` -error: aborting due to 9 previous errors +error: manual slice size calculation + --> tests/ui/manual_slice_size_calculation.rs:75:13 + | +LL | self.dst.len() * size_of::() + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::mem::size_of_val(&self.dst)` + +error: aborting due to 10 previous errors