# Non-Send Futures

**URL:** <https://internals.rust-lang.org/t/non-send-futures/20016>\
**Category:** language design\
**Created:** [December 11, 2023, 8:59am UTC](https://internals.rust-lang.org/t/non-send-futures/20016 "2023-12-11T08:59:48Z")\
**Posts on this page:** 6\
**Page:** 2

<div class="post-metadata">

**Author:** ![tvallotton](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/tvallotton/32/8153_2.png) [@tvallotton](https://internals.rust-lang.org/u/tvallotton)\
**Post date:** [December 17, 2023, 2:03pm UTC](https://internals.rust-lang.org/t/non-send-futures/20016/21 "2023-12-17T14:03:04Z")

</div>

You know, reading [this](https://github.com/Xudong-Huang/may/blob/master/docs/CLS_instead_of_TLS.md) reminded me of this thread. It is a green threading library that implements a work stealing executor. It seems it cannot soundly implement work stealing because of this same local storage thing.

Maybe if it could be temporarily disabled for `!Send` types at runtime this could be sidestepped. Like, only being disabled in a runtime context.

---

<div class="post-metadata">

**Author:** ![steffahn](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/steffahn/32/13288_2.png) [@steffahn](https://internals.rust-lang.org/u/steffahn)\
**Post date:** [December 17, 2023, 11:36pm UTC](https://internals.rust-lang.org/t/non-send-futures/20016/22 "2023-12-17T23:36:04Z")

</div>

> [@steffahn](#):
>
> Now introducing capsules could in principle work the same. A new effect `capsule` (naming TBD) would mark code that can be executed in the a context of a `Capsule::with` callback. It cannot access legacy `thread_local`, but only a new `thread_local` with a `CSync` constraint. (Whether or not there are ways to still have these two `thread_local` versions merged into one is something I’m not sure yet - probably yes.)
> 
> In either case, the obvious downside is that there’s a lot of code to mark then. This same problem applies with `const` already, it’s slow to mark everything `const` as such, and it’s manual effort.

The analogy to multi-threading isn’t perfect. Unlike for that, for capsules, I think there’s _another sound alternative to the effects-marker approach_ for achieving backwards compatibility:

Simply put, **_all existing types_** could be `CSend + CSync`. This includes … unfortunately … all generic parameters, so you’d need a `?Sized`-style opt-out thing here, too. Yes, marking these cases is a considerable effort, too, but… it _might_ be less bad than introducing an effect for this. I’m not certain.

If all existing types as `CSend + CSync`, it isn’t backwards-incompatible to require `thread_local` contents to be `CSend`.

How could all existing types be `CSend + CSync`, even though I’d proposed the opposite e.g. for `Rc`? The answer is following this argument:

> [@steffahn](#):
>
> Interestingly enough, as `TSend` and `CSend` stand for two orthogonal kinds of memory-boundary, one based on capsules and other thread-like boundaries, like tasks for futures; and one based on physical threads. I’m noticing that it’s _also_ feasible to build … well let’s call the above a `CSync`-limited `Rc` … to build a `TSync`-limited version.

All existing `!Send` or `!Sync` types could be considered still bound to physical-threads, i.e. “`TSync`-limited”, i.e. they would implement `!TSend` and/or `!TSync`, but `CSend + CSync` could be fulfilled. Only new versions of `Rc` and the like would be “`CSync`-limited”. New versions of such types could probably be parametrized somehow, too, so instead of doubling all the API, it would “just” become more generic.

---

<div class="post-metadata">

**Author:** ![fdasfe](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/fdasfe/32/13939_2.png) [@fdasfe](https://internals.rust-lang.org/u/fdasfe)\
**Post date:** [December 19, 2023, 1:11pm UTC](https://internals.rust-lang.org/t/non-send-futures/20016/23 "2023-12-19T13:11:53Z")

</div>

Alternative design: Only add `TSend`/`TSync` and make the current `Sync` and `Send` traits have the corresponding bound. This would be backwards compatible(because no existing traits would have their meaning change) while still allowing developers to relax bounds on functions from `Sync`/`Send` to `TSync`/`TSend`, or to add `Tsync`/`Tsend` impls to existing structs, like `RC`.

---

<div class="post-metadata">

**Author:** ![RalfJung](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/ralfjung/32/2415_2.png) [@RalfJung](https://internals.rust-lang.org/u/RalfJung)\
**Post date:** [December 22, 2023, 3:18pm UTC](https://internals.rust-lang.org/t/non-send-futures/20016/24 "2023-12-22T15:18:24Z")

</div>

> [@steffahn](#):
>
> Simply put, _ **all existing types** _ could be `CSend + CSync`. This includes … unfortunately … all generic parameters, so you’d need a `?Sized`-style opt-out thing here, too. Yes, marking these cases is a considerable effort, too, but… it _might_ be less bad than introducing an effect for this. I’m not certain.
> 
> If all existing types as `CSend + CSync`, it isn’t backwards-incompatible to require `thread_local` contents to be `CSend`.
> 
> How could all existing types be `CSend + CSync`, even though I’d proposed the opposite e.g. for `Rc`? The answer is following this argument:

New auto / `?` traits don't work entirely smoothly either, see [this recent blog post](https://without.boats/blog/changing-the-rules-of-rust/).

---

<div class="post-metadata">

**Author:** ![tvallotton](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/tvallotton/32/8153_2.png) [@tvallotton](https://internals.rust-lang.org/u/tvallotton)\
**Post date:** [February 9, 2024, 4:41pm UTC](https://internals.rust-lang.org/t/non-send-futures/20016/25 "2024-02-09T16:41:06Z")

</div>

Suppose we could somehow allow users to provide an allocation for TLS. Then async runtimes and stackful coroutine runtimes could provide an allocation of their own. TLS would become synonymous to the [`task_local!`](https://docs.rs/tokio/latest/tokio/macro.task_local.html) and [`coroutine_local!`](https://docs.rs/may/latest/may/macro.coroutine_local.html) macros these libs provide. Would the problem go away like this?

I'd imagine that we would then introduce a more restrictive version of TLS that has guaranteed kernel threading semantics, and keep the old one as having user level threads semantics.

---

<div class="post-metadata">

**Author:** ![system](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/system/32/14092_2.png) [@system](https://internals.rust-lang.org/u/system)\
**Post date:** [May 9, 2024, 4:41pm UTC](https://internals.rust-lang.org/t/non-send-futures/20016/26 "2024-05-09T16:41:55Z")

</div>

Closed on May 9, 2024, 4:41pm UTC

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.

[Previous page](https://internals.rust-lang.org/t/non-send-futures/20016.md?page=1)
