rust-lifetimes-borrowing
Skill4 starsChanged 3 months agoApache-2.0View on GitHub
Master Rust ownership, borrowing, and lifetimes. Use when fighting the borrow checker, annotating lifetimes, understanding move semantics, working with references across scopes, or debugging lifetime errors.
We split this skill into the rules it gives an agent
3 rules. About 0 are common, 2 are distinctive, and 1 is very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈2
Distinctive · estimate
This author's own choices. Worth a look.
1
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 22
When the owner goes out of scope, the value is dropped.
- Distinctive: line 65
If there is exactly one input lifetime, it is assigned to all output lifetimes.
- Very specific: line 66
If one of the parameters is &self or &mut self, its lifetime is assigned to all output lifetimes.
≈ “Common” is an estimate: at least 1 in 5 of the 308,232 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Rust Lifetimes & Borrowing
Comprehensive guide to Rust's ownership system, borrowing rules, and lifetime annotations based on The Rust Programming Language, The Rust Reference, and Common Rust Lifetime Misconceptions.
When to Use This Skill
- Borrow checker errors you don't understand
- Deciding between owned types and references
- Annotating lifetime parameters on structs/functions
- Understanding
'static,'a, and elision rules - Working with self-referential structures
- Debugging "does not live long enough" or "borrowed value dropped" errors
Ownership Rules
- Each value has exactly one owner.
- When the owner goes out of scope, the value is dropped.
- Ownership can be transferred (moved) but not duplicated (unless
Copy).
let s1 = String::from("hello");
let s2 = s1; // s1 is MOVED into s2; s1 is invalid
// println!("{s1}"); // compile error: use of moved value
let x: i32 = 5;
let y = x; // i32 is Copy; both x and y are validBorrowing Rules
- You can have either one
&mut Tor any number of&T— never both simultaneously. - References must always be valid (no dangling).
fn calculate(data: &[u32]) -> u32 { data.iter().sum() } // immutable borrow
fn push_item(v: &mut Vec<u32>, x: u32) { v.push(x); } // mutable borrowLifetime Annotations
Lifetimes describe the scope during which a reference is valid. They don't change how long data lives — they help the compiler verify correctness.
// Explicit: both inputs and output share lifetime 'a
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
if x.len() > y.len() { x } else { y }
}
// Struct holding a reference must declare the lifetime
struct Excerpt<'a> {
part: &'a str,
}Lifetime Elision Rules
The compiler infers lifetimes when unambiguous:
- Each reference parameter gets its own lifetime.
- If there is exactly one input lifetime, it is assigned to all output lifetimes.
- If one of the parameters is
&selfor&mut self, its lifetime is assigned to all output lifetimes.
// Elided (compiler infers)
fn first_word(s: &str) -> &str { ... }
// Desugared
fn first_word<'a>(s: &'a str) -> &'a str { ... }Common Misconceptions
1. T only contains owned types — WRONG
T is a superset of &T and &mut T. A generic T can be instantiated with reference types.
fn print_it<T: Display>(val: T) { println!("{val}"); }
print_it(&42); // T = &i32 — perfectly valid2. T: 'static means "lives forever" — WRONG
T: 'static means T can live for the entire program if needed — it contains no short-lived borrows. Owned types like String, Vec<u8> all satisfy 'static.
fn spawn_thread<T: Send + 'static>(val: T) { ... }
spawn_thread(String::from("hi")); // String: 'static ✓3. &'a T and T: 'a are the same — WRONG
T: 'a— T outlives 'a (T's internal references live at least as long as 'a)&'a T— a reference to T that is valid for 'a
4. Lifetimes grow/shrink at runtime — WRONG
Lifetimes are compile-time constructs. They describe static regions of code, not runtime durations.
5. Downgrading &mut to & is always safe — WRONG
Reborrowing as &*x is fine, but holding both the shared reborrow and the original &mut simultaneously is UB-adjacent (compiler rejects it).
6. Closures follow function elision rules — WRONG
Closures do NOT get the same elision rules as fn items. You often need explicit annotations or for<'a> bounds.
Variance
| Type | Variance in 'a | Variance in T |
&'a T | covariant | covariant |
&'a mut T | covariant | invariant |
Box<T> | — | covariant |
Cell<T> | — | invariant |
fn(T) -> U | — | contravariant in T, covariant in U |
Invariance means the lifetime/type cannot be shortened or lengthened — matters for mutable references and interior mutability.
Practical Patterns
Splitting borrows
let mut v = vec![1, 2, 3];
let (left, right) = v.split_at_mut(1);
left[0] = 10;
right[0] = 20; // both halves borrowed mutably — safe because disjointReturning references from methods
impl MyStruct {
fn name(&self) -> &str { &self.name } // ties output lifetime to &self
}NLL (Non-Lexical Lifetimes)
Borrows end at the point of last use, not at the end of the lexical scope:
let mut v = vec![1, 2, 3];
let first = &v[0];
println!("{first}"); // last use of `first`
v.push(4); // OK — `first` borrow already ended (NLL)Reference Map
references/ownership-moves.md— move semantics, Copy, Clone, drop orderreferences/borrowing-rules.md— borrow checker mechanics, reborrowing, two-phase borrowsreferences/lifetime-annotations.md— elision, explicit annotations, HRTBreferences/common-misconceptions.md— the 10 misconceptions with solutions
Key References
In this repository80 other files it gives its agents.
- a11y-accessibility-designSkill
- agentic-ui-patternsSkill
- ai-native-ui-designSkill
- ai-ui-anti-patternsSkill
- ai-ui-heuristicsSkill
- calm-technology-uiSkill
- conversion-growth-designSkill
- cross-platform-designSkill
- dark-mode-designSkill
- data-visualizationSkill
- design-systemsSkill
- design-thinking-processSkill
- error-empty-statesSkill
- ethical-design-patternsSkill
- form-uxSkill
- information-architectureSkill
- interaction-design-patternsSkill
- internationalization-uiSkill
- mobile-touch-designSkill
- modal-classes-lifecycleSkill
- modal-container-imagesSkill
- modal-dicts-queuesSkill
- modal-endpointsSkill
- modal-fundamentalsSkill
- modal-gpu-computeSkill
- modal-networkingSkill
- modal-observabilitySkill
- modal-parallel-executionSkill
- modal-sandboxesSkill
- modal-scaling-performanceSkill
- modal-schedulingSkill
- modal-secretsSkill
- modal-serversSkill
- modal-storageSkill
- modal-web-servingSkill
- modal-workspace-adminSkill
- motion-design-principlesSkill
- notifications-permissionsSkill
- onboarding-uxSkill
- rust-api-designSkill
- rust-async-programmingSkill
- rust-cargo-masterySkill
- rust-cli-applicationsSkill
- rust-clippy-lintsSkill
- rust-closures-iteratorsSkill
- rust-compiler-internalsSkill
- rust-concurrencySkill
- rust-design-patternsSkill
- rust-editionsSkill
- rust-embeddedSkill
- rust-error-handlingSkill
- rust-game-developmentSkill
- rust-macrosSkill
- rust-performanceSkill
- rust-rustdocSkill
- rust-rustup-toolchainSkill
- rust-smart-pointersSkill
- rust-testing-benchmarkingSkill
- rust-type-systemSkill
- rust-unsafe-ffiSkill
- The first 60 shown.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

