Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Recursive async functions don't internally implement auto traits #123072

Open
drewtato opened this issue Mar 26, 2024 · 1 comment
Open

Recursive async functions don't internally implement auto traits #123072

drewtato opened this issue Mar 26, 2024 · 1 comment
Labels
A-async-await Area: Async & Await A-auto-traits Area: auto traits (`auto trait Send`) A-traits Area: Trait system AsyncAwait-Triaged Async-await issues that have been triaged during a working group meeting. C-bug Category: This is a bug. fixed-by-next-solver Fixed by the next-generation trait solver, `-Znext-solver`. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. WG-async Working group: Async & await

Comments

@drewtato
Copy link

I tried this code:

fn spawn<F: Send>(_f: F) {}

pub async fn recur() {
    spawn(recur())
}

I expected to see this happen: Compiles successfully.

Instead, this happened:

error: cannot check whether the hidden type of opaque type satisfies auto traits
 --> src/lib.rs:4:11
  |
4 |     spawn(recur())
  |     ----- ^^^^^^^
  |     |
  |     required by a bound introduced by this call
  |
note: opaque type is declared here
 --> src/lib.rs:3:1
  |
3 | pub async fn recur() {
  | ^^^^^^^^^^^^^^^^^^^^
note: this item depends on auto traits of the hidden type, but may also be registering the hidden type. This is not supported right now. You can try moving the opaque type and the item that actually registers a hidden type into a new submodule
 --> src/lib.rs:3:14
  |
3 | pub async fn recur() {
  |              ^^^^^
note: required by a bound in `spawn`
 --> src/lib.rs:1:13
  |
1 | fn spawn<F: Send>(_f: F) {}
  |             ^^^^ required by this bound in `spawn`

It seems like recursive async functions only externally implement auto traits like Send. If you require Send inside its own body, then the function does not compile. This is extra unfortunate because recursive async functions require indirection, and one way of achieving that is by spawning it on a multithreaded executor. The diagnostic is also unhelpful. I'm not sure what it's actually for, but it sounds impossible to apply to this situation. The real solution I found is to manually desugar the async function into a regular function that returns an impl Future + Send:

fn spawn<F: Send>(_f: F) {}

pub fn recur() -> impl core::future::Future<Output = ()> + Send {
    async {
        spawn(recur())
    }
}

However, it would be ideal if the original was allowed as-is.

This is similar to #119727 but without the cycle error.

This was originally found in URLO: With tokio, “future returned by ‘a’ is not ‘Send’”, with tiny example

Meta

rustc 1.79.0-nightly 2024-03-24 from play.rust-lang.org

@drewtato drewtato added the C-bug Category: This is a bug. label Mar 26, 2024
@rustbot rustbot added the needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. label Mar 26, 2024
@workingjubilee workingjubilee added A-traits Area: Trait system T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. A-async-await Area: Async & Await A-auto-traits Area: auto traits (`auto trait Send`) WG-async Working group: Async & await labels Mar 26, 2024
@compiler-errors compiler-errors added fixed-by-next-solver Fixed by the next-generation trait solver, `-Znext-solver`. and removed needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. labels Mar 26, 2024
@traviscross
Copy link
Contributor

@rustbot labels +AsyncAwait-Triaged

We discussed this in the async triage call and, based on the markings by @compiler-errors, it seems this is fixed by the next solver, so we can mark this as triaged.

@rustbot rustbot added the AsyncAwait-Triaged Async-await issues that have been triaged during a working group meeting. label Apr 8, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-async-await Area: Async & Await A-auto-traits Area: auto traits (`auto trait Send`) A-traits Area: Trait system AsyncAwait-Triaged Async-await issues that have been triaged during a working group meeting. C-bug Category: This is a bug. fixed-by-next-solver Fixed by the next-generation trait solver, `-Znext-solver`. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. WG-async Working group: Async & await
Projects
None yet
Development

No branches or pull requests

5 participants