I think that confuses paradigm with configuration. Say, if one thread waits on another to finish, that doesn't mean the code suddenly becomes "single-threaded", it just means your two threads are in a serialized configuration in that instance. Similarly, when async code becomes serialized, it doesn't cease to be async: the scaffolding to make it concurrent is there, it's just unused in that specific configuration.
For example, C# uses this syntax:
await readA();
await readB();
when you have these two lines, the first I/O operation still yields control to a main executor during `await`, and other web requests can continue executing in the same thread while "readA()" is running. It's inherently concurrent, not in the scope of your two lines, but in the scope of your program.
Is Zig any different?