diff options
Diffstat (limited to 'crates/hir')
-rw-r--r-- | crates/hir/src/code_model.rs | 151 | ||||
-rw-r--r-- | crates/hir/src/source_analyzer.rs | 16 |
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 | }; |
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,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::{ | |||
20 | use hir_expand::{hygiene::Hygiene, name::AsName, HirFileId, InFile}; | 20 | use hir_expand::{hygiene::Hygiene, name::AsName, HirFileId, InFile}; |
21 | use hir_ty::{ | 21 | use 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 | }; |
25 | use syntax::{ | 25 | use 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 | ||