Async overloading
Impact
- By default, function definitions can be compiled into either sync or async mode
- Able to overload a function with two variants, one for sync and one for async
Design notes
This is a highly speculative deliverable. However, it would be great if one were able to write code that is neither sync nor sync, but potentially either. Further, one should be able to provide specialized variants that perform the same task but in slightly different ways; this would be particularly useful for primitives like TCP streams.
Monomorphize
The way to think of this is that every function has an implicit generic parameter indicating its scheduler mode. When one writes fn foo()
, that is like creating a generic impl:
#![allow(unused)] fn main() { impl<SM> Fn<(), SM> for Foo where SM: SchedulerMode, { ... } }
When one writes async fn
or sync fn
, those are like providing specific impls:
#![allow(unused)] fn main() { impl Fn<(), AsyncSchedulerMode> for Foo { ... } impl Fn<(), SchedulerMode> for Foo { ... } }
Further, by default, when you call a function, you invoke it in the same scheduler mode as the caller.
Implications for elsewhere
- If we had this feature, then having distinct modules like
use std::io
anduse std::async_io
would not be necessary. - Further, we would want to design our traits and so forth to have a "common subset" of functions that differ only in the presence or absence of the keyword
async
.