Debugging Refactor Snippets
Copy-paste before/after patterns for defects seen repeatedly in Rust code review and incidents.
Recipe
Pick the scenario matching your compiler error or prod symptom; apply after variant; run tests.
Working Example
E0502 borrow conflict
// Before
let r = &data.items[0];
data.items.push(item);
use_ref(r);
// After
let snapshot = data.items[0].clone();
data.items.push(item);
use_val(snapshot);Future not Send
// Before
let cache = Rc<RefCell<Cache>>::new(...);
tokio::spawn(async move { cache.borrow_mut().fill().await });
// After
let cache = Arc::new(tokio::sync::Mutex::new(Cache::new()));
let c = cache.clone();
tokio::spawn(async move { c.lock().await.fill().await });unwrap chain in handler
// Before
async fn get(Path(id): Path<u64>) -> Json<User> {
Json(db.fetch(id).await.unwrap())
}
// After
async fn get(Path(id): Path<u64>) -> Result<Json<User>, ApiError> {
let user = db.fetch(id).await?.ok_or(ApiError::NotFound)?;
Ok(Json(user))
}blocking in async
// Before
std::fs::read_to_string(path)?
// After
tokio::task::spawn_blocking(move || std::fs::read_to_string(path)).await??lossy cast
// Before
let x = user_input as u8;
// After
let x = u8::try_from(user_input).map_err(|_| Error::OutOfRange)?;Deep Dive
Keep team snippet library in internal wiki; link to these canonical fixes. Add test when applying snippet to prevent regression.
Gotchas
- Blind clone fix - perf hit. Fix: revisit ownership after green build.
- Arc everywhere - deadlock risk remains with wrong mutex. Fix: tokio mutex + short locks.
- Snippet without test - regression returns. Fix: minimal unit test per fix.
- Different edition - async trait syntax may differ; verify on 1.97.
- Copy from outdated blog - verify against current axum/sqlx APIs.
Alternatives
| Alternative | Use When | Don't Use When |
|---|---|---|
| rustfix/cargo fix | automated suggestions | semantic redesign |
| Mentor pairing | complex lifetimes | quick snippet ok |
FAQs
contribute snippets?
PR to team playbook when same fix thrice.
snippet vs article?
Articles explain why; snippets are quick apply.
org-specific?
Fork internal section for company crates.
unsafe snippets?
Require extra review; link SAFETY template.
axum 0.8?
Snippets assume axum 0.8 extractors; verify path if on 0.7.
sqlx offline?
Query macros need SQLX_OFFLINE data; separate snippet for CI.
polars collect?
Replace eager collect with lazy plan fix snippet in data team doc.
serde deny unknown?
Add attribute snippet for external API DTOs.
clippy auto?
cargo clippy --fix sometimes replaces snippet manually.
verify fix?
cargo test + clippy + relevant integration test.
Related
- Borrow-Checker Error Scenarios
- Panic & Unwrap Scenarios
- Send/Sync & Thread Errors
- Fighting the Borrow Checker
Stack versions: This page was written for Rust 1.97.0 (edition 2024), Tokio 1.x, Axum 0.8, serde 1.0, sqlx 0.8, clap 4, and Polars 0.46+.