Closed
Description
Code
pub trait Foo {
fn bar<F>(&mut self, func: F) -> impl std::future::Future<Output = ()> + Send
where
F: FnMut();
}
struct Baz {}
impl Foo for Baz {
async fn bar<F>(&mut self, _func: F) -> ()
where
F: FnMut() + Send,
{
()
}
}
Current output
$ cargo check
Checking playground v0.0.1 (/playground)
error[E0277]: `F` cannot be sent between threads safely
--> src/lib.rs:10:5
|
10 | / async fn bar<F>(&mut self, _func: F) -> ()
11 | | where
12 | | F: FnMut() + Send,
| |__________________________^ `F` cannot be sent between threads safely
|
note: required by a bound in `<Baz as Foo>::bar`
--> src/lib.rs:12:22
|
10 | async fn bar<F>(&mut self, _func: F) -> ()
| --- required by a bound in this associated function
11 | where
12 | F: FnMut() + Send,
| ^^^^ required by this bound in `<Baz as Foo>::bar`
help: consider further restricting this bound
|
12 | F: FnMut() + Send + std::marker::Send,
| +++++++++++++++++++
error[E0276]: impl has stricter requirements than trait
--> src/lib.rs:12:22
|
2 | / fn bar<F>(&mut self, func: F) -> impl std::future::Future<Output = ()> + Send
3 | | where
4 | | F: FnMut();
| |___________________- definition of `bar` from trait
...
12 | F: FnMut() + Send,
| ^^^^ impl has extra requirement `F: Send`
Some errors have detailed explanations: E0276, E0277.
For more information about an error, try `rustc --explain E0276`.
error: could not compile `playground` (lib) due to 2 previous errors
Desired output
$ cargo check
Checking playground v0.0.1 (/playground)
error[E0277]: `F` cannot be sent between threads safely
--> src/lib.rs:10:5
|
10 | / async fn bar<F>(&mut self, _func: F) -> ()
11 | | where
12 | | F: FnMut() + Send,
| |__________________________^ `F` cannot be sent between threads safely
|
note: required by a bound in `<Baz as Foo>::bar`
--> src/lib.rs:12:22
|
10 | async fn bar<F>(&mut self, _func: F) -> ()
| --- required by a bound in this associated function
11 | where
12 | F: FnMut() + Send,
| ^^^^ required by this bound in `<Baz as Foo>::bar`
help: consider further restricting this bound
|
4 | F: FnMut() + std::marker::Send,
| +++++++++++++++++++
error[E0276]: impl has stricter requirements than trait
--> src/lib.rs:12:22
|
2 | / fn bar<F>(&mut self, func: F) -> impl std::future::Future<Output = ()> + Send
3 | | where
4 | | F: FnMut();
| |___________________- definition of `bar` from trait
...
12 | F: FnMut() + Send,
| ^^^^ impl has extra requirement `F: Send`
Some errors have detailed explanations: E0276, E0277.
For more information about an error, try `rustc --explain E0276`.
error: could not compile `playground` (lib) due to 2 previous errors
Rationale and extra context
rustc
's suggestion to add the std::marker::Send
trait to the impl Foo for Baz
impl block is incorrect -- the function in that block already has the marker trait. Instead, it should suggest to add the trait in the where F: FnMut()
in the trait definition instead, or raise the error on the trait definition instead, because the real error is made there.
If the suggestion is applied, it will result in a second Send
bound added to line 12, which is definitely not correct.
Other cases
No response
Rust Version
$ rustc --version --verbose
rustc 1.79.0 (129f3b996 2024-06-10)
binary: rustc
commit-hash: 129f3b9964af4d4a709d1383930ade12dfe7c081
commit-date: 2024-06-10
host: x86_64-pc-windows-msvc
release: 1.79.0
LLVM version: 18.1.7
Anything else?
This is my first bug on the Rust issue tracker, so apologies if I'm confusing or did something wrong. I've been using Rust for around a year now on and off and it's really such a good language!