一键导入
rust-borrow-fixer
Diagnose and fix Rust borrow checker and lifetime errors. Paste compiler errors and code — get structured analysis and fixes.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Diagnose and fix Rust borrow checker and lifetime errors. Paste compiler errors and code — get structured analysis and fixes.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
Write Rust code with awareness of known AI pitfalls — ownership, lifetimes, async, module integration, idiomatic patterns. Use when writing new Rust code or implementing features.
Scaffold a new Rust project with correct structure, dependencies, and configuration. Handles workspace, library, and binary crate setup.
Review Rust code for correctness, safety, idiomatic patterns, and common AI-generated code smells. Use when reviewing Rust code quality or before merging.
基于 SOC 职业分类
| name | rust-borrow-fixer |
| description | Diagnose and fix Rust borrow checker and lifetime errors. Paste compiler errors and code — get structured analysis and fixes. |
| user-invocable | true |
Systematically diagnose and resolve borrow checker and lifetime errors. Don't guess — trace the actual ownership and borrowing relationships.
The user has a Rust compilation error related to borrowing, lifetimes, or ownership. They will provide compiler output and/or code.
Identify which category the error falls into:
| Error Pattern | Category | Typical Cause |
|---|---|---|
cannot borrow X as mutable because it is also borrowed as immutable | Aliasing violation | Overlapping & and &mut to same data |
X does not live long enough | Lifetime too short | Borrowed data dropped before borrow ends |
cannot move out of X because it is borrowed | Move-while-borrowed | Trying to take ownership while borrow exists |
lifetime may not live long enough | Lifetime mismatch | Function signature lifetimes don't match body |
missing lifetime specifier | Elision failure | Compiler can't infer lifetimes, needs annotation |
cannot return reference to local variable | Dangling reference | Returning a borrow to stack data |
closure may outlive the current function | Capture lifetime | Closure captures a borrow that doesn't live long enough |
use of moved value | Use-after-move | Value consumed, then used again |
For the problematic variable/reference:
& and &mut)Draw this out mentally or in comments before attempting a fix.
Prefer fixes in this order (least invasive to most):
Reorder statements — Often the simplest fix. Move the mutable borrow after the last use of the immutable borrow.
Narrow borrow scope — Introduce a block { } to limit how long a borrow lives.
// Before: borrows overlap
let x = &data;
let y = &mut data; // ERROR
// After: first borrow ends before second
{ let x = &data; use(x); }
let y = &mut data; // OK
Split the struct — If you're borrowing two fields of the same struct, borrow them individually instead of borrowing &mut self.
// Before: can't borrow self twice
self.process(self.data); // ERROR
// After: borrow fields independently
let data = &self.data;
Self::process_data(data, &mut self.output);
Change function signature — Accept &self instead of &mut self if mutation isn't needed, or take ownership if the caller doesn't need the value anymore.
Use interior mutability — Cell, RefCell, Mutex when shared mutation is genuinely needed (not as a borrow-checker escape hatch).
Restructure ownership — Sometimes the borrow checker is telling you the design is wrong. If data needs to be shared and mutated by multiple owners, rethink who owns what.
Avoid these "fixes":
.clone() without understanding why — this hides the real issue'static lifetime — this almost never solves the actual problemunsafe to bypass the borrow checker — this is always wrongRc<RefCell<T>> — this defeats Rust's compile-time guaranteesAfter applying the fix:
cargo check.// BAD: temporary String dropped, but we borrowed a &str from it
let s: &str = &format!("hello {}", name);
// GOOD: bind the temporary to extend its lifetime
let owned = format!("hello {}", name);
let s: &str = &owned;
// BAD: two mutable borrows
let a = &mut vec[0];
let b = &mut vec[1]; // ERROR even though different indices
// GOOD: use split_at_mut or index once
let (left, right) = vec.split_at_mut(1);
let a = &mut left[0];
let b = &mut right[0];
// BAD: closure captures &local
let local = String::new();
thread::spawn(|| use_string(&local)); // ERROR
// GOOD: move ownership into closure
let local = String::new();
thread::spawn(move || use_string(&local)); // OK, closure owns it