diff options
| author | Yudai Fukushima <49578068+granddaifuku@users.noreply.github.com> | 2023-11-08 17:03:07 +0000 |
|---|---|---|
| committer | granddaifuku <daifukuformac@gmail.com> | 2023-11-14 22:05:44 +0900 |
| commit | a9d42e6d6d8ce6fe9789c8d06223b7b2e28ff253 (patch) | |
| tree | 860028758b43fccbae460d4453b5fd6dc923d429 /clippy_lints/src | |
| parent | c3a6b376a43e1ce10c6f17872fd48e99ee294388 (diff) | |
fix: reduce [`manual_memcpy`] indexing when array length is same to loop range
Format refactor: extract function to shrink function length fix: remove cmp to calculate range fix: replace if_chain with let chains
Diffstat (limited to 'clippy_lints/src')
| -rw-r--r-- | clippy_lints/src/loops/manual_memcpy.rs | 47 |
1 files changed, 41 insertions, 6 deletions
diff --git a/clippy_lints/src/loops/manual_memcpy.rs b/clippy_lints/src/loops/manual_memcpy.rs index 89f70519c20..40d56240b9d 100644 --- a/clippy_lints/src/loops/manual_memcpy.rs +++ b/clippy_lints/src/loops/manual_memcpy.rs @@ -178,7 +178,9 @@ fn build_manual_memcpy_suggestion<'tcx>( let dst_base_str = snippet(cx, dst.base.span, "???"); let src_base_str = snippet(cx, src.base.span, "???"); - let dst = if dst_offset == sugg::EMPTY && dst_limit == sugg::EMPTY { + let dst = if (dst_offset == sugg::EMPTY && dst_limit == sugg::EMPTY) + || is_array_length_equal_to_range(cx, start, end, dst.base) + { dst_base_str } else { format!("{dst_base_str}[{}..{}]", dst_offset.maybe_par(), dst_limit.maybe_par()).into() @@ -190,11 +192,13 @@ fn build_manual_memcpy_suggestion<'tcx>( "clone_from_slice" }; - format!( - "{dst}.{method_str}(&{src_base_str}[{}..{}]);", - src_offset.maybe_par(), - src_limit.maybe_par() - ) + let src = if is_array_length_equal_to_range(cx, start, end, src.base) { + src_base_str + } else { + format!("{src_base_str}[{}..{}]", src_offset.maybe_par(), src_limit.maybe_par()).into() + }; + + format!("{dst}.{method_str}(&{src});") } /// a wrapper of `Sugg`. Besides what `Sugg` do, this removes unnecessary `0`; @@ -452,3 +456,34 @@ fn get_loop_counters<'a, 'tcx>( .into() }) } + +fn is_array_length_equal_to_range(cx: &LateContext<'_>, start: &Expr<'_>, end: &Expr<'_>, arr: &Expr<'_>) -> bool { + fn extract_lit_value(expr: &Expr<'_>) -> Option<u128> { + if let ExprKind::Lit(lit) = expr.kind + && let ast::LitKind::Int(value, _) = lit.node + { + Some(value) + } else { + None + } + } + + let arr_ty = cx.typeck_results().expr_ty(arr).peel_refs(); + + if let ty::Array(_, s) = arr_ty.kind() { + let size: u128 = if let Some(size) = s.try_eval_target_usize(cx.tcx, cx.param_env) { + size.into() + } else { + return false; + }; + + let range = match (extract_lit_value(start), extract_lit_value(end)) { + (Some(start_value), Some(end_value)) => end_value - start_value, + _ => return false, + }; + + size == range + } else { + false + } +} |
