Normal languages just sort of call functions on threads - and use locks when there is contention. You certainly can write the same sort of code in Swift - but that is not how async functions work.
The issue with locks is that waiting on a lock could be expensive - depending on the type of lock. And it also ties up the thread. If you have a thread pool you could end up with a lot of threads getting tied up in locks.
Async functions are suspendible. When they encounter a data hazard - the thread is released and allowed to go work on something else. When the conflict clears the function is picked back up and execution continues. Note: the way this is designed means that a _different_ thread may continue execution of the async function, and async functions should assume that they may change threads during execution. But this does prevent stalled threads just waiting on some condition. The compiler needs to extra notation to know your function has been designed around this sort of operation.
Basically: Async functions are not normal functions - they're allowed to be suspendible and may change threads mid execution - hence the extra notation. This improves both performance and safety.