diff options
Diffstat (limited to 'crates/hir/src/code_model.rs')
-rw-r--r-- | crates/hir/src/code_model.rs | 156 |
1 files changed, 60 insertions, 96 deletions
diff --git a/crates/hir/src/code_model.rs b/crates/hir/src/code_model.rs index b3218833d..00b0dc082 100644 --- a/crates/hir/src/code_model.rs +++ b/crates/hir/src/code_model.rs | |||
@@ -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, Obligation, ProjectionPredicate, ProjectionTy, Scalar, Substs, TraitEnvironment, |
36 | TyDefId, TyKind, TypeCtor, | 36 | 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}; |
@@ -1547,25 +1547,19 @@ impl Type { | |||
1547 | } | 1547 | } |
1548 | 1548 | ||
1549 | pub fn is_unit(&self) -> bool { | 1549 | pub fn is_unit(&self) -> bool { |
1550 | matches!( | 1550 | matches!(self.ty.value, Ty::Tuple(0, ..)) |
1551 | self.ty.value, | ||
1552 | Ty::Apply(ApplicationTy { ctor: TypeCtor::Tuple { cardinality: 0 }, .. }) | ||
1553 | ) | ||
1554 | } | 1551 | } |
1555 | pub fn is_bool(&self) -> bool { | 1552 | pub fn is_bool(&self) -> bool { |
1556 | matches!(self.ty.value, Ty::Apply(ApplicationTy { ctor: TypeCtor::Bool, .. })) | 1553 | matches!(self.ty.value, Ty::Scalar(Scalar::Bool)) |
1557 | } | 1554 | } |
1558 | 1555 | ||
1559 | pub fn is_mutable_reference(&self) -> bool { | 1556 | pub fn is_mutable_reference(&self) -> bool { |
1560 | matches!( | 1557 | matches!(self.ty.value, Ty::Ref(Mutability::Mut, ..)) |
1561 | self.ty.value, | ||
1562 | Ty::Apply(ApplicationTy { ctor: TypeCtor::Ref(Mutability::Mut), .. }) | ||
1563 | ) | ||
1564 | } | 1558 | } |
1565 | 1559 | ||
1566 | pub fn remove_ref(&self) -> Option<Type> { | 1560 | pub fn remove_ref(&self) -> Option<Type> { |
1567 | if let Ty::Apply(ApplicationTy { ctor: TypeCtor::Ref(_), .. }) = self.ty.value { | 1561 | if let Ty::Ref(.., substs) = &self.ty.value { |
1568 | self.ty.value.substs().map(|substs| self.derived(substs[0].clone())) | 1562 | Some(self.derived(substs[0].clone())) |
1569 | } else { | 1563 | } else { |
1570 | None | 1564 | None |
1571 | } | 1565 | } |
@@ -1654,14 +1648,14 @@ impl Type { | |||
1654 | .build(); | 1648 | .build(); |
1655 | let predicate = ProjectionPredicate { | 1649 | let predicate = ProjectionPredicate { |
1656 | projection_ty: ProjectionTy { associated_ty: alias.id, parameters: subst }, | 1650 | projection_ty: ProjectionTy { associated_ty: alias.id, parameters: subst }, |
1657 | ty: Ty::Bound(BoundVar::new(DebruijnIndex::INNERMOST, 0)), | 1651 | ty: Ty::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0)), |
1658 | }; | 1652 | }; |
1659 | let goal = Canonical { | 1653 | let goal = Canonical { |
1660 | value: InEnvironment::new( | 1654 | value: InEnvironment::new( |
1661 | self.ty.environment.clone(), | 1655 | self.ty.environment.clone(), |
1662 | Obligation::Projection(predicate), | 1656 | Obligation::Projection(predicate), |
1663 | ), | 1657 | ), |
1664 | kinds: Arc::new([TyKind::General]), | 1658 | kinds: Arc::new([TyVariableKind::General]), |
1665 | }; | 1659 | }; |
1666 | 1660 | ||
1667 | match db.trait_solve(self.krate, goal)? { | 1661 | match db.trait_solve(self.krate, goal)? { |
@@ -1685,7 +1679,7 @@ impl Type { | |||
1685 | 1679 | ||
1686 | pub fn as_callable(&self, db: &dyn HirDatabase) -> Option<Callable> { | 1680 | pub fn as_callable(&self, db: &dyn HirDatabase) -> Option<Callable> { |
1687 | let def = match self.ty.value { | 1681 | let def = match self.ty.value { |
1688 | Ty::Apply(ApplicationTy { ctor: TypeCtor::FnDef(def), parameters: _ }) => Some(def), | 1682 | Ty::FnDef(def, _) => Some(def), |
1689 | _ => None, | 1683 | _ => None, |
1690 | }; | 1684 | }; |
1691 | 1685 | ||
@@ -1694,20 +1688,16 @@ impl Type { | |||
1694 | } | 1688 | } |
1695 | 1689 | ||
1696 | pub fn is_closure(&self) -> bool { | 1690 | pub fn is_closure(&self) -> bool { |
1697 | matches!(&self.ty.value, Ty::Apply(ApplicationTy { ctor: TypeCtor::Closure { .. }, .. })) | 1691 | matches!(&self.ty.value, Ty::Closure { .. }) |
1698 | } | 1692 | } |
1699 | 1693 | ||
1700 | pub fn is_fn(&self) -> bool { | 1694 | pub fn is_fn(&self) -> bool { |
1701 | matches!( | 1695 | 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 | } | 1696 | } |
1707 | 1697 | ||
1708 | pub fn is_packed(&self, db: &dyn HirDatabase) -> bool { | 1698 | pub fn is_packed(&self, db: &dyn HirDatabase) -> bool { |
1709 | let adt_id = match self.ty.value { | 1699 | let adt_id = match self.ty.value { |
1710 | Ty::Apply(ApplicationTy { ctor: TypeCtor::Adt(adt_id), .. }) => adt_id, | 1700 | Ty::Adt(adt_id, ..) => adt_id, |
1711 | _ => return false, | 1701 | _ => return false, |
1712 | }; | 1702 | }; |
1713 | 1703 | ||
@@ -1719,7 +1709,7 @@ impl Type { | |||
1719 | } | 1709 | } |
1720 | 1710 | ||
1721 | pub fn is_raw_ptr(&self) -> bool { | 1711 | pub fn is_raw_ptr(&self) -> bool { |
1722 | matches!(&self.ty.value, Ty::Apply(ApplicationTy { ctor: TypeCtor::RawPtr(..), .. })) | 1712 | matches!(&self.ty.value, Ty::Raw(..)) |
1723 | } | 1713 | } |
1724 | 1714 | ||
1725 | pub fn contains_unknown(&self) -> bool { | 1715 | pub fn contains_unknown(&self) -> bool { |
@@ -1728,44 +1718,34 @@ impl Type { | |||
1728 | fn go(ty: &Ty) -> bool { | 1718 | fn go(ty: &Ty) -> bool { |
1729 | match ty { | 1719 | match ty { |
1730 | Ty::Unknown => true, | 1720 | Ty::Unknown => true, |
1731 | Ty::Apply(a_ty) => a_ty.parameters.iter().any(go), | 1721 | _ => ty.substs().map_or(false, |substs| substs.iter().any(go)), |
1732 | _ => false, | ||
1733 | } | 1722 | } |
1734 | } | 1723 | } |
1735 | } | 1724 | } |
1736 | 1725 | ||
1737 | pub fn fields(&self, db: &dyn HirDatabase) -> Vec<(Field, Type)> { | 1726 | pub fn fields(&self, db: &dyn HirDatabase) -> Vec<(Field, Type)> { |
1738 | if let Ty::Apply(a_ty) = &self.ty.value { | 1727 | let (variant_id, substs) = match self.ty.value { |
1739 | let variant_id = match a_ty.ctor { | 1728 | Ty::Adt(AdtId::StructId(s), ref substs) => (s.into(), substs), |
1740 | TypeCtor::Adt(AdtId::StructId(s)) => s.into(), | 1729 | Ty::Adt(AdtId::UnionId(u), ref substs) => (u.into(), substs), |
1741 | TypeCtor::Adt(AdtId::UnionId(u)) => u.into(), | 1730 | _ => 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 | }; | 1731 | }; |
1755 | Vec::new() | 1732 | |
1733 | db.field_types(variant_id) | ||
1734 | .iter() | ||
1735 | .map(|(local_id, ty)| { | ||
1736 | let def = Field { parent: variant_id.into(), id: local_id }; | ||
1737 | let ty = ty.clone().subst(substs); | ||
1738 | (def, self.derived(ty)) | ||
1739 | }) | ||
1740 | .collect() | ||
1756 | } | 1741 | } |
1757 | 1742 | ||
1758 | pub fn tuple_fields(&self, _db: &dyn HirDatabase) -> Vec<Type> { | 1743 | pub fn tuple_fields(&self, _db: &dyn HirDatabase) -> Vec<Type> { |
1759 | let mut res = Vec::new(); | 1744 | if let Ty::Tuple(_, substs) = &self.ty.value { |
1760 | if let Ty::Apply(a_ty) = &self.ty.value { | 1745 | substs.iter().map(|ty| self.derived(ty.clone())).collect() |
1761 | if let TypeCtor::Tuple { .. } = a_ty.ctor { | 1746 | } else { |
1762 | for ty in a_ty.parameters.iter() { | 1747 | Vec::new() |
1763 | let ty = ty.clone(); | 1748 | } |
1764 | res.push(self.derived(ty)); | ||
1765 | } | ||
1766 | } | ||
1767 | }; | ||
1768 | res | ||
1769 | } | 1749 | } |
1770 | 1750 | ||
1771 | pub fn autoderef<'a>(&'a self, db: &'a dyn HirDatabase) -> impl Iterator<Item = Type> + 'a { | 1751 | pub fn autoderef<'a>(&'a self, db: &'a dyn HirDatabase) -> impl Iterator<Item = Type> + 'a { |
@@ -1802,15 +1782,13 @@ impl Type { | |||
1802 | } | 1782 | } |
1803 | 1783 | ||
1804 | pub fn type_parameters(&self) -> impl Iterator<Item = Type> + '_ { | 1784 | pub fn type_parameters(&self) -> impl Iterator<Item = Type> + '_ { |
1805 | let ty = self.ty.value.strip_references(); | 1785 | self.ty |
1806 | let substs = match ty { | 1786 | .value |
1807 | Ty::Apply(apply_ty) => &apply_ty.parameters, | 1787 | .strip_references() |
1808 | Ty::Opaque(opaque_ty) => &opaque_ty.parameters, | 1788 | .substs() |
1809 | _ => return Either::Left(iter::empty()), | 1789 | .into_iter() |
1810 | }; | 1790 | .flat_map(|substs| substs.iter()) |
1811 | 1791 | .map(move |ty| self.derived(ty.clone())) | |
1812 | let iter = substs.iter().map(move |ty| self.derived(ty.clone())); | ||
1813 | Either::Right(iter) | ||
1814 | } | 1792 | } |
1815 | 1793 | ||
1816 | pub fn iterate_method_candidates<T>( | 1794 | pub fn iterate_method_candidates<T>( |
@@ -1900,17 +1878,8 @@ impl Type { | |||
1900 | 1878 | ||
1901 | // FIXME: provide required accessors such that it becomes implementable from outside. | 1879 | // FIXME: provide required accessors such that it becomes implementable from outside. |
1902 | pub fn is_equal_for_find_impls(&self, other: &Type) -> bool { | 1880 | pub fn is_equal_for_find_impls(&self, other: &Type) -> bool { |
1903 | match (&self.ty.value, &other.ty.value) { | 1881 | let rref = other.remove_ref(); |
1904 | (Ty::Apply(a_original_ty), Ty::Apply(ApplicationTy { ctor, parameters })) => match ctor | 1882 | 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 | } | 1883 | } |
1915 | 1884 | ||
1916 | fn derived(&self, ty: Ty) -> Type { | 1885 | fn derived(&self, ty: Ty) -> Type { |
@@ -1955,28 +1924,20 @@ impl Type { | |||
1955 | fn walk_type(db: &dyn HirDatabase, type_: &Type, cb: &mut impl FnMut(Type)) { | 1924 | fn walk_type(db: &dyn HirDatabase, type_: &Type, cb: &mut impl FnMut(Type)) { |
1956 | let ty = type_.ty.value.strip_references(); | 1925 | let ty = type_.ty.value.strip_references(); |
1957 | match ty { | 1926 | match ty { |
1958 | Ty::Apply(ApplicationTy { ctor, parameters }) => { | 1927 | Ty::Adt(..) => { |
1959 | match ctor { | 1928 | cb(type_.derived(ty.clone())); |
1960 | TypeCtor::Adt(_) => { | 1929 | } |
1961 | cb(type_.derived(ty.clone())); | 1930 | Ty::AssociatedType(..) => { |
1962 | } | 1931 | if let Some(_) = ty.associated_type_parent_trait(db) { |
1963 | TypeCtor::AssociatedType(_) => { | 1932 | 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 | } | 1933 | } |
1975 | |||
1976 | // adt params, tuples, etc... | ||
1977 | walk_substs(db, type_, parameters, cb); | ||
1978 | } | 1934 | } |
1979 | Ty::Opaque(opaque_ty) => { | 1935 | Ty::OpaqueType(..) => { |
1936 | if let Some(bounds) = ty.impl_trait_bounds(db) { | ||
1937 | walk_bounds(db, &type_.derived(ty.clone()), &bounds, cb); | ||
1938 | } | ||
1939 | } | ||
1940 | Ty::Alias(AliasTy::Opaque(opaque_ty)) => { | ||
1980 | if let Some(bounds) = ty.impl_trait_bounds(db) { | 1941 | if let Some(bounds) = ty.impl_trait_bounds(db) { |
1981 | walk_bounds(db, &type_.derived(ty.clone()), &bounds, cb); | 1942 | walk_bounds(db, &type_.derived(ty.clone()), &bounds, cb); |
1982 | } | 1943 | } |
@@ -1992,7 +1953,10 @@ impl Type { | |||
1992 | walk_bounds(db, &type_.derived(ty.clone()), bounds.as_ref(), cb); | 1953 | walk_bounds(db, &type_.derived(ty.clone()), bounds.as_ref(), cb); |
1993 | } | 1954 | } |
1994 | 1955 | ||
1995 | _ => (), | 1956 | _ => {} |
1957 | } | ||
1958 | if let Some(substs) = ty.substs() { | ||
1959 | walk_substs(db, type_, &substs, cb); | ||
1996 | } | 1960 | } |
1997 | } | 1961 | } |
1998 | 1962 | ||
@@ -2010,7 +1974,7 @@ impl HirDisplay for Type { | |||
2010 | #[derive(Debug)] | 1974 | #[derive(Debug)] |
2011 | pub struct Callable { | 1975 | pub struct Callable { |
2012 | ty: Type, | 1976 | ty: Type, |
2013 | sig: FnSig, | 1977 | sig: CallableSig, |
2014 | def: Option<CallableDefId>, | 1978 | def: Option<CallableDefId>, |
2015 | pub(crate) is_bound_method: bool, | 1979 | pub(crate) is_bound_method: bool, |
2016 | } | 1980 | } |