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.rs156
-rw-r--r--crates/hir/src/diagnostics.rs4
-rw-r--r--crates/hir/src/semantics.rs8
-rw-r--r--crates/hir/src/source_analyzer.rs16
4 files changed, 71 insertions, 113 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};
38use rustc_hash::FxHashSet; 38use rustc_hash::FxHashSet;
39use stdx::{format_to, impl_from}; 39use 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)]
2011pub struct Callable { 1975pub 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}
diff --git a/crates/hir/src/diagnostics.rs b/crates/hir/src/diagnostics.rs
index 5343a036c..b1ebba516 100644
--- a/crates/hir/src/diagnostics.rs
+++ b/crates/hir/src/diagnostics.rs
@@ -1,5 +1,7 @@
1//! FIXME: write short doc here 1//! FIXME: write short doc here
2pub use hir_def::diagnostics::{InactiveCode, UnresolvedModule, UnresolvedProcMacro}; 2pub use hir_def::diagnostics::{
3 InactiveCode, UnresolvedMacroCall, UnresolvedModule, UnresolvedProcMacro,
4};
3pub use hir_expand::diagnostics::{ 5pub use hir_expand::diagnostics::{
4 Diagnostic, DiagnosticCode, DiagnosticSink, DiagnosticSinkBuilder, 6 Diagnostic, DiagnosticCode, DiagnosticSink, DiagnosticSinkBuilder,
5}; 7};
diff --git a/crates/hir/src/semantics.rs b/crates/hir/src/semantics.rs
index 59292d5a2..144851f83 100644
--- a/crates/hir/src/semantics.rs
+++ b/crates/hir/src/semantics.rs
@@ -16,13 +16,12 @@ use rustc_hash::{FxHashMap, FxHashSet};
16use syntax::{ 16use syntax::{
17 algo::find_node_at_offset, 17 algo::find_node_at_offset,
18 ast::{self, GenericParamsOwner, LoopBodyOwner}, 18 ast::{self, GenericParamsOwner, LoopBodyOwner},
19 match_ast, AstNode, SyntaxNode, SyntaxToken, TextSize, 19 match_ast, AstNode, SyntaxNode, SyntaxNodePtr, SyntaxToken, TextSize,
20}; 20};
21 21
22use crate::{ 22use crate::{
23 code_model::Access, 23 code_model::Access,
24 db::HirDatabase, 24 db::HirDatabase,
25 diagnostics::Diagnostic,
26 semantics::source_to_def::{ChildContainer, SourceToDefCache, SourceToDefCtx}, 25 semantics::source_to_def::{ChildContainer, SourceToDefCache, SourceToDefCtx},
27 source_analyzer::{resolve_hir_path, SourceAnalyzer}, 26 source_analyzer::{resolve_hir_path, SourceAnalyzer},
28 AssocItem, Callable, ConstParam, Crate, Field, Function, HirFileId, Impl, InFile, Label, 27 AssocItem, Callable, ConstParam, Crate, Field, Function, HirFileId, Impl, InFile, Label,
@@ -141,7 +140,7 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> {
141 self.imp.original_range(node) 140 self.imp.original_range(node)
142 } 141 }
143 142
144 pub fn diagnostics_display_range(&self, diagnostics: &dyn Diagnostic) -> FileRange { 143 pub fn diagnostics_display_range(&self, diagnostics: InFile<SyntaxNodePtr>) -> FileRange {
145 self.imp.diagnostics_display_range(diagnostics) 144 self.imp.diagnostics_display_range(diagnostics)
146 } 145 }
147 146
@@ -385,8 +384,7 @@ impl<'db> SemanticsImpl<'db> {
385 node.as_ref().original_file_range(self.db.upcast()) 384 node.as_ref().original_file_range(self.db.upcast())
386 } 385 }
387 386
388 fn diagnostics_display_range(&self, diagnostics: &dyn Diagnostic) -> FileRange { 387 fn diagnostics_display_range(&self, src: InFile<SyntaxNodePtr>) -> FileRange {
389 let src = diagnostics.display_source();
390 let root = self.db.parse_or_expand(src.file_id).unwrap(); 388 let root = self.db.parse_or_expand(src.file_id).unwrap();
391 let node = src.value.to_node(&root); 389 let node = src.value.to_node(&root);
392 self.cache(root, src.file_id); 390 self.cache(root, src.file_id);
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