diff options
Diffstat (limited to 'crates/hir/src/code_model.rs')
-rw-r--r-- | crates/hir/src/code_model.rs | 165 |
1 files changed, 66 insertions, 99 deletions
diff --git a/crates/hir/src/code_model.rs b/crates/hir/src/code_model.rs index b3218833d..fc1a74641 100644 --- a/crates/hir/src/code_model.rs +++ b/crates/hir/src/code_model.rs | |||
@@ -14,7 +14,7 @@ use hir_def::{ | |||
14 | per_ns::PerNs, | 14 | per_ns::PerNs, |
15 | resolver::{HasResolver, Resolver}, | 15 | resolver::{HasResolver, Resolver}, |
16 | src::HasSource as _, | 16 | src::HasSource as _, |
17 | type_ref::{Mutability, TypeRef}, | 17 | type_ref::TypeRef, |
18 | AdtId, AssocContainerId, AssocItemId, AssocItemLoc, AttrDefId, ConstId, ConstParamId, | 18 | AdtId, AssocContainerId, AssocItemId, AssocItemLoc, AttrDefId, ConstId, ConstParamId, |
19 | DefWithBodyId, EnumId, FunctionId, GenericDefId, HasModule, ImplId, LifetimeParamId, | 19 | DefWithBodyId, EnumId, FunctionId, GenericDefId, HasModule, ImplId, LifetimeParamId, |
20 | LocalEnumVariantId, LocalFieldId, Lookup, ModuleId, StaticId, StructId, TraitId, TypeAliasId, | 20 | LocalEnumVariantId, LocalFieldId, Lookup, ModuleId, StaticId, StructId, TraitId, TypeAliasId, |
@@ -31,9 +31,9 @@ use hir_ty::{ | |||
31 | display::{write_bounds_like_dyn_trait_with_prefix, HirDisplayError, HirFormatter}, | 31 | display::{write_bounds_like_dyn_trait_with_prefix, HirDisplayError, HirFormatter}, |
32 | method_resolution, | 32 | method_resolution, |
33 | traits::{FnTrait, Solution, SolutionVariables}, | 33 | traits::{FnTrait, Solution, SolutionVariables}, |
34 | ApplicationTy, BoundVar, CallableDefId, Canonical, DebruijnIndex, FnSig, GenericPredicate, | 34 | AliasTy, BoundVar, CallableDefId, CallableSig, Canonical, DebruijnIndex, GenericPredicate, |
35 | InEnvironment, Obligation, ProjectionPredicate, ProjectionTy, Substs, TraitEnvironment, Ty, | 35 | InEnvironment, Mutability, Obligation, ProjectionPredicate, ProjectionTy, Scalar, Substs, |
36 | TyDefId, TyKind, TypeCtor, | 36 | TraitEnvironment, Ty, TyDefId, TyVariableKind, |
37 | }; | 37 | }; |
38 | use rustc_hash::FxHashSet; | 38 | use rustc_hash::FxHashSet; |
39 | use stdx::{format_to, impl_from}; | 39 | use stdx::{format_to, impl_from}; |
@@ -836,7 +836,7 @@ pub enum Access { | |||
836 | impl From<Mutability> for Access { | 836 | impl From<Mutability> for Access { |
837 | fn from(mutability: Mutability) -> Access { | 837 | fn from(mutability: Mutability) -> Access { |
838 | match mutability { | 838 | match mutability { |
839 | Mutability::Shared => Access::Shared, | 839 | Mutability::Not => Access::Shared, |
840 | Mutability::Mut => Access::Exclusive, | 840 | Mutability::Mut => Access::Exclusive, |
841 | } | 841 | } |
842 | } | 842 | } |
@@ -865,7 +865,10 @@ impl SelfParam { | |||
865 | .params | 865 | .params |
866 | .first() | 866 | .first() |
867 | .map(|param| match *param { | 867 | .map(|param| match *param { |
868 | TypeRef::Reference(.., mutability) => mutability.into(), | 868 | TypeRef::Reference(.., mutability) => match mutability { |
869 | hir_def::type_ref::Mutability::Shared => Access::Shared, | ||
870 | hir_def::type_ref::Mutability::Mut => Access::Exclusive, | ||
871 | }, | ||
869 | _ => Access::Owned, | 872 | _ => Access::Owned, |
870 | }) | 873 | }) |
871 | .unwrap_or(Access::Owned) | 874 | .unwrap_or(Access::Owned) |
@@ -1547,25 +1550,19 @@ impl Type { | |||
1547 | } | 1550 | } |
1548 | 1551 | ||
1549 | pub fn is_unit(&self) -> bool { | 1552 | pub fn is_unit(&self) -> bool { |
1550 | matches!( | 1553 | matches!(self.ty.value, Ty::Tuple(0, ..)) |
1551 | self.ty.value, | ||
1552 | Ty::Apply(ApplicationTy { ctor: TypeCtor::Tuple { cardinality: 0 }, .. }) | ||
1553 | ) | ||
1554 | } | 1554 | } |
1555 | pub fn is_bool(&self) -> bool { | 1555 | pub fn is_bool(&self) -> bool { |
1556 | matches!(self.ty.value, Ty::Apply(ApplicationTy { ctor: TypeCtor::Bool, .. })) | 1556 | matches!(self.ty.value, Ty::Scalar(Scalar::Bool)) |
1557 | } | 1557 | } |
1558 | 1558 | ||
1559 | pub fn is_mutable_reference(&self) -> bool { | 1559 | pub fn is_mutable_reference(&self) -> bool { |
1560 | matches!( | 1560 | matches!(self.ty.value, Ty::Ref(Mutability::Mut, ..)) |
1561 | self.ty.value, | ||
1562 | Ty::Apply(ApplicationTy { ctor: TypeCtor::Ref(Mutability::Mut), .. }) | ||
1563 | ) | ||
1564 | } | 1561 | } |
1565 | 1562 | ||
1566 | pub fn remove_ref(&self) -> Option<Type> { | 1563 | pub fn remove_ref(&self) -> Option<Type> { |
1567 | if let Ty::Apply(ApplicationTy { ctor: TypeCtor::Ref(_), .. }) = self.ty.value { | 1564 | if let Ty::Ref(.., substs) = &self.ty.value { |
1568 | self.ty.value.substs().map(|substs| self.derived(substs[0].clone())) | 1565 | Some(self.derived(substs[0].clone())) |
1569 | } else { | 1566 | } else { |
1570 | None | 1567 | None |
1571 | } | 1568 | } |
@@ -1654,14 +1651,14 @@ impl Type { | |||
1654 | .build(); | 1651 | .build(); |
1655 | let predicate = ProjectionPredicate { | 1652 | let predicate = ProjectionPredicate { |
1656 | projection_ty: ProjectionTy { associated_ty: alias.id, parameters: subst }, | 1653 | projection_ty: ProjectionTy { associated_ty: alias.id, parameters: subst }, |
1657 | ty: Ty::Bound(BoundVar::new(DebruijnIndex::INNERMOST, 0)), | 1654 | ty: Ty::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0)), |
1658 | }; | 1655 | }; |
1659 | let goal = Canonical { | 1656 | let goal = Canonical { |
1660 | value: InEnvironment::new( | 1657 | value: InEnvironment::new( |
1661 | self.ty.environment.clone(), | 1658 | self.ty.environment.clone(), |
1662 | Obligation::Projection(predicate), | 1659 | Obligation::Projection(predicate), |
1663 | ), | 1660 | ), |
1664 | kinds: Arc::new([TyKind::General]), | 1661 | kinds: Arc::new([TyVariableKind::General]), |
1665 | }; | 1662 | }; |
1666 | 1663 | ||
1667 | match db.trait_solve(self.krate, goal)? { | 1664 | match db.trait_solve(self.krate, goal)? { |
@@ -1685,7 +1682,7 @@ impl Type { | |||
1685 | 1682 | ||
1686 | pub fn as_callable(&self, db: &dyn HirDatabase) -> Option<Callable> { | 1683 | pub fn as_callable(&self, db: &dyn HirDatabase) -> Option<Callable> { |
1687 | let def = match self.ty.value { | 1684 | let def = match self.ty.value { |
1688 | Ty::Apply(ApplicationTy { ctor: TypeCtor::FnDef(def), parameters: _ }) => Some(def), | 1685 | Ty::FnDef(def, _) => Some(def), |
1689 | _ => None, | 1686 | _ => None, |
1690 | }; | 1687 | }; |
1691 | 1688 | ||
@@ -1694,20 +1691,16 @@ impl Type { | |||
1694 | } | 1691 | } |
1695 | 1692 | ||
1696 | pub fn is_closure(&self) -> bool { | 1693 | pub fn is_closure(&self) -> bool { |
1697 | matches!(&self.ty.value, Ty::Apply(ApplicationTy { ctor: TypeCtor::Closure { .. }, .. })) | 1694 | matches!(&self.ty.value, Ty::Closure { .. }) |
1698 | } | 1695 | } |
1699 | 1696 | ||
1700 | pub fn is_fn(&self) -> bool { | 1697 | pub fn is_fn(&self) -> bool { |
1701 | matches!( | 1698 | matches!(&self.ty.value, Ty::FnDef(..) | Ty::Function { .. }) |
1702 | &self.ty.value, | ||
1703 | Ty::Apply(ApplicationTy { ctor: TypeCtor::FnDef(..), .. }) | ||
1704 | | Ty::Apply(ApplicationTy { ctor: TypeCtor::FnPtr { .. }, .. }) | ||
1705 | ) | ||
1706 | } | 1699 | } |
1707 | 1700 | ||
1708 | pub fn is_packed(&self, db: &dyn HirDatabase) -> bool { | 1701 | pub fn is_packed(&self, db: &dyn HirDatabase) -> bool { |
1709 | let adt_id = match self.ty.value { | 1702 | let adt_id = match self.ty.value { |
1710 | Ty::Apply(ApplicationTy { ctor: TypeCtor::Adt(adt_id), .. }) => adt_id, | 1703 | Ty::Adt(adt_id, ..) => adt_id, |
1711 | _ => return false, | 1704 | _ => return false, |
1712 | }; | 1705 | }; |
1713 | 1706 | ||
@@ -1719,7 +1712,7 @@ impl Type { | |||
1719 | } | 1712 | } |
1720 | 1713 | ||
1721 | pub fn is_raw_ptr(&self) -> bool { | 1714 | pub fn is_raw_ptr(&self) -> bool { |
1722 | matches!(&self.ty.value, Ty::Apply(ApplicationTy { ctor: TypeCtor::RawPtr(..), .. })) | 1715 | matches!(&self.ty.value, Ty::Raw(..)) |
1723 | } | 1716 | } |
1724 | 1717 | ||
1725 | pub fn contains_unknown(&self) -> bool { | 1718 | pub fn contains_unknown(&self) -> bool { |
@@ -1728,44 +1721,34 @@ impl Type { | |||
1728 | fn go(ty: &Ty) -> bool { | 1721 | fn go(ty: &Ty) -> bool { |
1729 | match ty { | 1722 | match ty { |
1730 | Ty::Unknown => true, | 1723 | Ty::Unknown => true, |
1731 | Ty::Apply(a_ty) => a_ty.parameters.iter().any(go), | 1724 | _ => ty.substs().map_or(false, |substs| substs.iter().any(go)), |
1732 | _ => false, | ||
1733 | } | 1725 | } |
1734 | } | 1726 | } |
1735 | } | 1727 | } |
1736 | 1728 | ||
1737 | pub fn fields(&self, db: &dyn HirDatabase) -> Vec<(Field, Type)> { | 1729 | pub fn fields(&self, db: &dyn HirDatabase) -> Vec<(Field, Type)> { |
1738 | if let Ty::Apply(a_ty) = &self.ty.value { | 1730 | let (variant_id, substs) = match self.ty.value { |
1739 | let variant_id = match a_ty.ctor { | 1731 | Ty::Adt(AdtId::StructId(s), ref substs) => (s.into(), substs), |
1740 | TypeCtor::Adt(AdtId::StructId(s)) => s.into(), | 1732 | Ty::Adt(AdtId::UnionId(u), ref substs) => (u.into(), substs), |
1741 | TypeCtor::Adt(AdtId::UnionId(u)) => u.into(), | 1733 | _ => return Vec::new(), |
1742 | _ => return Vec::new(), | ||
1743 | }; | ||
1744 | |||
1745 | return db | ||
1746 | .field_types(variant_id) | ||
1747 | .iter() | ||
1748 | .map(|(local_id, ty)| { | ||
1749 | let def = Field { parent: variant_id.into(), id: local_id }; | ||
1750 | let ty = ty.clone().subst(&a_ty.parameters); | ||
1751 | (def, self.derived(ty)) | ||
1752 | }) | ||
1753 | .collect(); | ||
1754 | }; | 1734 | }; |
1755 | Vec::new() | 1735 | |
1736 | db.field_types(variant_id) | ||
1737 | .iter() | ||
1738 | .map(|(local_id, ty)| { | ||
1739 | let def = Field { parent: variant_id.into(), id: local_id }; | ||
1740 | let ty = ty.clone().subst(substs); | ||
1741 | (def, self.derived(ty)) | ||
1742 | }) | ||
1743 | .collect() | ||
1756 | } | 1744 | } |
1757 | 1745 | ||
1758 | pub fn tuple_fields(&self, _db: &dyn HirDatabase) -> Vec<Type> { | 1746 | pub fn tuple_fields(&self, _db: &dyn HirDatabase) -> Vec<Type> { |
1759 | let mut res = Vec::new(); | 1747 | if let Ty::Tuple(_, substs) = &self.ty.value { |
1760 | if let Ty::Apply(a_ty) = &self.ty.value { | 1748 | substs.iter().map(|ty| self.derived(ty.clone())).collect() |
1761 | if let TypeCtor::Tuple { .. } = a_ty.ctor { | 1749 | } else { |
1762 | for ty in a_ty.parameters.iter() { | 1750 | Vec::new() |
1763 | let ty = ty.clone(); | 1751 | } |
1764 | res.push(self.derived(ty)); | ||
1765 | } | ||
1766 | } | ||
1767 | }; | ||
1768 | res | ||
1769 | } | 1752 | } |
1770 | 1753 | ||
1771 | pub fn autoderef<'a>(&'a self, db: &'a dyn HirDatabase) -> impl Iterator<Item = Type> + 'a { | 1754 | pub fn autoderef<'a>(&'a self, db: &'a dyn HirDatabase) -> impl Iterator<Item = Type> + 'a { |
@@ -1802,15 +1785,13 @@ impl Type { | |||
1802 | } | 1785 | } |
1803 | 1786 | ||
1804 | pub fn type_parameters(&self) -> impl Iterator<Item = Type> + '_ { | 1787 | pub fn type_parameters(&self) -> impl Iterator<Item = Type> + '_ { |
1805 | let ty = self.ty.value.strip_references(); | 1788 | self.ty |
1806 | let substs = match ty { | 1789 | .value |
1807 | Ty::Apply(apply_ty) => &apply_ty.parameters, | 1790 | .strip_references() |
1808 | Ty::Opaque(opaque_ty) => &opaque_ty.parameters, | 1791 | .substs() |
1809 | _ => return Either::Left(iter::empty()), | 1792 | .into_iter() |
1810 | }; | 1793 | .flat_map(|substs| substs.iter()) |
1811 | 1794 | .map(move |ty| self.derived(ty.clone())) | |
1812 | let iter = substs.iter().map(move |ty| self.derived(ty.clone())); | ||
1813 | Either::Right(iter) | ||
1814 | } | 1795 | } |
1815 | 1796 | ||
1816 | pub fn iterate_method_candidates<T>( | 1797 | pub fn iterate_method_candidates<T>( |
@@ -1900,17 +1881,8 @@ impl Type { | |||
1900 | 1881 | ||
1901 | // FIXME: provide required accessors such that it becomes implementable from outside. | 1882 | // FIXME: provide required accessors such that it becomes implementable from outside. |
1902 | pub fn is_equal_for_find_impls(&self, other: &Type) -> bool { | 1883 | pub fn is_equal_for_find_impls(&self, other: &Type) -> bool { |
1903 | match (&self.ty.value, &other.ty.value) { | 1884 | let rref = other.remove_ref(); |
1904 | (Ty::Apply(a_original_ty), Ty::Apply(ApplicationTy { ctor, parameters })) => match ctor | 1885 | self.ty.value.equals_ctor(rref.as_ref().map_or(&other.ty.value, |it| &it.ty.value)) |
1905 | { | ||
1906 | TypeCtor::Ref(..) => match parameters.as_single() { | ||
1907 | Ty::Apply(a_ty) => a_original_ty.ctor == a_ty.ctor, | ||
1908 | _ => false, | ||
1909 | }, | ||
1910 | _ => a_original_ty.ctor == *ctor, | ||
1911 | }, | ||
1912 | _ => false, | ||
1913 | } | ||
1914 | } | 1886 | } |
1915 | 1887 | ||
1916 | fn derived(&self, ty: Ty) -> Type { | 1888 | fn derived(&self, ty: Ty) -> Type { |
@@ -1955,28 +1927,20 @@ impl Type { | |||
1955 | fn walk_type(db: &dyn HirDatabase, type_: &Type, cb: &mut impl FnMut(Type)) { | 1927 | fn walk_type(db: &dyn HirDatabase, type_: &Type, cb: &mut impl FnMut(Type)) { |
1956 | let ty = type_.ty.value.strip_references(); | 1928 | let ty = type_.ty.value.strip_references(); |
1957 | match ty { | 1929 | match ty { |
1958 | Ty::Apply(ApplicationTy { ctor, parameters }) => { | 1930 | Ty::Adt(..) => { |
1959 | match ctor { | 1931 | cb(type_.derived(ty.clone())); |
1960 | TypeCtor::Adt(_) => { | 1932 | } |
1961 | cb(type_.derived(ty.clone())); | 1933 | Ty::AssociatedType(..) => { |
1962 | } | 1934 | if let Some(_) = ty.associated_type_parent_trait(db) { |
1963 | TypeCtor::AssociatedType(_) => { | 1935 | cb(type_.derived(ty.clone())); |
1964 | if let Some(_) = ty.associated_type_parent_trait(db) { | ||
1965 | cb(type_.derived(ty.clone())); | ||
1966 | } | ||
1967 | } | ||
1968 | TypeCtor::OpaqueType(..) => { | ||
1969 | if let Some(bounds) = ty.impl_trait_bounds(db) { | ||
1970 | walk_bounds(db, &type_.derived(ty.clone()), &bounds, cb); | ||
1971 | } | ||
1972 | } | ||
1973 | _ => (), | ||
1974 | } | 1936 | } |
1975 | |||
1976 | // adt params, tuples, etc... | ||
1977 | walk_substs(db, type_, parameters, cb); | ||
1978 | } | 1937 | } |
1979 | Ty::Opaque(opaque_ty) => { | 1938 | Ty::OpaqueType(..) => { |
1939 | if let Some(bounds) = ty.impl_trait_bounds(db) { | ||
1940 | walk_bounds(db, &type_.derived(ty.clone()), &bounds, cb); | ||
1941 | } | ||
1942 | } | ||
1943 | Ty::Alias(AliasTy::Opaque(opaque_ty)) => { | ||
1980 | if let Some(bounds) = ty.impl_trait_bounds(db) { | 1944 | if let Some(bounds) = ty.impl_trait_bounds(db) { |
1981 | walk_bounds(db, &type_.derived(ty.clone()), &bounds, cb); | 1945 | walk_bounds(db, &type_.derived(ty.clone()), &bounds, cb); |
1982 | } | 1946 | } |
@@ -1992,7 +1956,10 @@ impl Type { | |||
1992 | walk_bounds(db, &type_.derived(ty.clone()), bounds.as_ref(), cb); | 1956 | walk_bounds(db, &type_.derived(ty.clone()), bounds.as_ref(), cb); |
1993 | } | 1957 | } |
1994 | 1958 | ||
1995 | _ => (), | 1959 | _ => {} |
1960 | } | ||
1961 | if let Some(substs) = ty.substs() { | ||
1962 | walk_substs(db, type_, &substs, cb); | ||
1996 | } | 1963 | } |
1997 | } | 1964 | } |
1998 | 1965 | ||
@@ -2010,7 +1977,7 @@ impl HirDisplay for Type { | |||
2010 | #[derive(Debug)] | 1977 | #[derive(Debug)] |
2011 | pub struct Callable { | 1978 | pub struct Callable { |
2012 | ty: Type, | 1979 | ty: Type, |
2013 | sig: FnSig, | 1980 | sig: CallableSig, |
2014 | def: Option<CallableDefId>, | 1981 | def: Option<CallableDefId>, |
2015 | pub(crate) is_bound_method: bool, | 1982 | pub(crate) is_bound_method: bool, |
2016 | } | 1983 | } |