mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-28 12:54:58 +00:00
Auto merge of #16555 - davidbarsky:david/speedup-completions-by-exploiting-orphan-rules, r=Veykril
performance: Speed up Method Completions By Taking Advantage of Orphan Rules (Continues https://github.com/rust-lang/rust-analyzer/pull/16498) This PR speeds up method completions by doing two things without regressing `analysis-stats`[^1]: - Filter candidate traits prior to calling `iterate_path_candidates` by relying on orphan rules (see below for a slightly more in-depth explanation). When generating completions [on `slog::Logger`](5e9e59c312/common/src/ledger.rs (L78)
) in `oxidecomputer/omicron` as a test, this PR halved my completion times—it's now 454ms cold and 281ms warm. Before this PR, it was 808ms cold and 579ms warm. - Inline some of the method candidate checks into `is_valid_method_candidate` and remove some unnecessary visibility checks. This was suggested by `@Veykril` in [this comment](https://github.com/rust-lang/rust-analyzer/pull/16498#issuecomment-1929864427). We filter candidate traits by taking advantage of orphan rules. For additional details, I'll rely on `@WaffleLapkin's` explanation [from Zulip](420942417
): > A type `A` can only implements traits which > 1. Have a blanket implementation (`impl<T> Trait for T {}`) > 2. Have implementation for `A` (`impl Trait for A {}`) > > Blanket implementation can only exist in `Trait`'s crate. Implementation for `A` can only exist in `A`'s or `Trait`'s crate. Big thanks to Waffle for its keen observation! --- I think some additional improvements are possible: - `for_trait_and_self_ty` seemingly does not distinguish between `&T`, `&mut T`, or `T`, resulting in seemingly irrelevant traits like `tokio::io::AsyncWrite` being being included for, e.g., `&slog::Logger`. I don't know they're being considered due to the [autoref/autoderef behavior](a02a219773/crates/hir-ty/src/method_resolution.rs (L945-L962)
), but I wonder if it'd make sense to filter by mutability earlier and not consider trait implementations that require `&mut T` when we only have a `&T`. - The method completions [spend a _lot_ of time in unification](421072356
), and while there might be low-hanging fruit there, it might make more sense to wait for the new trait solver in `rustc`. I dunno. [^1]: The filtering occurs outside of typechecking, after all.
This commit is contained in:
commit
5fead606bc
6 changed files with 243 additions and 4 deletions
|
@ -4239,6 +4239,10 @@ impl Type {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn fingerprint_for_trait_impl(&self) -> Option<TyFingerprint> {
|
||||
TyFingerprint::for_trait_impl(&self.ty)
|
||||
}
|
||||
|
||||
pub(crate) fn canonical(&self) -> Canonical<Ty> {
|
||||
hir_ty::replace_errors_with_variables(&self.ty)
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue