cosmian/kms/rust-clone-audit

Claude Code and agent skill by cosmian/kms

Trust tier 3
  • community
Source check pending

Checking that the SKILL.md file is still in the repository.

Detect and eliminate abusive cloning in Rust: treat every `.clone()`, `.to_owned()`, `.to_vec()`, `Cow::into_owned()`, and equivalent owned-duplication call as a potential ownership-design defect, not a free fix for a borrow-checker error. Use when writing, reviewing, or refactoring Rust code, especially when a `.clone()` is added to make code compile.

Install

npx vskill@latest install cosmian/kms/rust-clone-audit

SKILL.md

Rust Clone Audit

Companion to `rust-signature-design` (parameter identity/count) and `rust-refactor` (duplicated code blocks): this skill targets a different axis — the owned-vs-borrowed decision for a single value at the call site where a clone-equivalent call appears. It does not scan for duplicated logic or judge parameter lists.

Goal: identify and aggressively eliminate unnecessary cloning. Must not introduce .clone() merely to satisfy the borrow checker without first exhausting borrowing, lifetime, and ownership-transfer alternatives — the same rule the lint-suppression decision tree in `rust.instructions.md` already applies to clippy::redundant_clone and clippy::clone_on_copy.

Step 1 — Classify every clone-equivalent call

KindCall shapeLegitimate whenKMS example
Handle cloneArc::clone(&x), Rc::clone(&x), x.clone() on Arc/RcAlways — O(1) ref-count bump, not a data copyArc::clone(&recorder.calls) (database_objects.rs:1131), Arc::clone(&barrier) (audit/pgsql.rs:2070)
Thread/task move clonex.clone() right before tokio::spawn/`thread::spawn(move \\...)`The spawned task outlives the current scope and needs its own owned copy—
Copy-type clone.clone() on a Copy type (u32, bool, small enum)Never needed — use the value directly or .copied()/.cloned() on an Option/Iterator—
Borrow-checker-dodge clone.clone() added only to make an error disappear, with no owned-value requirement downstreamNever — restructure the borrow instead (see rust-unofficial/patterns, "Clone to satisfy the borrow checker")—
Field-extraction cloneself.field.clone() returned as an owned value from &selfThe caller genuinely needs ownership (stores it, moves it across an await/thread boundary); otherwise return &T/&str—
API-forced cloneFunction signature takes T but the body only reads it — every caller must .clone() to call itNever by itself — change the parameter to &T (one signature change fixes every call site)—
Cow-eligible clone.to_string()/.to_owned() used because some code paths modify the value and others don'tOnly on the paths that actually modify; otherwise return Cow<'_, str> or the borrow—

Step 2 — Discover

bash
# Clone-equivalent call density per file, worst-first
rg -c '\.clone\(\)|\.to_owned\(\)|\.to_vec\(\)|Cow::into_owned\(\)' --type rust <path> | sort -t: -k2 -rn | head -20
# Clones immediately preceding a borrow-checker-shaped error pattern: same binding re-read right after
rg -n '(\w+)\.clone\(\)' --type rust <path> -B1 | rg -B1 'let \w+ = &?\1\b'
# Clones on Copy-eligible primitives (near-certain waste)
rg -n '\.(u8|u16|u32|u64|usize|i8|i16|i32|i64|isize|bool|f32|f64)\(\)\.clone\(\)|: *(u8|u16|u32|u64|usize|bool)\b.*\.clone\(\)' --type rust <path>
# Functions that take an owned T but only read it (API-forced clone candidates)
rg -n 'fn \w+\([^)]*: (String|Vec<\w+>|HashMap<[^)]+>)[^)]*\)' --type rust <path>

Step 3 — Pick the narrowest fix (checklist, in order)

  1. Can the parameter/field be borrowed instead? Change T → &T (or &str/&[T] for

String/Vec<T>); update every caller — this is often the single-signature fix that removes N call-site clones at once.

  1. Is this `Arc::clone`/`Rc::clone`? Stop — it is already correct, leave it.
  2. Is the value moving into a spawned task/thread/`'static` closure? Clone is necessary;

leave it, optionally add a // moved into spawned task comment if the reason isn't obvious from context.

  1. Does only some code paths need an owned value? Return Cow<'_, T> instead of

unconditionally cloning or unconditionally borrowing.

  1. Is the clone on a `Copy` type? Remove .clone() entirely; use .copied()/.cloned()

for Option<&T>/Iterator<Item = &T> conversions.

  1. Is the clone structurally required (stored in a new owner, e.g. a struct field or a

HashMap key/value, with no shared-ownership type in use)? Keep it — this is legitimate duplication, not abuse. Do not force Arc/Rc onto a type with no concurrent/shared ownership need just to avoid a single clone.

Before / after (illustrative)

rust
// Before — caller forced to clone because the function takes ownership it never needs.
fn log_message(msg: String) {
println!("[LOG] {msg}");
}
log_message(message.clone());
log_message(message);
// After — borrow; zero allocation, callable repeatedly.
fn log_message(msg: &str) {
println!("[LOG] {msg}");
}
log_message(&message);
log_message(&message);

Do not

  • Do not remove a clone that is structurally required (the value is stored in a new owner, or

moved into a spawned task/thread) just to reduce a clone count.

  • Do not replace a single clone with Arc/Rc/RefCell wrapping across a type with no

concurrent or shared-ownership requirement — that trades one allocation for a bigger runtime cost (atomic ops, interior-mutability panics) and a wider API change.

  • Do not silence clippy::redundant_clone / clippy::clone_on_copy with a bare #[allow]

instead of fixing the call site — forbidden on new code per rust.instructions.md.

  • Do not change a crate/kmip wire struct's field from owned to borrowed — KMIP structs are

spec-bound value types serialized independently of caller lifetimes.

  • Do not flag Arc::clone/Rc::clone as defects — they are O(1) ref-count bumps, never a data

copy (see Step 1).

References

Security

  • Security scanPassed, 95 of 100Pattern checks on the skill's files.
  • Model reviewPassed

Quality evaluation

  • Task evaluationNot runNo evaluation yet. Run one in Skill Studio.

Source

Popularity

Repository stars
363
Repository forks
41
7-day trend score
0

Stars and forks are for the whole GitHub repository, not this skill alone. Not refreshed yet.

Works with

Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.

  • Claude Code
  • Cursor
  • GitHub Copilot
  • Windsurf
  • Codex
  • Gemini CLI
  • Cline
  • Amp
  • Roo Code
  • Goose
  • Continue
  • Kilo Code
  • Junie
  • Trae
  • OpenHands
  • Qwen Code
  • AI Agent
  • Tabnine Chat
  • Sourcegraph Cody
  • Amazon Q
  • Firebase Genkit
  • Sweep
  • Devin
  • Phind
  • Mentat
  • Claude Desktop
  • Aider
  • GPT Pilot
  • Plandex
  • bolt.new
  • v0
  • Replit Agent
  • Anse
  • TypingMind
  • BetterChatGPT
  • LibreChat
  • Warp AI
  • Pieces
  • Fig AI
Embed badge
vskill VERIFIED badge
[![vskill VERIFIED](https://verified-skill.com/api/v1/skills/cosmian/kms/rust-clone-audit/badge)](https://verified-skill.com/skills/cosmian/kms/rust-clone-audit)

Something wrong with this skill or its page? Tell us.