Controversial opinion: keeping `Rc` across `await` should not make future `!Send` by itself

A related thing --- another safe abstraction that's prevented by the current thread-local API are library-based stackful coroutines:

I wonder if this points towards some deficiency in thread-local API? And it does seem to me that thread locals are a principle issue here, intuitively, it seems like the following program:

#[derive(Clone, Default)]
struct Context {
    inner: std::rc::Rc<ContextInner>
}

impl Context {
    fn get(&self) -> u32 {
        self.inner.get()
    }
}

type ContextInner = std::cell::Cell<u32>;

async fn f() {
    let context = Context::default();
    g(&context).await;
}

async fn g(context: &Context) {
    let _ = context.get();
    h().await;
    let _ = context.get();
}

async fn h() {

}

#[tokio::main]
async fn main() {
    tokio::spawn(f()).await.unwrap();
}

should be able to execute successfully, the same way a blocking equivalent would just work.

1 Like