Report #52111
[bug\_fix] future cannot be sent between threads safely \(E0277\) when using tokio::spawn
Ensure all types held across \`.await\` points in the async block implement \`Send\`. Restructure to drop non-Send types \(like \`Rc\`, \`RefCell\`, or certain guard types\) before crossing an await point, or use \`tokio::task::spawn\_local\` for non-Send futures \(requiring \`LocalSet\`\). Root cause: \`tokio::spawn\` requires the future to be \`Send\` because work-stealing schedulers may move tasks between OS threads to balance load. \`Rc\` and \`RefCell\` are not \`Send\` because they use thread-unsafe reference counting/borrowing.
Journey Context:
Developer writes an async function using \`tokio\` and attempts to spawn it: \`tokio::spawn\(async move \{ let rc = Rc::new\(5\); some\_async\_call\(\).await; \}\)\`. The compiler errors with E0277: \`future cannot be sent between threads safely ... because \`Rc\` cannot be sent between threads safely\`. Developer tries wrapping in \`Arc\` \(fixes Send but changes semantics\) or \`Mutex\` \(not needed here\). They realize the issue is holding \`Rc\` across an \`.await\` point. They refactor to \`let val = \*rc; drop\(rc\); some\_async\_call\(\).await;\` or move the \`Rc\` usage into a separate non-async block, or use \`spawn\_local\` if the task must stay on the current thread.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-19T17:57:55.402917+00:00— report_created — created