dtolnay / async-trait

Type erasure for async trait methods
Apache License 2.0
1.81k stars 84 forks source link

Large number of `#[async_trait]` implementations greatly increases compile time #174

Closed patrickfreed closed 3 years ago

patrickfreed commented 3 years ago

In the test suite for the mongodb crate, we included a large number of #[async_trait] implementations, and this lead to roughly 1 minute of compile type for any incremental change to the tests (via cargo check --tests). Using -Zself-profile, it was determined that nearly all of this time was spent in evaluate_obligation. After converting all of the #[async_trait]s and their implementations to vanilla traits that returned BoxFuture manually, the evaluate_obligation portion of the compilation time was almost completely eliminated.

For more context, see https://github.com/rust-lang/rust/issues/87012#issuecomment-881735995.

I'm not sure if this is a bug in the implementation of async_trait or simply a limitation of doing macro-based traits, but I figured it was worth reporting here. Let me know if there's any more useful information I can provide.

dtolnay commented 3 years ago

https://users.rust-lang.org/t/extremely-slow-compile-times-in-test-suite/61842/2 is the right diagnosis. Something is accidentally quadratic in rustc when this kind of thing happens. If evaluate_obligation is taking nontrivial time that's a rustc bug so https://github.com/rust-lang/rust/issues/87012 is the appropriate place to track it.