async-recursion icon indicating copy to clipboard operation
async-recursion copied to clipboard

Applying the '?' expression to an async function doesn't seem to work as intended.

Open myyrakle opened this issue 3 years ago • 3 comments

image I always use ? expressions. However, after adding async, an inconvenient error occurs even if i use the method introduced in other documents or use your library.

image This is a problem that occurs because the Pin and Box are additionally covered. Do you know a neat solution to this?

myyrakle avatar Sep 20 '22 14:09 myyrakle

? appears to be working fine, however something is tripping up on the Box<dyn Error> in the Result (possibly rustc can't infer the type we actually want somewhere). The following reproduction experiences a similar issue:

use std::error::Error;
use thiserror::Error;

#[derive(Debug, Error)]
pub enum MyError {
    #[error("something went wrong")]
    Cool,
}


pub enum Expression {
    Literal(&'static str),
    Nested(Box<Expression>),
    AnotherOne,
}

#[async_recursion::async_recursion]
pub async fn resolve_expression(expression: &Expression) -> Result<i32, Box<dyn Error>> {
    match expression {
        Expression::Literal(_) => Ok(7),
        Expression::Nested(nested) => {
            let x = resolve_expression(nested).await?;
            Ok(x + 1)
        }
        Expression::AnotherOne => Err(Box::new(MyError::Cool)),
    }
}

I'll have a go at fixing this up.

dcchut avatar Sep 20 '22 21:09 dcchut

@myyrakle I still intend to fix this properly, but a temporary workaround might be to explicitly cast your boxed error to Box<dyn Error>. This change applied to my example above looks like:

#[async_recursion::async_recursion]
pub async fn resolve_expression(expression: &Expression) -> Result<i32, Box<dyn Error>> {
    match expression {
        Expression::Literal(_) => Ok(7),
        Expression::Nested(nested) => {
            let x = resolve_expression(nested).await?;
            Ok(x + 1)
        }
        Expression::AnotherOne => Err(Box::new(MyError::Cool) as Box<dyn Error>), // <-- cast error type here
    }
}

dcchut avatar Sep 20 '22 23:09 dcchut

Thanks for your kind reply. I hope you can solve it.

myyrakle avatar Sep 20 '22 23:09 myyrakle