aboutsummaryrefslogtreecommitdiff
path: root/crates/hir/src/code_model.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/hir/src/code_model.rs')
-rw-r--r--crates/hir/src/code_model.rs165
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};
38use rustc_hash::FxHashSet; 38use rustc_hash::FxHashSet;
39use stdx::{format_to, impl_from}; 39use stdx::{format_to, impl_from};
@@ -836,7 +836,7 @@ pub enum Access {
836impl From<Mutability> for Access { 836impl 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)]
2011pub struct Callable { 1978pub 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}