Using `async` functions from synchronous functions (and breaking all the rules)

Even if this was possible, this could only address the OP's need (blocking a sync function until an async one has completed) provided what you call the "specific work" never awaits on jobs that happen to run on the thread that is blocked by the waiting OP's synchronous function.

I don't see how this can be guaranteed, how it is possible to avoid deadlocks.

Even if one "derails" some tasks with alternative executors, those tasks may await on other async functions that must run their jobs on the default pool, or a specific thread, or use continuations in order to wrap god knows what.

The main thread is the first example that comes to my mind. If I run, from the main thread, a sync function that blocks until a Task ends, then any @MainActor or DispatchQueue.main that happens somewhere during the Task's execution will deadlock.

One could imagine a technique to avoid dealocks: only allow sync functions to wait for an async one when they are started from special threads: threads that are guaranteed to never be used by async functions.

But such functions could not be called from async functions. Such functions could not be called from the main thread either. This would just ruin the OP's intent, which is to define public sync apis that wrap async ones (with the ability to freely call them).

Am I right saying that deadlocks are lurking everywhere in this whole forum thread?

@MainAction func f() {
    // It will be very difficult for the Vapor team to guarantee
    // that their async implementation of `doStuff` NEVER
    // happens to schedule something on the main thread,
    // directly or indirectly through third-party or system libraries.
    let x = Vapor.syncDoStuff() // block and cross fingers
}