Challenge 2: Fix a Borrow Checker Conflict — Possible Solution ==================================================================== Step 1 — the version that fails to compile: fn main() { let mut s = String::from("hello"); let r1 = &s; let r2 = &mut s; println!("{} {}", r1, r2); } THE EXACT COMPILER ERROR (paraphrased from rustc's real message): error[E0502]: cannot borrow `s` as mutable because it is also borrowed as immutable --> src/main.rs:5:14 | 4 | let r1 = &s; | -- immutable borrow occurs here 5 | let r2 = &mut s; | ^^^^^^ mutable borrow occurs here 6 | println!("{} {}", r1, r2); | -- immutable borrow later used here Step 2 — the fix, ensuring r1's last use happens before r2 is created: fn main() { let mut s = String::from("hello"); let r1 = &s; println!("{}", r1); // r1's last use — its borrow effectively ends here let r2 = &mut s; println!("{}", r2); } WHY THIS WORKS AS AN ANSWER ------------------------------ The first version has r1 (immutable) and r2 (mutable) both ALIVE at the same time — r1 is still used in the final println!, which means its borrow spans right up to that point, directly overlapping with r2's mutable borrow. This is exactly the mutable-XOR-immutable violation this chapter's borrow checker rule forbids. The fix uses non-lexical lifetimes (this chapter's closing warn-box): moving r1's only use (its own println!) to happen BEFORE r2 is even created means r1's borrow is considered "over" by the time r2 borrows s mutably — the two borrows no longer overlap in time, even though both variables are still technically in scope for the rest of the function. The borrow checker tracks actual USE, not just lexical scope, which is what makes this reordering a valid fix.