pub trait Blocking {
// Required method
fn run<T, F>(&self, f: F) -> impl Future<Output = Result<T, Cancelled>>
where T: Send + 'static,
F: FnOnce() -> T + Send + 'static;
}Expand description
A separate trait, not a method: getaddrinfo blocks, and wasm and
embedded have no blocking pool at all. The absence of the capability
must be a compile error, not an unimplemented!() in the runtime.
The one place in the whole project where we declare Send ourselves,
and here it’s honest: both tokio::task::spawn_blocking and
blocking::unblock require Send + 'static, and the Blocking
capability doesn’t exist on wasm at all — there’s nothing for it to
infect. The justification is amendment-C5 (docs/exceptions.md), an
amendment separate from C1/C2: those two are about erasing auto-traits in dyn Trait on the Client -> Transport path, whereas here the bound is
declared directly in the signature of a capability trait that simply
doesn’t exist on wasm.
The bounds live in where, not in the generic parameter list fn run<T: Send + …>, so each one can carry its own send-bound-exception
marker on its own line: the CI no-declared-send job matches bound
declarations line by line, and a single shared comment after the
generic list wouldn’t cover it.
Two distinct failure modes of f are not conflated into one channel:
- A panic in
fis a bug in the calling code. It must be re-raised as a panic (std::panic::resume_unwind, with the original payload), not quietly turned into a value that can be?-propagated — otherwise the implementation hides a defect in the caller’s code behind aResult. - The background thread pool going away (for example, the runtime
shutting down while a task is still queued and hasn’t started
running) is not a bug in the calling code, but an ordinary runtime
lifecycle event. The implementation must return
Cancelled, not panic: a library panicking on a normal (if rare) runtime-shutdown scenario would contradict the rest of the project (“no silent no-ops… typed error, never a discarded value” — the same principle applied here, just to failure instead of success).
Required Methods§
Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".