aboutsummaryrefslogtreecommitdiff
path: root/crates/hir/src/lib.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/hir/src/lib.rs')
-rw-r--r--crates/hir/src/lib.rs58
1 files changed, 44 insertions, 14 deletions
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs
index 25e5bfb01..c5161dadd 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};
51use hir_ty::{ 51use 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,
@@ -695,8 +696,8 @@ impl Adt {
695 } 696 }
696 } 697 }
697 698
698 pub fn krate(self, db: &dyn HirDatabase) -> Option<Crate> { 699 pub fn krate(self, db: &dyn HirDatabase) -> Crate {
699 Some(self.module(db).krate()) 700 self.module(db).krate()
700 } 701 }
701 702
702 pub fn name(self, db: &dyn HirDatabase) -> Name { 703 pub fn name(self, db: &dyn HirDatabase) -> Name {
@@ -1018,8 +1019,8 @@ impl TypeAlias {
1018 Module { id: self.id.lookup(db.upcast()).module(db.upcast()) } 1019 Module { id: self.id.lookup(db.upcast()).module(db.upcast()) }
1019 } 1020 }
1020 1021
1021 pub fn krate(self, db: &dyn HirDatabase) -> Option<Crate> { 1022 pub fn krate(self, db: &dyn HirDatabase) -> Crate {
1022 Some(self.module(db).krate()) 1023 self.module(db).krate()
1023 } 1024 }
1024 1025
1025 pub fn type_ref(self, db: &dyn HirDatabase) -> Option<TypeRef> { 1026 pub fn type_ref(self, db: &dyn HirDatabase) -> Option<TypeRef> {
@@ -1482,9 +1483,44 @@ impl Impl {
1482 1483
1483 inherent.all_impls().chain(trait_.all_impls()).map(Self::from).collect() 1484 inherent.all_impls().chain(trait_.all_impls()).map(Self::from).collect()
1484 } 1485 }
1485 pub fn for_trait(db: &dyn HirDatabase, krate: Crate, trait_: Trait) -> Vec<Impl> { 1486
1486 let impls = db.trait_impls_in_crate(krate.id); 1487 pub fn all_for_type(db: &dyn HirDatabase, Type { krate, ty }: Type) -> Vec<Impl> {
1487 impls.for_trait(trait_.id).map(Self::from).collect() 1488 let def_crates = match ty.value.def_crates(db, krate) {
1489 Some(def_crates) => def_crates,
1490 None => return Vec::new(),
1491 };
1492
1493 let filter = |impl_def: &Impl| {
1494 let target_ty = impl_def.target_ty(db);
1495 let rref = target_ty.remove_ref();
1496 ty.value.equals_ctor(rref.as_ref().map_or(&target_ty.ty.value, |it| &it.ty.value))
1497 };
1498
1499 let mut all = Vec::new();
1500 def_crates.into_iter().for_each(|id| {
1501 all.extend(db.inherent_impls_in_crate(id).all_impls().map(Self::from).filter(filter))
1502 });
1503 let fp = TyFingerprint::for_impl(&ty.value);
1504 for id in db.crate_graph().iter() {
1505 match fp {
1506 Some(fp) => all.extend(
1507 db.trait_impls_in_crate(id).for_self_ty(fp).map(Self::from).filter(filter),
1508 ),
1509 None => all
1510 .extend(db.trait_impls_in_crate(id).all_impls().map(Self::from).filter(filter)),
1511 }
1512 }
1513 all
1514 }
1515
1516 pub fn all_for_trait(db: &dyn HirDatabase, trait_: Trait) -> Vec<Impl> {
1517 let krate = trait_.module(db).krate();
1518 let mut all = Vec::new();
1519 for Crate { id } in krate.reverse_dependencies(db).into_iter().chain(Some(krate)) {
1520 let impls = db.trait_impls_in_crate(id);
1521 all.extend(impls.for_trait(trait_.id).map(Self::from))
1522 }
1523 all
1488 } 1524 }
1489 1525
1490 // FIXME: the return type is wrong. This should be a hir version of 1526 // FIXME: the return type is wrong. This should be a hir version of
@@ -1932,12 +1968,6 @@ impl Type {
1932 self.ty.value.associated_type_parent_trait(db).map(Into::into) 1968 self.ty.value.associated_type_parent_trait(db).map(Into::into)
1933 } 1969 }
1934 1970
1935 // FIXME: provide required accessors such that it becomes implementable from outside.
1936 pub fn is_equal_for_find_impls(&self, other: &Type) -> bool {
1937 let rref = other.remove_ref();
1938 self.ty.value.equals_ctor(rref.as_ref().map_or(&other.ty.value, |it| &it.ty.value))
1939 }
1940
1941 fn derived(&self, ty: Ty) -> Type { 1971 fn derived(&self, ty: Ty) -> Type {
1942 Type { 1972 Type {
1943 krate: self.krate, 1973 krate: self.krate,