pub fn block_on<F>(fut: F) -> F::OutputExpand description
Sync-to-async bridge. Forwards to the shared multi-thread
runtime’s block_on. Used by the TUI input loop and by App
methods that need to wait on a crate::Pending from outside
an async context.
Three execution contexts to handle:
- Non-tokio caller (sync
main, sync test): no current handle, fall through totarget.block_on(fut)directly. - Multi-thread tokio caller (e.g. spawned task on the
shared LSP runtime): relinquish the worker via
[
tokio::task::block_in_place] so other tasks keep running while we block ontarget. - Non-multi-thread tokio caller (e.g. the editor actor’s
dedicated
current_threadruntime per slice3c.final.E.swap):block_in_placepanics here because the current runtime isn’tMultiThread; we instead escape to a fresh OS thread viastd::thread::scopeand drive the future ontargetfrom outside any tokio context.
The third case is the fix for slice 3c.fixup.actor-block-on:
before this, block_on calls from inside the editor actor’s
runtime (file save, document.dispatch_with_cancel, LSP
completion-resolve, code-action apply, synthetic-buffer seed)
panicked with “can call blocking only when running on the
multi-threaded runtime” — caught only by cargo bench
(release builds), not by cargo test (which preserves direct
App.editor: Editor via the cfg(test) escape hatch and
thus never spawns the actor).
Send bound: F: Send + F::Output: Send are required by
std::thread::scope in the third case. Every existing caller
satisfies these (Arc-backed handles, owned move-captures); if
a future caller doesn’t, the type system catches it at the
call site.