Skip to content

impl has stricter requirements than trait for async fn in traits also incorrectly suggests adding trait bound that already exists #122506

Closed
@nskobelevs

Description

@nskobelevs

I tried this code:

use std::future::Future;

trait Foo {
    fn foo<S>(&self, s: S) -> impl Future<Output = S> + Send;
}

struct Bar;

impl Foo for Bar {
    async fn foo<S>(&self, s: S) -> S
    where
        S: std::marker::Send,
    {
        s
    }
}

which returns the following errors:

error: future cannot be sent between threads safely
  --> src/main.rs:10:5
   |
10 | /     async fn foo<S>(&self, s: S) -> S
11 | |     where
12 | |         S: std::marker::Send,
   | |_____________________________^ future returned by `foo` is not `Send`
   |
note: captured value is not `Send`
  --> src/main.rs:10:28
   |
10 |     async fn foo<S>(&self, s: S) -> S
   |                            ^ has type `S` which is not `Send`
note: required by a bound in `Foo::{opaque#0}`
  --> src/main.rs:4:57
   |
4  |     fn foo<S>(&self, s: S) -> impl Future<Output = S> + Send;
   |                                                         ^^^^ required by this bound in `Foo::{opaque#0}`
help: consider further restricting this bound
   |
12 |         S: std::marker::Send + std::marker::Send,
   |                              +++++++++++++++++++

error[E0276]: impl has stricter requirements than trait
  --> src/main.rs:12:12
   |
4  |     fn foo<S>(&self, s: S) -> impl Future<Output = S> + Send;
   |     --------------------------------------------------------- definition of `foo` from trait
...
12 |         S: std::marker::Send,
   |            ^^^^^^^^^^^^^^^^^ impl has extra requirement `S: Send`

For more information about this error, try `rustc --explain E0276`.

impl has stricter requirements than trait is the correct error and hint here, should the future cannot be sent between threads safely error be surfaced in this case given it's not real cause and it suggests to add a bound that already exists making the output just more confusing.

Meta

This happens on both beta and nightly.
In stable E0276 doesn't even appear at all and it only gives the first error + hint

rustc --version --verbose: (nightly)

rustc 1.78.0-nightly (3b1717c05 2024-03-10)
binary: rustc
commit-hash: 3b1717c052de4a2dbdd3badb0e7a885f40a8ad9e
commit-date: 2024-03-10
host: aarch64-apple-darwin
release: 1.78.0-nightly
LLVM version: 18.1.0

rustc --version --verbose: (beta)

rustc 1.77.0-beta.7 (339fb6965 2024-03-06)
binary: rustc
commit-hash: 339fb6965026c4260d38ab6fd61cfcbecffd8279
commit-date: 2024-03-06
host: aarch64-apple-darwin
release: 1.77.0-beta.7
LLVM version: 17.0.6

Metadata

Metadata

Labels

A-diagnosticsArea: Messages for errors, warnings, and lintsA-suggestion-diagnosticsArea: Suggestions generated by the compiler applied by `cargo fix`C-bugCategory: This is a bug.D-invalid-suggestionDiagnostics: A structured suggestion resulting in incorrect code.S-has-mcveStatus: A Minimal Complete and Verifiable Example has been found for this issueT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions