dtolnay / async-trait

Type erasure for async trait methods
Apache License 2.0
1.84k stars 85 forks source link

Send/Sync bounds treated differently than their fully expanded paths #169

Closed compiler-errors closed 3 years ago

compiler-errors commented 3 years ago

When dealing with traits with default implementations, this wiki suggests adding Send and/or Sync bounds onto the trait to allow the trait to be object-safe.

This works great if the Send or Sync bounds are just plain idents, but if you bound the trait by their expanded ::core::marker::{Send, Sync} forms, then the code doesn't remove the bound from the function.

See the expanded code in: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=1345c978f5ae50b27a52cb294f1276ba

pub trait ObjectUnsafe: ::core::marker::Sync {
    #[must_use]
    #[allow(clippy :: let_unit_value, clippy :: type_complexity, clippy ::
            type_repetition_in_bounds, clippy :: used_underscore_binding)]
    fn f<'life0, 'async_trait>(&'life0 self)
     ->
         ::core::pin::Pin<Box<dyn ::core::future::Future<Output = ()> +
                              ::core::marker::Send + 'async_trait>> where
     'life0: 'async_trait, Self: ::core::marker::Sync + 'async_trait {
        Box::pin(async move  { let __self = self; let _: () = { }; })
    }
}

pub trait ObjectSafe: Sync {
    #[must_use]
    #[allow(clippy :: let_unit_value, clippy :: type_complexity, clippy ::
            type_repetition_in_bounds, clippy :: used_underscore_binding)]
    fn f<'life0, 'async_trait>(&'life0 self)
     ->
         ::core::pin::Pin<Box<dyn ::core::future::Future<Output = ()> +
                              ::core::marker::Send + 'async_trait>> where
     'life0: 'async_trait, Self: 'async_trait {
        Box::pin(async move  { let __self = self; let _: () = { }; })
    }
}