I think of async to mean "When you call me I won't actually do anything right now, I'll just prepare the data structures to help remember what needs to get done, and return those structures to you, which you can then hand over to an event loop (executor) at your leisure". That return type? That's not actually what is getting returned right now when you call the function... that's what the future returned will eventually resolve to. That level of unexpectedness/magic is hard for me to stomach but in this case I'm ok because the feature provided and the ergonomics are so very good.
I think of await to mean "When this code is combined with all the other code that needs to be executed asynchronously on the event loop, this code will not be able to progress until this thing we are waiting on finishes. The event loop can therefore use this hint to schedule things and keep the processors busy."
I think I built up a good understanding of how this kind of a system works with futures 0.1 and tokio. It took some time but it all clicked together for me. But as for async/await as language features I'm satisfied to just let it be magic. I don't care to look under the covers at this point. I know it's similar to how futures worked, and I trust the rust team weaved it together well.