about summary refs log tree commit diff
diff options
context:
space:
mode:
authorSamuel Tardieu <sam@rfc1149.net>2025-05-14 23:29:17 +0200
committerSamuel Tardieu <sam@rfc1149.net>2025-05-14 23:38:37 +0200
commitfe4b4e832941b554b802b5ea2bbbe95806c093fe (patch)
treeb1ff73aa1446fde367eddd27165953c9edaf982a
parent4ec219393a48eff84c8c08b854d50a454b8f422c (diff)
downloadrust-fe4b4e832941b554b802b5ea2bbbe95806c093fe.tar.gz
rust-fe4b4e832941b554b802b5ea2bbbe95806c093fe.zip
`mem::size_of_val` is const-stable since Rust 1.85
-rw-r--r--book/src/lint_configuration.md1
-rw-r--r--clippy_config/src/conf.rs1
-rw-r--r--clippy_lints/src/lib.rs2
-rw-r--r--clippy_lints/src/manual_slice_size_calculation.rs19
-rw-r--r--clippy_utils/src/msrvs.rs2
-rw-r--r--tests/ui/manual_slice_size_calculation.fixed12
-rw-r--r--tests/ui/manual_slice_size_calculation.rs12
-rw-r--r--tests/ui/manual_slice_size_calculation.stderr10
8 files changed, 45 insertions, 14 deletions
diff --git a/book/src/lint_configuration.md b/book/src/lint_configuration.md
index 0db4182dbcd..9809e32de8a 100644
--- a/book/src/lint_configuration.md
+++ b/book/src/lint_configuration.md
@@ -836,6 +836,7 @@ The minimum rust version that the project supports. Defaults to the `rust-versio
 * [`manual_repeat_n`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_repeat_n)
 * [`manual_retain`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_retain)
 * [`manual_slice_fill`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_slice_fill)
+* [`manual_slice_size_calculation`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_slice_size_calculation)
 * [`manual_split_once`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_split_once)
 * [`manual_str_repeat`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_str_repeat)
 * [`manual_strip`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_strip)
diff --git a/clippy_config/src/conf.rs b/clippy_config/src/conf.rs
index ad0aea39d41..4ce8d001c2f 100644
--- a/clippy_config/src/conf.rs
+++ b/clippy_config/src/conf.rs
@@ -739,6 +739,7 @@ define_Conf! {
         manual_repeat_n,
         manual_retain,
         manual_slice_fill,
+        manual_slice_size_calculation,
         manual_split_once,
         manual_str_repeat,
         manual_strip,
diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs
index 006145cc623..ec5227018ce 100644
--- a/clippy_lints/src/lib.rs
+++ b/clippy_lints/src/lib.rs
@@ -866,7 +866,7 @@ pub fn register_lints(store: &mut rustc_lint::LintStore, conf: &'static Conf) {
     store.register_late_pass(move |_| Box::new(unnecessary_box_returns::UnnecessaryBoxReturns::new(conf)));
     store.register_late_pass(move |_| Box::new(lines_filter_map_ok::LinesFilterMapOk::new(conf)));
     store.register_late_pass(|_| Box::new(tests_outside_test_module::TestsOutsideTestModule));
-    store.register_late_pass(|_| Box::new(manual_slice_size_calculation::ManualSliceSizeCalculation));
+    store.register_late_pass(|_| Box::new(manual_slice_size_calculation::ManualSliceSizeCalculation::new(conf)));
     store.register_early_pass(move || Box::new(excessive_nesting::ExcessiveNesting::new(conf)));
     store.register_late_pass(|_| Box::new(items_after_test_module::ItemsAfterTestModule));
     store.register_early_pass(|| Box::new(ref_patterns::RefPatterns));
diff --git a/clippy_lints/src/manual_slice_size_calculation.rs b/clippy_lints/src/manual_slice_size_calculation.rs
index b6a4f44b0e4..0c09a47c965 100644
--- a/clippy_lints/src/manual_slice_size_calculation.rs
+++ b/clippy_lints/src/manual_slice_size_calculation.rs
@@ -1,11 +1,13 @@
+use clippy_config::Conf;
 use clippy_utils::diagnostics::span_lint_and_sugg;
+use clippy_utils::msrvs::{self, Msrv};
 use clippy_utils::source::snippet_with_context;
 use clippy_utils::{expr_or_init, is_in_const_context, std_or_core};
 use rustc_errors::Applicability;
 use rustc_hir::{BinOpKind, Expr, ExprKind};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::ty;
-use rustc_session::declare_lint_pass;
+use rustc_session::impl_lint_pass;
 use rustc_span::symbol::sym;
 
 declare_clippy_lint! {
@@ -36,16 +38,25 @@ declare_clippy_lint! {
     complexity,
     "manual slice size calculation"
 }
-declare_lint_pass!(ManualSliceSizeCalculation => [MANUAL_SLICE_SIZE_CALCULATION]);
+impl_lint_pass!(ManualSliceSizeCalculation => [MANUAL_SLICE_SIZE_CALCULATION]);
+
+pub struct ManualSliceSizeCalculation {
+    msrv: Msrv,
+}
+
+impl ManualSliceSizeCalculation {
+    pub fn new(conf: &Conf) -> Self {
+        Self { msrv: conf.msrv }
+    }
+}
 
 impl<'tcx> LateLintPass<'tcx> for ManualSliceSizeCalculation {
     fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
         if let ExprKind::Binary(ref op, left, right) = expr.kind
             && BinOpKind::Mul == op.node
             && !expr.span.from_expansion()
-            // Does not apply inside const because size_of_val is not cost in stable.
-            && !is_in_const_context(cx)
             && let Some((receiver, refs_count)) = simplify(cx, left, right)
+            && (!is_in_const_context(cx) || self.msrv.meets(cx, msrvs::CONST_SIZE_OF_VAL))
         {
             let ctxt = expr.span.ctxt();
             let mut app = Applicability::MachineApplicable;
diff --git a/clippy_utils/src/msrvs.rs b/clippy_utils/src/msrvs.rs
index 223a8649eb3..ec3de2b9dc8 100644
--- a/clippy_utils/src/msrvs.rs
+++ b/clippy_utils/src/msrvs.rs
@@ -24,7 +24,7 @@ macro_rules! msrv_aliases {
 msrv_aliases! {
     1,88,0 { LET_CHAINS }
     1,87,0 { OS_STR_DISPLAY, INT_MIDPOINT, CONST_CHAR_IS_DIGIT }
-    1,85,0 { UINT_FLOAT_MIDPOINT }
+    1,85,0 { UINT_FLOAT_MIDPOINT, CONST_SIZE_OF_VAL }
     1,84,0 { CONST_OPTION_AS_SLICE, MANUAL_DANGLING_PTR }
     1,83,0 { CONST_EXTERN_FN, CONST_FLOAT_BITS_CONV, CONST_FLOAT_CLASSIFY, CONST_MUT_REFS, CONST_UNWRAP }
     1,82,0 { IS_NONE_OR, REPEAT_N, RAW_REF_OP }
diff --git a/tests/ui/manual_slice_size_calculation.fixed b/tests/ui/manual_slice_size_calculation.fixed
index 9df5a2ac5cd..090f0fd30c5 100644
--- a/tests/ui/manual_slice_size_calculation.fixed
+++ b/tests/ui/manual_slice_size_calculation.fixed
@@ -60,9 +60,15 @@ fn main() {
     let _ = size_of::<i32>() * 5 * s_i32.len(); // Ok (MISSED OPPORTUNITY)
 }
 
-const fn _const(s_i32: &[i32]) {
-    // True negative:
-    let _ = s_i32.len() * size_of::<i32>(); // Ok, can't use size_of_val in const
+#[clippy::msrv = "1.85"]
+const fn const_ok(s_i32: &[i32]) {
+    let _ = std::mem::size_of_val(s_i32);
+    //~^ manual_slice_size_calculation
+}
+
+#[clippy::msrv = "1.84"]
+const fn const_before_msrv(s_i32: &[i32]) {
+    let _ = s_i32.len() * size_of::<i32>();
 }
 
 fn issue_14802() {
diff --git a/tests/ui/manual_slice_size_calculation.rs b/tests/ui/manual_slice_size_calculation.rs
index db14d891c80..3c19a0eb5ce 100644
--- a/tests/ui/manual_slice_size_calculation.rs
+++ b/tests/ui/manual_slice_size_calculation.rs
@@ -60,9 +60,15 @@ fn main() {
     let _ = size_of::<i32>() * 5 * s_i32.len(); // Ok (MISSED OPPORTUNITY)
 }
 
-const fn _const(s_i32: &[i32]) {
-    // True negative:
-    let _ = s_i32.len() * size_of::<i32>(); // Ok, can't use size_of_val in const
+#[clippy::msrv = "1.85"]
+const fn const_ok(s_i32: &[i32]) {
+    let _ = s_i32.len() * size_of::<i32>();
+    //~^ manual_slice_size_calculation
+}
+
+#[clippy::msrv = "1.84"]
+const fn const_before_msrv(s_i32: &[i32]) {
+    let _ = s_i32.len() * size_of::<i32>();
 }
 
 fn issue_14802() {
diff --git a/tests/ui/manual_slice_size_calculation.stderr b/tests/ui/manual_slice_size_calculation.stderr
index 00eb32b3e1c..8e9b49e4bf2 100644
--- a/tests/ui/manual_slice_size_calculation.stderr
+++ b/tests/ui/manual_slice_size_calculation.stderr
@@ -56,10 +56,16 @@ LL |     let _ = external!(&[1u64][..]).len() * size_of::<u64>();
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::mem::size_of_val(external!(&[1u64][..]))`
 
 error: manual slice size calculation
-  --> tests/ui/manual_slice_size_calculation.rs:75:13
+  --> tests/ui/manual_slice_size_calculation.rs:65:13
+   |
+LL |     let _ = s_i32.len() * size_of::<i32>();
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::mem::size_of_val(s_i32)`
+
+error: manual slice size calculation
+  --> tests/ui/manual_slice_size_calculation.rs:81:13
    |
 LL |             self.dst.len() * size_of::<u8>()
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::mem::size_of_val(&self.dst)`
 
-error: aborting due to 10 previous errors
+error: aborting due to 11 previous errors