Misleading help suggests `Sync` bound when shareable reference is passed across or into await
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 119k
- Forks
- 16.1k
- PR merge metrics
- PR metrics pending
Description
#59245 results in an error that may be difficult to interpret when structuring generic async code:
use std::fmt::Display;
async fn run(mut state: impl Display) {
do_stuff(&state).await;
// ...
}
async fn do_stuff(state: &impl Display) {
println!("{state}");
}
fn spawn_task<T>(state: T)
where
T: Display + Send + 'static,
{
tokio::spawn(run(state));
}
The compiler (as of 1.82.0-nightly (80eb5a8e9 2024-08-13)) produces this error output:
error[E0277]: `T` cannot be shared between threads safely
--> src/main.rs:16:18
|
16 | tokio::spawn(run(state));
| ------------ ^^^^^^^^^^ `T` cannot be shared between threads safely
| |
| required by a bound introduced by this call
|
= note: required for `&T` to implement `Send`
note: required because it's used within this `async` fn body
--> src/main.rs:8:41
|
8 | async fn do_stuff(state: &impl Display) {
| _________________________________________^
9 | | println!("{state}");
10 | | }
| |_^
note: required because it's used within this `async` fn body
--> src/main.rs:3:35
|
3 | async fn run(state: impl Display) {
| ___________________________________^
4 | | do_stuff(&state).await;
5 | | // ...
6 | | }
| |_^
note: required by a bound in `tokio::spawn`
--> /home/mzabaluev/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.39.2/src/task/spawn.rs:167:21
|
165 | pub fn spawn<F>(future: F) -> JoinHandle<F::Output>
| ----- required by a bound in this function
166 | where
167 | F: Future + Send + 'static,
| ^^^^ required by this bound in `spawn`
help: consider further restricting this bound
|
14 | T: Display + Send + 'static + std::marker::Sync,
| +++++++++++++++++++
A non-restrictive, but also unintuitive, solution is to make the reference passed to do_stuff mutable (i.e. provably exclusive), even though mutability is not required by the function body.
Desired outcome
The help heuristic should detect that the Sync bound arises due to a shareable reference becoming a member of an async closure for which Send is required, and suggest using an exclusive reference as an alternative to restricting the bound.
Originally posted by @mzabaluev in https://github.com/rust-lang/rust/issues/59245#issuecomment-2289520996
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Reproduce the E0277 diagnostic from the example and inspect the compiler's help heuristic for the Sync suggestion when a shareable reference is held across an await. Trace how the async body and required Send bound are reported; done means the diagnostic offers an exclusive-reference alternative instead of only suggesting Sync.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 38/100