this post was submitted on 22 Jan 2026
20 points (100.0% liked)

Rust

7692 readers
18 users here now

Welcome to the Rust community! This is a place to discuss about the Rust programming language.

Wormhole

!performance@programming.dev

Credits

  • The icon is a modified version of the official rust logo (changing the colors to a gradient and black background)

founded 2 years ago
MODERATORS
 

I just ran into the wonderful error message

the trait is not dyn compatible because method publish_video is async

and boy, what a rabbit hole. I found out about async_trait which resolves this by turning async methods into fn method() -> Pin<Box<dyn Future + Send + 'async_trait>>, but I thought that's what the async fn was syntax sugar for??? Then I ran into this member-only medium post claiming

Rust Async Traits: What Finally Works Now

Async functions in traits shipped. Here’s what that means for your service interfaces.

But I clicked through every rust release since 1.75.0 where impl AsyncTrait was shipped and couldn't find a mention of async. Now I'm just confused (and still using async_trait). Hence the question above...

you are viewing a single comment's thread
view the rest of the comments
[–] TehPers@beehaw.org 2 points 2 days ago* (last edited 2 days ago)

Breaking down what async fn in trait does, it converts it to a fn method() -> impl Future<Output=T>, which breaks further down into fn method() -> Self::__MethodRet where the generated associated type implements Future.

This doesn't work for dyn Trait because of the associated type (and the fact method() needs a dyn-safe self parameter).

Instead, your methods need to return dyn Future in some capacity since that return type doesn't rely on associated types. That's where async_trait comes in. Box<dyn Future<...>> is a dyn-safe boxed future, then it's pinned because async usually generates a self-referential type, and you need to pin it anyway to .poll() the resulting future.

Edit: also, being pedantic, associated types are fine in dyn traits, but you need to specify the type for it (like dyn Blah<Foo=i32>. Even if you could name the return type from an async fn, it'd be different for every impl block, so that's not realistic here.