Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cannot implement async trait that returning "impl Trait" #281

Closed
nicholas-1vbw opened this issue Jan 3, 2025 · 1 comment · Fixed by #282
Closed

cannot implement async trait that returning "impl Trait" #281

nicholas-1vbw opened this issue Jan 3, 2025 · 1 comment · Fixed by #282

Comments

@nicholas-1vbw
Copy link

Since rust 1.75, we are able to write functions that return impl Trait in trait.

I'd like to use it with async_trait, like below:

#[async_trait::async_trait]
pub trait X {
    type Error;
    async fn x(&self) -> Result<impl AsRef<str> + Send + Sync, Self::Error>;
}

The code upon can pass the compilation, but implementing X cannot.

struct T;
#[async_trait::async_trait]
impl X for T {
   type Error = ();
   async fn x(&self) -> Result<impl AsRef<str> + Send + Sync, Self::Error> {
      Ok("Hello World")
   }
}

Complation error:

error[E0562]: `impl Trait` is not allowed in paths
  --> scratch/src/main.rs:11:33
   |
11 |     async fn x(&self) -> Result<impl AsRef<str> + Send + Sync, Self::Error> {
   |                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   |
   = note: `impl Trait` is only allowed in arguments and return types of functions and methods

error[E0562]: `impl Trait` is not allowed in the type of variable bindings
  --> scratch/src/main.rs:11:33
   |
11 |     async fn x(&self) -> Result<impl AsRef<str> + Send + Sync, Self::Error> {
   |                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   |
   = note: `impl Trait` is only allowed in arguments and return types of functions and methods

After inspecting code generated by async_trait macro:

impl X for T {
    type Error = ();
    #[allow(
        elided_named_lifetimes,
        clippy::async_yields_async,
        clippy::diverging_sub_expression,
        clippy::let_unit_value,
        clippy::needless_arbitrary_self_type,
        clippy::no_effect_underscore_binding,
        clippy::shadow_same,
        clippy::type_complexity,
        clippy::type_repetition_in_bounds,
        clippy::used_underscore_binding
    )]
    fn x<'life0, 'async_trait>(
        &'life0 self,
    ) -> ::core::pin::Pin<
        Box<
            dyn ::core::future::Future<
                Output = Result<impl AsRef<str>, Self::Error>,
            > + ::core::marker::Send + 'async_trait,
        >,
    >
    where
        'life0: 'async_trait,
        Self: 'async_trait,
    {
        Box::pin(async move {
            if let ::core::option::Option::Some(__ret) = ::core::option::Option::None::<
                Result<impl AsRef<str> + Send + Sync, Self::Error>,
            > {
                #[allow(unreachable_code)] return __ret;
            }
            let __self = self;
            let __ret: Result<impl AsRef<str> + Send + Sync, Self::Error> = { Ok("Hello World") };
            #[allow(unreachable_code)] __ret
        })
    }
}

Upon inspecting the generated code by the async_trait macro, the impl Trait appears in type annotations, causing the issue. Replacing these occurrences of impl Trait with _ resolves the compilation errors.

Can the macro automatically replace all instances of impl Trait with _ to bypass this issue?

@dtolnay
Copy link
Owner

dtolnay commented Jan 3, 2025

Fixed in 0.1.84.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants