Use ChatGPT to explain a Rust borrow error before adding clone

A Rust error can disappear when you move a reference's last use before a mutation. Ask ChatGPT to trace the immutable borrow, the conflicting mutation and the later use. Adding clone() may also compile, but it creates a separate value and can change what the program is meant to preserve.

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.

Keep reading