diff options
Diffstat (limited to 'crates/hir/src/lib.rs')
-rw-r--r-- | crates/hir/src/lib.rs | 48 |
1 files changed, 36 insertions, 12 deletions
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs index 817a01db1..d8ccfde0c 100644 --- a/crates/hir/src/lib.rs +++ b/crates/hir/src/lib.rs | |||
@@ -509,7 +509,7 @@ impl Field { | |||
509 | /// placeholder types for type parameters). This is good for showing | 509 | /// placeholder types for type parameters). This is good for showing |
510 | /// signature help, but not so good to actually get the type of the field | 510 | /// signature help, but not so good to actually get the type of the field |
511 | /// when you actually have a variable of the struct. | 511 | /// when you actually have a variable of the struct. |
512 | pub fn signature_ty(&self, db: &dyn HirDatabase) -> Type { | 512 | pub fn ty(&self, db: &dyn HirDatabase) -> Type { |
513 | let var_id = self.parent.into(); | 513 | let var_id = self.parent.into(); |
514 | let generic_def_id: GenericDefId = match self.parent { | 514 | let generic_def_id: GenericDefId = match self.parent { |
515 | VariantDef::Struct(it) => it.id.into(), | 515 | VariantDef::Struct(it) => it.id.into(), |
@@ -1580,11 +1580,24 @@ impl Impl { | |||
1580 | ty.equals_ctor(rref.as_ref().map_or(&self_ty.ty, |it| &it.ty)) | 1580 | ty.equals_ctor(rref.as_ref().map_or(&self_ty.ty, |it| &it.ty)) |
1581 | }; | 1581 | }; |
1582 | 1582 | ||
1583 | let fp = TyFingerprint::for_inherent_impl(&ty); | ||
1584 | let fp = if let Some(fp) = fp { | ||
1585 | fp | ||
1586 | } else { | ||
1587 | return Vec::new(); | ||
1588 | }; | ||
1589 | |||
1583 | let mut all = Vec::new(); | 1590 | let mut all = Vec::new(); |
1584 | def_crates.iter().for_each(|&id| { | 1591 | def_crates.iter().for_each(|&id| { |
1585 | all.extend(db.inherent_impls_in_crate(id).all_impls().map(Self::from).filter(filter)) | 1592 | all.extend( |
1593 | db.inherent_impls_in_crate(id) | ||
1594 | .for_self_ty(&ty) | ||
1595 | .into_iter() | ||
1596 | .cloned() | ||
1597 | .map(Self::from) | ||
1598 | .filter(filter), | ||
1599 | ) | ||
1586 | }); | 1600 | }); |
1587 | let fp = TyFingerprint::for_impl(&ty); | ||
1588 | for id in def_crates | 1601 | for id in def_crates |
1589 | .iter() | 1602 | .iter() |
1590 | .flat_map(|&id| Crate { id }.transitive_reverse_dependencies(db)) | 1603 | .flat_map(|&id| Crate { id }.transitive_reverse_dependencies(db)) |
@@ -1592,13 +1605,12 @@ impl Impl { | |||
1592 | .chain(def_crates.iter().copied()) | 1605 | .chain(def_crates.iter().copied()) |
1593 | .unique() | 1606 | .unique() |
1594 | { | 1607 | { |
1595 | match fp { | 1608 | all.extend( |
1596 | Some(fp) => all.extend( | 1609 | db.trait_impls_in_crate(id) |
1597 | db.trait_impls_in_crate(id).for_self_ty(fp).map(Self::from).filter(filter), | 1610 | .for_self_ty_without_blanket_impls(fp) |
1598 | ), | 1611 | .map(Self::from) |
1599 | None => all | 1612 | .filter(filter), |
1600 | .extend(db.trait_impls_in_crate(id).all_impls().map(Self::from).filter(filter)), | 1613 | ); |
1601 | } | ||
1602 | } | 1614 | } |
1603 | all | 1615 | all |
1604 | } | 1616 | } |
@@ -1825,7 +1837,7 @@ impl Type { | |||
1825 | Solution::Unique(s) => s | 1837 | Solution::Unique(s) => s |
1826 | .value | 1838 | .value |
1827 | .subst | 1839 | .subst |
1828 | .interned() | 1840 | .as_slice(&Interner) |
1829 | .first() | 1841 | .first() |
1830 | .map(|ty| self.derived(ty.assert_ty_ref(&Interner).clone())), | 1842 | .map(|ty| self.derived(ty.assert_ty_ref(&Interner).clone())), |
1831 | Solution::Ambig(_) => None, | 1843 | Solution::Ambig(_) => None, |
@@ -1972,7 +1984,7 @@ impl Type { | |||
1972 | None | 1984 | None |
1973 | } | 1985 | } |
1974 | 1986 | ||
1975 | pub fn type_parameters(&self) -> impl Iterator<Item = Type> + '_ { | 1987 | pub fn type_arguments(&self) -> impl Iterator<Item = Type> + '_ { |
1976 | self.ty | 1988 | self.ty |
1977 | .strip_references() | 1989 | .strip_references() |
1978 | .as_adt() | 1990 | .as_adt() |
@@ -2054,6 +2066,18 @@ impl Type { | |||
2054 | self.ty.dyn_trait().map(Into::into) | 2066 | self.ty.dyn_trait().map(Into::into) |
2055 | } | 2067 | } |
2056 | 2068 | ||
2069 | /// If a type can be represented as `dyn Trait`, returns all traits accessible via this type, | ||
2070 | /// or an empty iterator otherwise. | ||
2071 | pub fn applicable_inherent_traits<'a>( | ||
2072 | &'a self, | ||
2073 | db: &'a dyn HirDatabase, | ||
2074 | ) -> impl Iterator<Item = Trait> + 'a { | ||
2075 | self.autoderef(db) | ||
2076 | .filter_map(|derefed_type| derefed_type.ty.dyn_trait()) | ||
2077 | .flat_map(move |dyn_trait_id| hir_ty::all_super_traits(db.upcast(), dyn_trait_id)) | ||
2078 | .map(Trait::from) | ||
2079 | } | ||
2080 | |||
2057 | pub fn as_impl_traits(&self, db: &dyn HirDatabase) -> Option<Vec<Trait>> { | 2081 | pub fn as_impl_traits(&self, db: &dyn HirDatabase) -> Option<Vec<Trait>> { |
2058 | self.ty.impl_trait_bounds(db).map(|it| { | 2082 | self.ty.impl_trait_bounds(db).map(|it| { |
2059 | it.into_iter() | 2083 | it.into_iter() |