diff options
Diffstat (limited to 'crates')
-rw-r--r-- | crates/hir/src/lib.rs | 12 | ||||
-rw-r--r-- | crates/hir_ty/src/method_resolution.rs | 10 |
2 files changed, 19 insertions, 3 deletions
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs index a9d3c9156..42a805c57 100644 --- a/crates/hir/src/lib.rs +++ b/crates/hir/src/lib.rs | |||
@@ -51,7 +51,8 @@ use hir_expand::{diagnostics::DiagnosticSink, name::name, MacroDefKind}; | |||
51 | use hir_ty::{ | 51 | use hir_ty::{ |
52 | autoderef, | 52 | autoderef, |
53 | display::{write_bounds_like_dyn_trait_with_prefix, HirDisplayError, HirFormatter}, | 53 | display::{write_bounds_like_dyn_trait_with_prefix, HirDisplayError, HirFormatter}, |
54 | method_resolution, to_assoc_type_id, | 54 | method_resolution::{self, TyFingerprint}, |
55 | to_assoc_type_id, | ||
55 | traits::{FnTrait, Solution, SolutionVariables}, | 56 | traits::{FnTrait, Solution, SolutionVariables}, |
56 | AliasTy, BoundVar, CallableDefId, CallableSig, Canonical, DebruijnIndex, GenericPredicate, | 57 | AliasTy, BoundVar, CallableDefId, CallableSig, Canonical, DebruijnIndex, GenericPredicate, |
57 | InEnvironment, Interner, Obligation, ProjectionPredicate, ProjectionTy, Scalar, Substs, Ty, | 58 | InEnvironment, Interner, Obligation, ProjectionPredicate, ProjectionTy, Scalar, Substs, Ty, |
@@ -1500,13 +1501,20 @@ impl Impl { | |||
1500 | def_crates.iter().for_each(|&id| { | 1501 | def_crates.iter().for_each(|&id| { |
1501 | all.extend(db.inherent_impls_in_crate(id).all_impls().map(Self::from).filter(filter)) | 1502 | all.extend(db.inherent_impls_in_crate(id).all_impls().map(Self::from).filter(filter)) |
1502 | }); | 1503 | }); |
1504 | let fp = TyFingerprint::for_impl(&ty.value); | ||
1503 | for id in def_crates | 1505 | for id in def_crates |
1504 | .iter() | 1506 | .iter() |
1505 | .flat_map(|&id| Crate { id }.reverse_dependencies(db)) | 1507 | .flat_map(|&id| Crate { id }.reverse_dependencies(db)) |
1506 | .map(|Crate { id }| id) | 1508 | .map(|Crate { id }| id) |
1507 | .chain(def_crates.iter().copied()) | 1509 | .chain(def_crates.iter().copied()) |
1508 | { | 1510 | { |
1509 | all.extend(db.trait_impls_in_crate(id).all_impls().map(Self::from).filter(filter)); | 1511 | match fp { |
1512 | Some(fp) => all.extend( | ||
1513 | db.trait_impls_in_crate(id).for_self_ty(fp).map(Self::from).filter(filter), | ||
1514 | ), | ||
1515 | None => all | ||
1516 | .extend(db.trait_impls_in_crate(id).all_impls().map(Self::from).filter(filter)), | ||
1517 | } | ||
1510 | } | 1518 | } |
1511 | all | 1519 | all |
1512 | } | 1520 | } |
diff --git a/crates/hir_ty/src/method_resolution.rs b/crates/hir_ty/src/method_resolution.rs index c7055bee5..57f37ef4b 100644 --- a/crates/hir_ty/src/method_resolution.rs +++ b/crates/hir_ty/src/method_resolution.rs | |||
@@ -44,7 +44,7 @@ impl TyFingerprint { | |||
44 | /// Creates a TyFingerprint for looking up an impl. Only certain types can | 44 | /// Creates a TyFingerprint for looking up an impl. Only certain types can |
45 | /// have impls: if we have some `struct S`, we can have an `impl S`, but not | 45 | /// have impls: if we have some `struct S`, we can have an `impl S`, but not |
46 | /// `impl &S`. Hence, this will return `None` for reference types and such. | 46 | /// `impl &S`. Hence, this will return `None` for reference types and such. |
47 | pub(crate) fn for_impl(ty: &Ty) -> Option<TyFingerprint> { | 47 | pub fn for_impl(ty: &Ty) -> Option<TyFingerprint> { |
48 | let fp = match *ty.interned(&Interner) { | 48 | let fp = match *ty.interned(&Interner) { |
49 | TyKind::Str => TyFingerprint::Str, | 49 | TyKind::Str => TyFingerprint::Str, |
50 | TyKind::Never => TyFingerprint::Never, | 50 | TyKind::Never => TyFingerprint::Never, |
@@ -141,6 +141,14 @@ impl TraitImpls { | |||
141 | } | 141 | } |
142 | } | 142 | } |
143 | 143 | ||
144 | /// Queries all trait impls for the given type. | ||
145 | pub fn for_self_ty(&self, fp: TyFingerprint) -> impl Iterator<Item = ImplId> + '_ { | ||
146 | self.map | ||
147 | .values() | ||
148 | .flat_map(move |impls| impls.get(&None).into_iter().chain(impls.get(&Some(fp)))) | ||
149 | .flat_map(|it| it.iter().copied()) | ||
150 | } | ||
151 | |||
144 | /// Queries all impls of the given trait. | 152 | /// Queries all impls of the given trait. |
145 | pub fn for_trait(&self, trait_: TraitId) -> impl Iterator<Item = ImplId> + '_ { | 153 | pub fn for_trait(&self, trait_: TraitId) -> impl Iterator<Item = ImplId> + '_ { |
146 | self.map | 154 | self.map |