Thanks for this great research! I'm much in agreement with most of the conclusions.
If you maintain a library, what are some of the challenges you’ve encountered in making it operate generically across executors? What could help there?
The biggest challenge I found was the absence of common interfaces, or more precisely the absence of implementations of those interfaces.
I have worked around it by creating/implementing those interfaces myself and wrapping existing executors (async_executors and async_nursery). With those in place I feel it's possible to write executor agnostic libraries. I don't agree that having to spawn in libraries is a rare requirement limited to async drop.
Another big issue is the Sink trait which is quite absent from these discussions. The main issue seems to be the requirement of being able to reserve a slot in the sink. This makes implementing it quite awkward, which means not many types implement it even where it would be appropriate. This makes it hard to abstract out over channels for example.
There isn't much background available about the motivations for the current design, and if it outweighs the downsides, or if there are better alternatives. I have tried to summarize what I have found through web searches in this issue. It's not even clear to me if there are any examples of code that currently uses the Sink trait and relies on the possibility of reserving a slot.
Anyway, I think it's an important interface, and I hope we can work to a consensus of what it should look like.
Do you have ideas for useful bits of polish? Are there small changes or stdlib additions that would make everyday life that much easier?
Sendbasically requires doubling all interfaces, eg.
LocalSpawn. Having to box futures for async trait methods, makes the problem worse.
#[test] async fnwould be a nice bit of polish, although it's easier to work around than the issues above.
I think your propositions for moving things into std are spot on. Personally I don't mind to bump version numbers regularly, but as time goes by the stability will be appreciated by more people, so it's good to anticipate.
I know it's a much more ambitious feature, but it's worth noting how often the phrase "you would need GAT's for that" comes up in user forums. It seems it would be a big enabler for plenty of things. It comes up way more often than async drop or even async trait fn, even though those are still very much desired features.