Shared a call hands back stays atomic at yes even where it never crosses a threadOpen and answer this issue on GitHub.
note · opened 2026-10-03 · updated 2026-10-06 · 0 comments
At user_parallelism = yes, contracts::sharing lowers a Shared to a plain count where it can prove the value never crosses a thread. ADR-037 D7 says the analysis may only take an atomic away, never add one.
A Shared that came out of a call is never given a plain count today. It is forced to the atomic floor through Fallback::UnseenOrigin (origin_unseen in crates/nikaia/src/contracts/sharing.rs), because the analysis did not see the allocation being made.
That seed was once needed. task::both, the pool the compiler used for automatic statement overlapping, could run a call on a thread of its own and hand its result back. That path is gone:
overlap2..overlap8 poll every branch on the block’s own thread (ADR-292 D4).So the reason a returned Shared crosses has disappeared, while the seed stays. The result is correct (an atomic count is never unsafe, ADR-312 D11), but slower than it needs to be: about 9 ns per clone-and-drop pair (ADR-037 D6).
Shared it returns was allocated there and never crossed. This is a new piece of the sharing contract (ADR-312 D11 keeps that contract at the floor, so the column’s meaning would need a decision), or an intra-package analysis that reads the callee’s body.Shared values out of functions at yes, before building anything.user_parallelism = no already makes every count plain (ADR-312 D10).