m03-mutability

CRITICAL: Use for mutability issues. Triggers: E0596, E0499, E0502, cannot borrow as mutable, already borrowed as immutable, mut, &mut, interior mutability,…

INSTALLATION
npx skills add https://github.com/actionbook/rust-skills --skill m03-mutability
Run in your project or agent environment. Adjust flags if your CLI version differs.

SKILL.md

Mutability

Layer 1: Language Mechanics

Core Question

Why does this data need to change, and who can change it?

Before adding interior mutability, understand:

  • Is mutation essential or accidental complexity?
  • Who should control mutation?
  • Is the mutation pattern safe?

Error → Design Question

ErrorDon't Just SayAsk Instead
E0596"Add mut"Should this really be mutable?
E0499"Split borrows"Is the data structure right?
E0502"Separate scopes"Why do we need both borrows?
RefCell panic"Use try_borrow"Is runtime check appropriate?

Thinking Prompt

Before adding mutability:

-

Is mutation necessary?

  • Maybe transform → return new value
  • Maybe builder → construct immutably

-

Who controls mutation?

  • External caller → &mut T
  • Internal logic → interior mutability
  • Concurrent access → synchronized mutability

-

What's the thread context?

  • Single-thread → Cell/RefCell
  • Multi-thread → Mutex/RwLock/Atomic

Trace Up ↑

When mutability conflicts persist:

E0499/E0502 (borrow conflicts)

    ↑ Ask: Is the data structure designed correctly?

    ↑ Check: m09-domain (should data be split?)

    ↑ Check: m07-concurrency (is async involved?)
Persistent ErrorTrace ToQuestion
Repeated borrow conflictsm09-domainShould data be restructured?
RefCell in asyncm07-concurrencyIs Send/Sync needed?
Mutex deadlocksm07-concurrencyIs the lock design right?

Trace Down ↓

From design to implementation:

"Need mutable access from &self"

    ↓ T: Copy → Cell<T>

    ↓ T: !Copy → RefCell<T>

"Need thread-safe mutation"

    ↓ Simple counters → AtomicXxx

    ↓ Complex data → Mutex<T> or RwLock<T>

"Need shared mutable state"

    ↓ Single-thread: Rc<RefCell<T>>

    ↓ Multi-thread: Arc<Mutex<T>>

Borrow Rules

At any time, you can have EITHER:

├─ Multiple &T (immutable borrows)

└─ OR one &mut T (mutable borrow)

Never both simultaneously.

Quick Reference

PatternThread-SafeRuntime CostUse When
&mut TN/AZeroExclusive mutable access
Cell NoZeroCopy types, no refs needed
RefCell NoRuntime checkNon-Copy, need runtime borrow
Mutex YesLock contentionThread-safe mutation
RwLock YesLock contentionMany readers, few writers
Atomic*YesMinimalSimple types (bool, usize)

Error Code Reference

ErrorCauseQuick Fix
E0596Borrowing immutable as mutableAdd mut or redesign
E0499Multiple mutable borrowsRestructure code flow
E0502&mut while & existsSeparate borrow scopes

Interior Mutability Decision

ScenarioChoose
T: Copy, single-threadCell
T: !Copy, single-threadRefCell
T: Copy, multi-threadAtomicXxx
T: !Copy, multi-threadMutex or RwLock
Read-heavy, multi-threadRwLock
Simple flags/countersAtomicBool, AtomicUsize

Anti-Patterns

Anti-PatternWhy BadBetter
RefCell everywhereRuntime panicsClear ownership design
Mutex for single-threadUnnecessary overheadRefCell
Ignore RefCell panicHard to debugHandle or restructure
Lock inside hot loopPerformance killerBatch operations

Related Skills

WhenSee
Smart pointer choicem02-resource
Thread safetym07-concurrency
Data structure designm09-domain
Anti-patternsm15-anti-pattern
BrowserAct

Let your agent run on any real-world website

Bypass CAPTCHA & anti-bot for free. Start local, scale to cloud.

Explore BrowserAct Skills →

Stop writing automation&scrapers

Install the CLI. Run your first Skill in 30 seconds. Scale when you're ready.

Start free
free · no credit card