Box::pin use but recursion in an async fn requires boxing error reappears

Hi,

I use to have this function working :

impl MyTrait for MyStruct

     async fn is_valid(&self, res: &mut bool){
            match self {
                MyEnum::A(x)    => { Box::pin(x.is_valid(res)).await; },
                MyEnum::B(x)    => { Box::pin(x.is_valid(res)).await; },
            }
       }
   }
}

// with
pub trait MyTrait{
    async fn is_valid(&self, res: &mut bool>);
}

// with MyEnum::A and MyEnum::B implement alors MyTrait

Now, I want to change is_valid function in MyTrait so it return directly a bool. So I make this change :

async fn is_valid(&self) -> bool {
        let mut res;
        match self {
            MyEnum::A(x)    => { res = Box::pin(x.is_valid().await) },
            MyEnum::B(x)    => { res = Box::pin(x.is_valid().await) },

        }
        *Pin::into_inner(res)
    }

// with
pub trait MyTrait{
    async fn is_valid(&self) -> bool;
}

But now the problem I solve with the first version reappears with the second version...

error[E0733]: recursion in an async fn requires boxing

Can you explain why I don't have problem of recursion anymore in first version and why there is in second ?

You simply moved the Box parens outside the await. If you move them back before the await it works:

enum MyEnum<T, U> {
    A(T),
    B(U),
}

impl<T, U> MyTrait for MyEnum<T, U>
where
    T: MyTrait,
    U: MyTrait,
{
    async fn is_valid(&self) -> bool {
        match self {
            MyEnum::A(x) => Box::pin(x.is_valid()).await,
            MyEnum::B(x) => Box::pin(x.is_valid()).await,
        }
    }
}

pub trait MyTrait {
    async fn is_valid(&self) -> bool;
}
1 Like

Damn... I need to sleep...
Thank you very much.

1 Like