aboutsummaryrefslogtreecommitdiff
path: root/crates/hir/src
diff options
context:
space:
mode:
Diffstat (limited to 'crates/hir/src')
-rw-r--r--crates/hir/src/code_model.rs151
-rw-r--r--crates/hir/src/source_analyzer.rs16
2 files changed, 61 insertions, 106 deletions
diff --git a/crates/hir/src/code_model.rs b/crates/hir/src/code_model.rs
index 4109b2ea8..cdb54eca2 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 BoundVar, CallableDefId, Canonical, DebruijnIndex, FnSig, GenericPredicate, InEnvironment,
35 InEnvironment, Obligation, ProjectionPredicate, ProjectionTy, Scalar, Substs, TraitEnvironment, 35 Obligation, ProjectionPredicate, ProjectionTy, Scalar, Substs, TraitEnvironment, Ty, TyDefId,
36 Ty, TyDefId, TyKind, TypeCtor, 36 TyKind,
37}; 37};
38use rustc_hash::FxHashSet; 38use rustc_hash::FxHashSet;
39use stdx::{format_to, impl_from}; 39use stdx::{format_to, impl_from};
@@ -1547,28 +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 { cardinality: 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!( 1553 matches!(self.ty.value, Ty::Scalar(Scalar::Bool))
1557 self.ty.value,
1558 Ty::Apply(ApplicationTy { ctor: TypeCtor::Scalar(Scalar::Bool), .. })
1559 )
1560 } 1554 }
1561 1555
1562 pub fn is_mutable_reference(&self) -> bool { 1556 pub fn is_mutable_reference(&self) -> bool {
1563 matches!( 1557 matches!(self.ty.value, Ty::Ref(Mutability::Mut, ..))
1564 self.ty.value,
1565 Ty::Apply(ApplicationTy { ctor: TypeCtor::Ref(Mutability::Mut), .. })
1566 )
1567 } 1558 }
1568 1559
1569 pub fn remove_ref(&self) -> Option<Type> { 1560 pub fn remove_ref(&self) -> Option<Type> {
1570 if let Ty::Apply(ApplicationTy { ctor: TypeCtor::Ref(_), .. }) = self.ty.value { 1561 if let Ty::Ref(.., substs) = &self.ty.value {
1571 self.ty.value.substs().map(|substs| self.derived(substs[0].clone())) 1562 Some(self.derived(substs[0].clone()))
1572 } else { 1563 } else {
1573 None 1564 None
1574 } 1565 }
@@ -1688,7 +1679,7 @@ impl Type {
1688 1679
1689 pub fn as_callable(&self, db: &dyn HirDatabase) -> Option<Callable> { 1680 pub fn as_callable(&self, db: &dyn HirDatabase) -> Option<Callable> {
1690 let def = match self.ty.value { 1681 let def = match self.ty.value {
1691 Ty::Apply(ApplicationTy { ctor: TypeCtor::FnDef(def), parameters: _ }) => Some(def), 1682 Ty::FnDef(def, _) => Some(def),
1692 _ => None, 1683 _ => None,
1693 }; 1684 };
1694 1685
@@ -1697,20 +1688,16 @@ impl Type {
1697 } 1688 }
1698 1689
1699 pub fn is_closure(&self) -> bool { 1690 pub fn is_closure(&self) -> bool {
1700 matches!(&self.ty.value, Ty::Apply(ApplicationTy { ctor: TypeCtor::Closure { .. }, .. })) 1691 matches!(&self.ty.value, Ty::Closure { .. })
1701 } 1692 }
1702 1693
1703 pub fn is_fn(&self) -> bool { 1694 pub fn is_fn(&self) -> bool {
1704 matches!( 1695 matches!(&self.ty.value, Ty::FnDef(..) | Ty::FnPtr { .. })
1705 &self.ty.value,
1706 Ty::Apply(ApplicationTy { ctor: TypeCtor::FnDef(..), .. })
1707 | Ty::Apply(ApplicationTy { ctor: TypeCtor::FnPtr { .. }, .. })
1708 )
1709 } 1696 }
1710 1697
1711 pub fn is_packed(&self, db: &dyn HirDatabase) -> bool { 1698 pub fn is_packed(&self, db: &dyn HirDatabase) -> bool {
1712 let adt_id = match self.ty.value { 1699 let adt_id = match self.ty.value {
1713 Ty::Apply(ApplicationTy { ctor: TypeCtor::Adt(adt_id), .. }) => adt_id, 1700 Ty::Adt(adt_id, ..) => adt_id,
1714 _ => return false, 1701 _ => return false,
1715 }; 1702 };
1716 1703
@@ -1722,7 +1709,7 @@ impl Type {
1722 } 1709 }
1723 1710
1724 pub fn is_raw_ptr(&self) -> bool { 1711 pub fn is_raw_ptr(&self) -> bool {
1725 matches!(&self.ty.value, Ty::Apply(ApplicationTy { ctor: TypeCtor::RawPtr(..), .. })) 1712 matches!(&self.ty.value, Ty::RawPtr(..))
1726 } 1713 }
1727 1714
1728 pub fn contains_unknown(&self) -> bool { 1715 pub fn contains_unknown(&self) -> bool {
@@ -1731,44 +1718,34 @@ impl Type {
1731 fn go(ty: &Ty) -> bool { 1718 fn go(ty: &Ty) -> bool {
1732 match ty { 1719 match ty {
1733 Ty::Unknown => true, 1720 Ty::Unknown => true,
1734 Ty::Apply(a_ty) => a_ty.parameters.iter().any(go), 1721 _ => ty.substs().map_or(false, |substs| substs.iter().any(go)),
1735 _ => false,
1736 } 1722 }
1737 } 1723 }
1738 } 1724 }
1739 1725
1740 pub fn fields(&self, db: &dyn HirDatabase) -> Vec<(Field, Type)> { 1726 pub fn fields(&self, db: &dyn HirDatabase) -> Vec<(Field, Type)> {
1741 if let Ty::Apply(a_ty) = &self.ty.value { 1727 let (variant_id, substs) = match self.ty.value {
1742 let variant_id = match a_ty.ctor { 1728 Ty::Adt(AdtId::StructId(s), ref substs) => (s.into(), substs),
1743 TypeCtor::Adt(AdtId::StructId(s)) => s.into(), 1729 Ty::Adt(AdtId::UnionId(u), ref substs) => (u.into(), substs),
1744 TypeCtor::Adt(AdtId::UnionId(u)) => u.into(), 1730 _ => return Vec::new(),
1745 _ => return Vec::new(),
1746 };
1747
1748 return db
1749 .field_types(variant_id)
1750 .iter()
1751 .map(|(local_id, ty)| {
1752 let def = Field { parent: variant_id.into(), id: local_id };
1753 let ty = ty.clone().subst(&a_ty.parameters);
1754 (def, self.derived(ty))
1755 })
1756 .collect();
1757 }; 1731 };
1758 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()
1759 } 1741 }
1760 1742
1761 pub fn tuple_fields(&self, _db: &dyn HirDatabase) -> Vec<Type> { 1743 pub fn tuple_fields(&self, _db: &dyn HirDatabase) -> Vec<Type> {
1762 let mut res = Vec::new(); 1744 if let Ty::Tuple { substs, .. } = &self.ty.value {
1763 if let Ty::Apply(a_ty) = &self.ty.value { 1745 substs.iter().map(|ty| self.derived(ty.clone())).collect()
1764 if let TypeCtor::Tuple { .. } = a_ty.ctor { 1746 } else {
1765 for ty in a_ty.parameters.iter() { 1747 Vec::new()
1766 let ty = ty.clone(); 1748 }
1767 res.push(self.derived(ty));
1768 }
1769 }
1770 };
1771 res
1772 } 1749 }
1773 1750
1774 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 {
@@ -1805,15 +1782,13 @@ impl Type {
1805 } 1782 }
1806 1783
1807 pub fn type_parameters(&self) -> impl Iterator<Item = Type> + '_ { 1784 pub fn type_parameters(&self) -> impl Iterator<Item = Type> + '_ {
1808 let ty = self.ty.value.strip_references(); 1785 self.ty
1809 let substs = match ty { 1786 .value
1810 Ty::Apply(apply_ty) => &apply_ty.parameters, 1787 .strip_references()
1811 Ty::Opaque(opaque_ty) => &opaque_ty.parameters, 1788 .substs()
1812 _ => return Either::Left(iter::empty()), 1789 .into_iter()
1813 }; 1790 .flat_map(|substs| substs.iter())
1814 1791 .map(move |ty| self.derived(ty.clone()))
1815 let iter = substs.iter().map(move |ty| self.derived(ty.clone()));
1816 Either::Right(iter)
1817 } 1792 }
1818 1793
1819 pub fn iterate_method_candidates<T>( 1794 pub fn iterate_method_candidates<T>(
@@ -1903,17 +1878,8 @@ impl Type {
1903 1878
1904 // FIXME: provide required accessors such that it becomes implementable from outside. 1879 // FIXME: provide required accessors such that it becomes implementable from outside.
1905 pub fn is_equal_for_find_impls(&self, other: &Type) -> bool { 1880 pub fn is_equal_for_find_impls(&self, other: &Type) -> bool {
1906 match (&self.ty.value, &other.ty.value) { 1881 let rref = other.remove_ref();
1907 (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))
1908 {
1909 TypeCtor::Ref(..) => match parameters.as_single() {
1910 Ty::Apply(a_ty) => a_original_ty.ctor == a_ty.ctor,
1911 _ => false,
1912 },
1913 _ => a_original_ty.ctor == *ctor,
1914 },
1915 _ => false,
1916 }
1917 } 1883 }
1918 1884
1919 fn derived(&self, ty: Ty) -> Type { 1885 fn derived(&self, ty: Ty) -> Type {
@@ -1958,26 +1924,18 @@ impl Type {
1958 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)) {
1959 let ty = type_.ty.value.strip_references(); 1925 let ty = type_.ty.value.strip_references();
1960 match ty { 1926 match ty {
1961 Ty::Apply(ApplicationTy { ctor, parameters }) => { 1927 Ty::Adt(..) => {
1962 match ctor { 1928 cb(type_.derived(ty.clone()));
1963 TypeCtor::Adt(_) => { 1929 }
1964 cb(type_.derived(ty.clone())); 1930 Ty::AssociatedType(..) => {
1965 } 1931 if let Some(_) = ty.associated_type_parent_trait(db) {
1966 TypeCtor::AssociatedType(_) => { 1932 cb(type_.derived(ty.clone()));
1967 if let Some(_) = ty.associated_type_parent_trait(db) { 1933 }
1968 cb(type_.derived(ty.clone())); 1934 }
1969 } 1935 Ty::OpaqueType(..) => {
1970 } 1936 if let Some(bounds) = ty.impl_trait_bounds(db) {
1971 TypeCtor::OpaqueType(..) => { 1937 walk_bounds(db, &type_.derived(ty.clone()), &bounds, cb);
1972 if let Some(bounds) = ty.impl_trait_bounds(db) {
1973 walk_bounds(db, &type_.derived(ty.clone()), &bounds, cb);
1974 }
1975 }
1976 _ => (),
1977 } 1938 }
1978
1979 // adt params, tuples, etc...
1980 walk_substs(db, type_, parameters, cb);
1981 } 1939 }
1982 Ty::Opaque(opaque_ty) => { 1940 Ty::Opaque(opaque_ty) => {
1983 if let Some(bounds) = ty.impl_trait_bounds(db) { 1941 if let Some(bounds) = ty.impl_trait_bounds(db) {
@@ -1995,7 +1953,10 @@ impl Type {
1995 walk_bounds(db, &type_.derived(ty.clone()), bounds.as_ref(), cb); 1953 walk_bounds(db, &type_.derived(ty.clone()), bounds.as_ref(), cb);
1996 } 1954 }
1997 1955
1998 _ => (), 1956 _ => {}
1957 }
1958 if let Some(substs) = ty.substs() {
1959 walk_substs(db, type_, &substs, cb);
1999 } 1960 }
2000 } 1961 }
2001 1962
diff --git a/crates/hir/src/source_analyzer.rs b/crates/hir/src/source_analyzer.rs
index dc21f6051..64ce4add1 100644
--- a/crates/hir/src/source_analyzer.rs
+++ b/crates/hir/src/source_analyzer.rs
@@ -20,7 +20,7 @@ use hir_def::{
20use hir_expand::{hygiene::Hygiene, name::AsName, HirFileId, InFile}; 20use hir_expand::{hygiene::Hygiene, name::AsName, HirFileId, InFile};
21use hir_ty::{ 21use hir_ty::{
22 diagnostics::{record_literal_missing_fields, record_pattern_missing_fields}, 22 diagnostics::{record_literal_missing_fields, record_pattern_missing_fields},
23 InferenceResult, Substs, Ty, 23 InferenceResult, Substs,
24}; 24};
25use syntax::{ 25use syntax::{
26 ast::{self, AstNode}, 26 ast::{self, AstNode},
@@ -299,14 +299,11 @@ impl SourceAnalyzer {
299 let infer = self.infer.as_ref()?; 299 let infer = self.infer.as_ref()?;
300 300
301 let expr_id = self.expr_id(db, &literal.clone().into())?; 301 let expr_id = self.expr_id(db, &literal.clone().into())?;
302 let substs = match &infer.type_of_expr[expr_id] { 302 let substs = infer.type_of_expr[expr_id].substs()?;
303 Ty::Apply(a_ty) => &a_ty.parameters,
304 _ => return None,
305 };
306 303
307 let (variant, missing_fields, _exhaustive) = 304 let (variant, missing_fields, _exhaustive) =
308 record_literal_missing_fields(db, infer, expr_id, &body[expr_id])?; 305 record_literal_missing_fields(db, infer, expr_id, &body[expr_id])?;
309 let res = self.missing_fields(db, krate, substs, variant, missing_fields); 306 let res = self.missing_fields(db, krate, &substs, variant, missing_fields);
310 Some(res) 307 Some(res)
311 } 308 }
312 309
@@ -320,14 +317,11 @@ impl SourceAnalyzer {
320 let infer = self.infer.as_ref()?; 317 let infer = self.infer.as_ref()?;
321 318
322 let pat_id = self.pat_id(&pattern.clone().into())?; 319 let pat_id = self.pat_id(&pattern.clone().into())?;
323 let substs = match &infer.type_of_pat[pat_id] { 320 let substs = infer.type_of_pat[pat_id].substs()?;
324 Ty::Apply(a_ty) => &a_ty.parameters,
325 _ => return None,
326 };
327 321
328 let (variant, missing_fields, _exhaustive) = 322 let (variant, missing_fields, _exhaustive) =
329 record_pattern_missing_fields(db, infer, pat_id, &body[pat_id])?; 323 record_pattern_missing_fields(db, infer, pat_id, &body[pat_id])?;
330 let res = self.missing_fields(db, krate, substs, variant, missing_fields); 324 let res = self.missing_fields(db, krate, &substs, variant, missing_fields);
331 Some(res) 325 Some(res)
332 } 326 }
333 327