Question about async fn in traits: return type is Send or not
⚓ Rust 📅 2025-10-12 👤 surdeus 👁️ 6//! https://blog.rust-lang.org/2023/12/21/async-fn-rpit-in-traits/
#![allow(dead_code)]
use std::marker::PhantomData;
fn assert_send<T: Send>(_: T) {}
trait Foo {
// equal to `foo(&self) -> impl Future<..>`
// not `impl Future<..> + Send`
async fn foo(&self) {}
}
// A is Send
struct A(u8);
impl Foo for A {}
fn handle_a(a: A) {
// no err!!!
// ??? Why a.foo() is Send ???
assert_send(a.foo());
}
// B is !Send
struct B(PhantomData<*mut u8>);
impl Foo for B {}
fn handle_b(b: B) {
// err
// b.foo() is not Send, correct
assert_send(b.foo());
}
fn handle_foo<F>(f: F)
where
F: Foo + Send,
{
// err
// although F is Send, f.foo() is not Send, correct
assert_send(f.foo());
}
In handle_b, b.foo() is not Send, in handle_foo, f.foo() is not Send, this is expected. No matter b/f is Send or not, the future is not Send.
But in handle_a, a.foo() is suprisingly Send, this confuses me a lot. Compared A and B, I can assume that a.foo() is Send since A is Send. But f.foo() is not Send even f is Send, so the assumption is definitely wrong.
What is the key point here, what makes a.foo() Send?
2 posts - 2 participants
🏷️ Rust_feed