Async: the trait `Draw` cannot be made into an object

Hello,

I am fighting with dyn Trait to get a vector of different types...
When the code is sync, it compiles without any problem, but when I switch to async code, it fails.

I don't want to use an enum and I don't want to move function to another trait: is it possible ?

Thank you in advance for your help.

Your code works if you use the #[async_trait] macro from the async-trait crate (GitHub - dtolnay/async-trait: Type erasure for async trait methods), which creates traits that work with dyn Trait. Using async fn inside traits without this macro, they do not work with dyn Trait.

Playground

Here are the changes I made:

@@ -1,4 +1,7 @@
-pub trait Draw {
+use async_trait::async_trait;
+
+#[async_trait]
+pub trait Draw: Send {
     async fn draw(&mut self);
     async fn draw2(&mut self);
 }
@@ -23,6 +26,7 @@
     pub label: String,
 }
 
+#[async_trait]
 impl Draw for Button {
     async fn draw(&mut self) {
@@ -38,6 +42,7 @@
     options: Vec<String>,
 }
 
+#[async_trait]
 impl Draw for SelectBox {
     async fn draw(&mut self) {
@@ -47,6 +52,7 @@
 }
 
+#[async_trait]
 impl<T: ?Sized + Draw> Draw for Box<T> {
     async fn draw(&mut self) {
         (**self).draw().await
@@ -59,7 +65,7 @@
 async fn main() -> Result<(), ()> {
     println!("Hello, world!");
-    let screen: Screen<Box<dyn Draw>> = Screen {
+    let mut screen: Screen<Box<dyn Draw>> = Screen {
         components: vec![
             Box::new(SelectBox {
2 Likes