Reading through & is half the story. To change a borrowed value, you need a mutable reference: &mut.
&mut — borrow to modify
&mut s lends a reference that can change the value. The function modifies the caller's data in place — no ownership transfer, no return needed. The value itself must be declared mut for this to be allowed; you can't take a mutable reference to something immutable.
The one big restriction
At any given time you may have either any number of immutable references or exactly one mutable reference to a value — never both. While a &mut exists, no other reference (mutable or not) to that value can coexist. This feels strict at first, and it's the single most important rule in the language.
Why this prevents real bugs
Consider iterating a list while something else modifies it — a classic crash (iterator invalidation) in many languages. In Rust the borrow checker refuses: the iteration holds a reference, so a concurrent &mut won't compile. The bug is impossible, not merely discouraged.