async_futures.md (1835B)
1 # Async Futures 2 3 These two signatures are functionally equivalent — `async fn` is just syntactic 4 sugar that the compiler desugars into the explicit `impl Future` form. 5 6 ```rust 7 trait T { 8 async fn f(&self) -> u32; 9 } 10 ``` 11 12 ```rust 13 trait T { 14 fn f(&self) -> impl Future<Output = u32>; 15 } 16 ``` 17 18 ### Question: whats the different between: 19 20 ```rust 21 fn create_user(user: NewUser, pool: &Pool<Postgres>) -> impl std::future::Future<Output = sqlx::Result<User>> + Send; 22 ``` 23 24 and 25 26 ```rust 27 async fn create_user(user: NewUser, pool: &Pool<Postgres>) -> sqlx::Result<User>; 28 ``` 29 30 ## What the compiler does 31 32 When you write: 33 34 ```rust 35 async fn create_user(user: NewUser, pool: &Pool<Postgres>) -> sqlx::Result<User> 36 ``` 37 38 The compiler automatically rewrites it to something like: 39 (rust-lang)[https://blog.rust-lang.org/inside-rust/2022/11/17/async-fn-in-trait-nightly.html] 40 41 ```rust 42 fn create_user(user: NewUser, pool: &Pool<Postgres>) -> impl Future<Output = sqlx::Result<User>> + '_ 43 ``` 44 45 So the first signature in your example is just the explicit version of what 46 async fn does implicitly. 47 48 The + Send detail The most important practical difference in your specific 49 example is the explicit `+ Send` bound on the first signature. This guarantees 50 the returned future is safe to send across threads, which is required when 51 spawning tasks with `tokio::spawn`. With `async fn`, whether the future is 52 `Send` is inferred from the function body — if any non-`Send` type is held 53 across an .await` point, the compiler will reject it without giving you an 54 explicit contract. 55 [rust-lang](https://rust-lang.github.io/async-book/part-guide/more-async-await.html) 56 57 58 So the explicit form is useful when you're writing trait objects, function 59 pointers, or want to enforce `Send` as part of a public API contract, while 60 `async 61 fn` is preferred for everyday use.