why doesn't Rust allow branches to share the same mutable reference?
This is not a problem limited to async functions. You can't do this even in synchronous, single-threaded code. This is a core principle of the Rust borrow checker, and it prevents stuff like this:
let mut v = vec!["foo".to_owned()];
let first = &v[0];
v.clear();
println!("{first}"); // Use after free!
The fact that both futures will not run at the same time is both irrelevant and potentially not even true! A theoretical async runtime that provides scoped tasks could indeed allow one of the functions to spawn a task on another thread, letting that task use the mutable borrow.
Even if that were not true though, the above synchronous example explains succinctly why this is problematic: one future might take a reference to some data structure that the other future invalidates.
If you really need to have shared mutable access, you will have to do it through an interior mutability mechanism (Mutex, et al).