m01-ownership
actionbook/rust-skills
Diagnose and fix Rust ownership, borrowing, and lifetime errors by understanding data roles and scope boundaries.
What is m01-ownership?
This skill helps resolve Rust's ownership and lifetime errors (E0382, E0597, E0506, E0507, E0515, E0716, E0106) by reframing them as design questions rather than syntax fixes. Use it when the compiler reports moved values, borrowed references that don't live long enough, or lifetime annotation issues.
- Maps compiler errors to underlying ownership design questions
- Provides decision trees for choosing between move, borrow, clone, Rc, Arc, and Cow patterns
- Traces persistent errors up to domain-layer design or down to implementation patterns
- Distinguishes between symptom fixes and structural redesigns
- References error codes with causes and quick fixes
- Identifies anti-patterns like excessive cloning or fighting the borrow checker
How to install m01-ownership
npx skills add https://github.com/actionbook/rust-skills --skill m01-ownershipHow to use m01-ownership
- 1.When you encounter an ownership error, identify the error code (E0382, E0597, etc.)
- 2.Ask the core question: 'Who should own this data, and for how long?'
- 3.Classify the data role: is it an entity (owned), value object (clone OK), or temporary computation?
- 4.Check the Quick Reference table to select the appropriate pattern (move, &T, &mut T, clone, Rc, Arc, Cow)
- 5.If the error persists after 3 attempts, trace up to m09-domain or m02-resource for design-layer issues
Use cases
- Resolving E0382 'value moved' errors by determining correct data ownership
- Fixing E0597 'borrowed value does not live long enough' by restructuring scope boundaries
- Choosing between Rc/Arc for shared data based on threading requirements
- Deciding when to clone versus redesign ownership for value objects
- Debugging E0506/E0507 mutation conflicts with borrowing rules
- Rust developers learning ownership semantics
- Engineers debugging borrow checker errors in production code
- Teams refactoring code with repeated ownership issues
- Developers transitioning from garbage-collected languages
m01-ownership FAQ
Use clone() only for actual copies of value objects; use Arc<T> for multi-thread shared ownership or Rc<T> for single-thread sharing. Excessive cloning hides design issues.
E0382 occurs when you move a value you still need; E0507 occurs when you try to move out of a borrowed reference. Both signal ownership design problems.
Ask: does the caller need the data after the function? If yes, return owned; if no, take a reference. For shared access, use Rc/Arc instead of cloning.
Use 'static only for truly global data or when you intentionally want to restrict to static references. Most code should use appropriate scoped lifetimes.
If ownership errors repeat, they often signal a domain-layer design issue. Trace up to m09-domain to verify entity/value-object classification, or to m02-resource for smart-pointer choices.
Full instructions (SKILL.md)
Source of truth, from actionbook/rust-skills.
name: m01-ownership description: "CRITICAL: Use for ownership/borrow/lifetime issues. Triggers: E0382, E0597, E0506, E0507, E0515, E0716, E0106, value moved, borrowed value does not live long enough, cannot move out of, use of moved value, ownership, borrow, lifetime, 'a, 'static, move, clone, Copy, 所有权, 借用, 生命周期" user-invocable: false
Ownership & Lifetimes
Layer 1: Language Mechanics
Core Question
Who should own this data, and for how long?
Before fixing ownership errors, understand the data's role:
- Is it shared or exclusive?
- Is it short-lived or long-lived?
- Is it transformed or just read?
Error → Design Question
| Error | Don't Just Say | Ask Instead |
|---|---|---|
| E0382 | "Clone it" | Who should own this data? |
| E0597 | "Extend lifetime" | Is the scope boundary correct? |
| E0506 | "End borrow first" | Should mutation happen elsewhere? |
| E0507 | "Clone before move" | Why are we moving from a reference? |
| E0515 | "Return owned" | Should caller own the data? |
| E0716 | "Bind to variable" | Why is this temporary? |
| E0106 | "Add 'a" | What is the actual lifetime relationship? |
Thinking Prompt
Before fixing an ownership error, ask:
-
What is this data's domain role?
- Entity (unique identity) → owned
- Value Object (interchangeable) → clone/copy OK
- Temporary (computation result) → maybe restructure
-
Is the ownership design intentional?
- By design → work within constraints
- Accidental → consider redesign
-
Fix symptom or redesign?
- If Strike 3 (3rd attempt) → escalate to Layer 2
Trace Up ↑
When errors persist, trace to design layer:
E0382 (moved value)
↑ Ask: What design choice led to this ownership pattern?
↑ Check: m09-domain (is this Entity or Value Object?)
↑ Check: domain-* (what constraints apply?)
| Persistent Error | Trace To | Question |
|---|---|---|
| E0382 repeated | m02-resource | Should use Arc/Rc for sharing? |
| E0597 repeated | m09-domain | Is scope boundary at right place? |
| E0506/E0507 | m03-mutability | Should use interior mutability? |
Trace Down ↓
From design decisions to implementation:
"Data needs to be shared immutably"
↓ Use: Arc<T> (multi-thread) or Rc<T> (single-thread)
"Data needs exclusive ownership"
↓ Use: move semantics, take ownership
"Data is read-only view"
↓ Use: &T (immutable borrow)
Quick Reference
| Pattern | Ownership | Cost | Use When |
|---|---|---|---|
| Move | Transfer | Zero | Caller doesn't need data |
&T | Borrow | Zero | Read-only access |
&mut T | Exclusive borrow | Zero | Need to modify |
clone() | Duplicate | Alloc + copy | Actually need a copy |
Rc<T> | Shared (single) | Ref count | Single-thread sharing |
Arc<T> | Shared (multi) | Atomic ref count | Multi-thread sharing |
Cow<T> | Clone-on-write | Alloc if mutated | Might modify |
Error Code Reference
| Error | Cause | Quick Fix |
|---|---|---|
| E0382 | Value moved | Clone, reference, or redesign ownership |
| E0597 | Reference outlives owner | Extend owner scope or restructure |
| E0506 | Assign while borrowed | End borrow before mutation |
| E0507 | Move out of borrowed | Clone or use reference |
| E0515 | Return local reference | Return owned value |
| E0716 | Temporary dropped | Bind to variable |
| E0106 | Missing lifetime | Add 'a annotation |
Anti-Patterns
| Anti-Pattern | Why Bad | Better |
|---|---|---|
.clone() everywhere | Hides design issues | Design ownership properly |
| Fight borrow checker | Increases complexity | Work with the compiler |
'static for everything | Restricts flexibility | Use appropriate lifetimes |
Leak with Box::leak | Memory leak | Proper lifetime design |
Related Skills
| When | See |
|---|---|
| Need smart pointers | m02-resource |
| Need interior mutability | m03-mutability |
| Data is domain entity | m09-domain |
| Learning ownership concepts | m14-mental-model |
Related skills
More from actionbook/rust-skills and the wider catalog.

m02-resource
Master Rust smart pointers and resource management for correct ownership patterns.

m03-mutability
Resolve Rust mutability conflicts by understanding ownership, borrowing rules, and interior mutability patterns.

m04-zero-cost
Master generics, traits, and zero-cost abstraction—choose static vs. dynamic dispatch correctly.

m05-type-driven
Use Rust's type system to make invalid states unrepresentable at compile time.

m06-error-handling
Master Rust error handling: when to use Result, Option, panic, and how to propagate errors effectively.

m07-concurrency
Master Rust concurrency: threads, async/await, channels, and thread-safe primitives.