This probably isn't right for Rust, and even then probably can't be done semver compatibly due to the plan to make convert::Infallible = !, but I got wondering about whether the semantics of
impl<T> FromResidual<!> for T {
fn from_residual(residual: !) -> Self {
match residual {}
}
}
make sense.
How would this actually get used? The specific use case I'm pondering is fn spawn(task) -> JoinHandle<Output> style APIs. There's two main ways to expose a join: like thread::JoinHandle::join, returning Result<Output, PanicPayload>, suspending and reifying a potential unwind, or like thread::scope, returning Output and propagating any potential panic.
The idea is that it should be possible to make propagating unwinds as simple as a ? to extract the happy path, with Try::branch resuming the unwind in the branching case. This could even make the syntactic overhead of poisoning mutexes less, theoretically. Sync primitives reaching across task boundaries could surface observed unwinds more simply to downstream systems.
The one major issue I'm now realizing is that you can't both return a simple manipulable Result and have ? with this behavior, because Result has its standard ? behavior. If you need to have an adapter method to access one of the cases anyway, might as well just instead have an easy method call for unwrap_or_else(resume_unwind)[1].
So I guess this idea doesn't really go anywhere. I still think the idea of using ? for lightweight unwind catch and rethrow is interesting, but justifying it as sugar doesn't work if it salts the inspection case.
Yes, the coherence boundary between core and std make providing this impossible for now. âŠī¸