"implementation of `FnOnce` is not general enough" involving closure, Send requirement, associated type
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 119k
- Forks
- 16.1k
- PR merge metrics
- PR metrics pending
Description
I tried this code:
pub trait Stream: Sized {
type Element;
type Final;
fn consume(self) -> impl std::future::Future<Output = Self::Final> {
std::future::pending()
}
fn map_elements<F, T>(self, f: F) -> MapElements<Self, F>
where
F: FnMut(Self::Element) -> T,
{
MapElements(self, f)
}
}
pub struct MapElements<S, F>(pub S, pub F);
impl<S, F, T> Stream for MapElements<S, F>
where
S: Stream,
F: FnMut(S::Element) -> T,
{
type Element = T;
type Final = S::Final;
}
pub struct SliceStream<'a>(pub &'a [i32]);
impl<'a> Stream for SliceStream<'a> {
type Element = &'a i32;
type Final = ();
}
fn is_send<T: Send>(_t: &T) {}
fn inputs_are_references() {
let fut = async {
SliceStream(&[17, 19]).map_elements(|n: &i32| -> i32 { *n * 2 }).consume().await;
};
is_send(&fut);
}
This is already as minimized as I could get it, but someone else might have better luck.
I expected to see this happen: It compiles
Instead, this happened: It fails with the most inscrutable of errors 🧐
error: implementation of `FnOnce` is not general enough
--> bad-lifetime-696.rs:41:5
|
41 | is_send(&fut);
| ^^^^^^^^^^^^^ implementation of `FnOnce` is not general enough
|
= note: closure with signature `fn(&'0 i32) -> i32` must implement `FnOnce<(&'1 i32,)>`, for any two lifetimes `'0` and `'1`...
= note: ...but it actually implements `FnOnce<(&i32,)>`
Using -Znext-solver=globally the error becomes:
error[E0277]: `{coroutine witness@bad-lifetime-696.rs:38:15: 38:20}` cannot be sent between threads safely
--> bad-lifetime-696.rs:41:5
|
38 | let fut = async {
| ----- within this `{async block@bad-lifetime-696.rs:38:15: 38:20}`
...
41 | is_send(&fut);
| ^^^^^^^^^^^^^ `{coroutine witness@bad-lifetime-696.rs:38:15: 38:20}` cannot be sent between threads safely
|
= help: within `{async block@bad-lifetime-696.rs:38:15: 38:20}`, the trait `Send` is not implemented for `{coroutine witness@bad-lifetime-696.rs:38:15: 38:20}`
note: required because it's used within this `async` block
--> bad-lifetime-696.rs:38:15
|
38 | let fut = async {
| ^^^^^
note: required by a bound in `is_send`
--> bad-lifetime-696.rs:35:15
|
35 | fn is_send<T: Send>(_t: &T) {}
| ^^^^ required by this bound in `is_send`
Meta
rustc --version --verbose:
rustc 1.96.0-nightly (48cc71ee8 2026-03-31)
binary: rustc
commit-hash: 48cc71ee88cd0f11217eced958b9930970da998b
commit-date: 2026-03-31
host: aarch64-apple-darwin
release: 1.96.0-nightly
LLVM version: 22.1.2
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
Start with the minimized reproduction in bad-lifetime-696.rs or the linked Rust Playground, and compare the default solver with -Znext-solver=globally using the reported nightly version. Trace how the closure's associated type, input lifetime, and Send requirement produce the diagnostics; done means the valid example compiles or the compiler reports the underlying failure accurately.
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