|
| 1 | +use clippy_config::Conf; |
1 | 2 | use clippy_utils::diagnostics::span_lint_and_sugg;
|
| 3 | +use clippy_utils::msrvs::{self, Msrv}; |
2 | 4 | use clippy_utils::source::snippet_with_context;
|
3 | 5 | use clippy_utils::{expr_or_init, is_in_const_context, std_or_core};
|
4 | 6 | use rustc_errors::Applicability;
|
5 | 7 | use rustc_hir::{BinOpKind, Expr, ExprKind};
|
6 | 8 | use rustc_lint::{LateContext, LateLintPass};
|
7 | 9 | use rustc_middle::ty;
|
8 |
| -use rustc_session::declare_lint_pass; |
| 10 | +use rustc_session::impl_lint_pass; |
9 | 11 | use rustc_span::symbol::sym;
|
10 | 12 |
|
11 | 13 | declare_clippy_lint! {
|
@@ -36,20 +38,33 @@ declare_clippy_lint! {
|
36 | 38 | complexity,
|
37 | 39 | "manual slice size calculation"
|
38 | 40 | }
|
39 |
| -declare_lint_pass!(ManualSliceSizeCalculation => [MANUAL_SLICE_SIZE_CALCULATION]); |
| 41 | +impl_lint_pass!(ManualSliceSizeCalculation => [MANUAL_SLICE_SIZE_CALCULATION]); |
| 42 | + |
| 43 | +pub struct ManualSliceSizeCalculation { |
| 44 | + msrv: Msrv, |
| 45 | +} |
| 46 | + |
| 47 | +impl ManualSliceSizeCalculation { |
| 48 | + pub fn new(conf: &Conf) -> Self { |
| 49 | + Self { msrv: conf.msrv } |
| 50 | + } |
| 51 | +} |
40 | 52 |
|
41 | 53 | impl<'tcx> LateLintPass<'tcx> for ManualSliceSizeCalculation {
|
42 | 54 | fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
|
43 | 55 | if let ExprKind::Binary(ref op, left, right) = expr.kind
|
44 | 56 | && BinOpKind::Mul == op.node
|
45 | 57 | && !expr.span.from_expansion()
|
46 |
| - // Does not apply inside const because size_of_val is not cost in stable. |
47 |
| - && !is_in_const_context(cx) |
48 | 58 | && let Some((receiver, refs_count)) = simplify(cx, left, right)
|
| 59 | + && (!is_in_const_context(cx) || self.msrv.meets(cx, msrvs::CONST_SIZE_OF_VAL)) |
49 | 60 | {
|
50 | 61 | let ctxt = expr.span.ctxt();
|
51 | 62 | let mut app = Applicability::MachineApplicable;
|
52 |
| - let deref = "*".repeat(refs_count - 1); |
| 63 | + let deref = if refs_count > 0 { |
| 64 | + "*".repeat(refs_count - 1) |
| 65 | + } else { |
| 66 | + "&".into() |
| 67 | + }; |
53 | 68 | let val_name = snippet_with_context(cx, receiver.span, ctxt, "slice", &mut app).0;
|
54 | 69 | let Some(sugg) = std_or_core(cx) else { return };
|
55 | 70 |
|
|
0 commit comments