I'd like to consider that claim with a bit more nuance, because I find it doesn't hold water for me.
First, let's just deal with the claim that we should block adding another
#[global_*] attribute on a generalization of the problem. Here we must be careful to draw a distinction between two very different arguments:
- Argument 1:
#[global_allocator] was a fundamentally bad idea, and we should not add more APIs like that.
- Argument 2:
#[global_allocator] was a fundamentally good idea, but it should be done in a more principled, generalizable way.
These arguments are very different! The first would present a compelling case (if the underlying claim that its a bad idea has meritt) that we should not add another similar interface. But the second is not so compelling. Such a generalization already has to contend with the existence of
#[global_allocator], what specific additional challenge would
#[global_executor] present to generalizing this concept? That depends on the specific API, which we don't have a proposal for.
What seems much more reasonable would be to insist that
#[global_executor] should not be different from
#[global_allocator] in a way that makes generalizations more difficult. But assuming that holds, its just two deprecated APIs instead of one, both of which presumably are replaced with a macro expansion to the generalized language feature someday.
Second, I just don't think generalizing this concept and enabling libraries other than std to define their own of these is a very good idea. It's everything Rust's choice to use of type classes over ML modules is against.
In the course of working on Rust, we have found a few concerns which are so truly global that they justify going against the trait philosophy and adding these entry points. Memory allocation is one, I claim task execution ought to be another. But these concerns can be counted on one hand from my perspective, and I would want a lot of good practical arguments for why end users should be allowed to create more.