In this small example, a label starts as Draft. You want to display that original label and then append ready to the same string. The order of those two actions determines whether the immutable borrow overlaps the mutation.
Keep the failing example small
This authored program deliberately fails to compile:
fn main() {
let mut label = String::from("Draft");
let original = &label;
label.push_str(" ready");
println!("Before: {original}");
println!("After: {label}");
}
original borrows label immutably. push_str needs mutable access, but the program uses original afterward. The compiler therefore rejects this overlapping access; changing the variable name does not resolve it.
The Rust book's borrowing chapter, checked October 24, 2026, explains that a reference's scope can end at its last use before the surrounding block ends. Use that rule to inspect the order, rather than assuming every reference remains active until the closing brace.
End the read before changing the string
If displaying the original text first is the intended behavior, move that display before the mutation:
fn main() {
let mut label = String::from("Draft");
let original = &label;
println!("Before: {original}");
label.push_str(" ready");
println!("After: {label}");
}
The expected output is:
Before: Draft
After: Draft ready
The immutable reference is no longer used when push_str runs. No copied string is needed for this sequence.
With Rust installed, save the failing and repaired versions in separate files. Check your compiler with rustc --version. For a file named borrow_fixed.rs, compile it with rustc --edition=2021 borrow_fixed.rs, then run the generated executable using your platform's command. Keep the error from the failing version alongside the repaired output.
Decide whether you need an old value later
Suppose the real requirement changes: first update the string, then display both its old and new contents. Reordering the old display no longer fulfills that requirement. An owned snapshot can express it:
fn main() {
let mut label = String::from("Draft");
let original = label.clone();
label.push_str(" ready");
println!("Before: {original}");
println!("After: {label}");
}
Here original owns another string. A bare let original = label; would move ownership instead, leaving label unavailable for this later mutation. Borrowing, moving and cloning solve different requirements; choose after deciding whether the old contents must survive independently.
Ask for the borrow trace and both behavior choices
Explain this exact Rust compiler error.
rustc --version: [PASTE]
Code and complete diagnostic: [PASTE]
Intended output order: [DESCRIBE]
Identify the immutable borrow, attempted mutable access and final
use that creates the conflict. Show the smallest repair when the
old value may be printed before mutation. Then explain what must
change if I need the old contents after mutation instead.
Distinguish a reference, an ownership move and an owned clone.
Do not add unsafe code, lifetime annotations or clone every value.
Give expected output and commands for my OS; distinguish predictions
from actual compiler results.
OpenAI's prompting guidance supports providing the exact example and intended result. Supplying the output order prevents a compiling rewrite from quietly changing the task.
For a larger failure, the debugging guide explains how to preserve a small reproduction. Before adopting the repair, confirm which value each later statement should observe. The useful outcome is code whose ownership matches that requirement, with the compiler diagnostic and output checked on the same version.