rust-lang / rust-lang/rust

higher-ranked-assumptions: "unable to satisfy constraints involving placeholders" when proving Send for AFIT/RPITIT future constrained by HRTB

Open
#157,339 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

-Zassumptions-on-binders A-higher-ranked C-bug fixed-by-higher-ranked-assumptions needs-triage T-types
Dominant language
Rust
Stars
119k
Forks
16.1k
PR merge metrics
PR metrics pending

Description

use std::future::Future;

pub trait Acceptor<'a> {
    fn accept(self) -> impl Future<Output = Self> + Send + 'a;
}

pub trait Stream {
    fn consume<A>(self, acceptor: A) -> impl Future<Output = ()>
    where
        for<'a> A: Acceptor<'a>;
}

fn block_on<F: Send>(_: F) {}

fn check() {
    block_on(async move {
        struct S;
        impl Stream for S {
            async fn consume<A>(self, acceptor: A)
            where
                for<'a> A: Acceptor<'a>,
            {
                acceptor.accept().await;
            }
        }

        struct A;
        impl<'a> Acceptor<'a> for A {
            fn accept(self) -> impl Future<Output = Self> + Send + 'a {
                async { A }
            }
        }

        S.consume(A).await;
    });
}

godbolt

error: unable to satisfy constraints involving placeholders due to unknown implied bounds

error[E0277]: `{coroutine witness@<source>:25:13: 27:14}` cannot be sent between threads safely
  --> <source>:19:5
   |
19 |       block_on(async move {
   |       ^        ---------- within this `{async block@<source>:19:14: 19:24}`
   |  _____|
   | |
20 | |         struct S;
21 | |         impl Stream for S {
22 | |             async fn consume<A>(self, acceptor: A)
...  |
37 | |         S.consume(A).await;
38 | |     });
   | |______^ `{coroutine witness@<source>:25:13: 27:14}` cannot be sent between threads safely
   |
   = help: within `{async block@<source>:19:14: 19:24}`, the trait `Send` is not implemented for `{coroutine witness@<source>:25:13: 27:14}`
note: required because it's used within this `async` fn body
  --> <source>:25:13
   |
25 | /             {
26 | |                 acceptor.accept().await;
27 | |             }
   | |_____________^
note: required because it's used within this `async` block
  --> <source>:19:14
   |
19 |     block_on(async move {
   |              ^^^^^^^^^^
note: required by a bound in `block_on`
  --> <source>:16:16
   |
16 | fn block_on<F: Send>(_: F) {}
   |                ^^^^ required by this bound in `block_on`

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by compiling the minimal reproduction in the issue or the linked Godbolt example and confirm the placeholder-constraint and Send errors. Trace the compiler's handling of the async Stream::consume implementation, higher-ranked Acceptor bounds, and RPITIT futures; done means the example compiles with the outer future satisfying Send.

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
Quiet
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.