diff options
Diffstat (limited to 'crates/hir/src/lib.rs')
-rw-r--r-- | crates/hir/src/lib.rs | 90 |
1 files changed, 66 insertions, 24 deletions
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs index c5161dadd..f0bc2c7b9 100644 --- a/crates/hir/src/lib.rs +++ b/crates/hir/src/lib.rs | |||
@@ -29,6 +29,8 @@ mod has_source; | |||
29 | pub mod diagnostics; | 29 | pub mod diagnostics; |
30 | pub mod db; | 30 | pub mod db; |
31 | 31 | ||
32 | mod display; | ||
33 | |||
32 | use std::{iter, sync::Arc}; | 34 | use std::{iter, sync::Arc}; |
33 | 35 | ||
34 | use arrayvec::ArrayVec; | 36 | use arrayvec::ArrayVec; |
@@ -50,8 +52,8 @@ use hir_def::{ | |||
50 | use hir_expand::{diagnostics::DiagnosticSink, name::name, MacroDefKind}; | 52 | use hir_expand::{diagnostics::DiagnosticSink, name::name, MacroDefKind}; |
51 | use hir_ty::{ | 53 | use hir_ty::{ |
52 | autoderef, | 54 | autoderef, |
53 | display::{write_bounds_like_dyn_trait_with_prefix, HirDisplayError, HirFormatter}, | ||
54 | method_resolution::{self, TyFingerprint}, | 55 | method_resolution::{self, TyFingerprint}, |
56 | primitive::UintTy, | ||
55 | to_assoc_type_id, | 57 | to_assoc_type_id, |
56 | traits::{FnTrait, Solution, SolutionVariables}, | 58 | traits::{FnTrait, Solution, SolutionVariables}, |
57 | AliasTy, BoundVar, CallableDefId, CallableSig, Canonical, DebruijnIndex, GenericPredicate, | 59 | AliasTy, BoundVar, CallableDefId, CallableSig, Canonical, DebruijnIndex, GenericPredicate, |
@@ -571,6 +573,12 @@ impl Struct { | |||
571 | } | 573 | } |
572 | } | 574 | } |
573 | 575 | ||
576 | impl HasVisibility for Struct { | ||
577 | fn visibility(&self, db: &dyn HirDatabase) -> Visibility { | ||
578 | db.struct_data(self.id).visibility.resolve(db.upcast(), &self.id.resolver(db.upcast())) | ||
579 | } | ||
580 | } | ||
581 | |||
574 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 582 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
575 | pub struct Union { | 583 | pub struct Union { |
576 | pub(crate) id: UnionId, | 584 | pub(crate) id: UnionId, |
@@ -603,6 +611,12 @@ impl Union { | |||
603 | } | 611 | } |
604 | } | 612 | } |
605 | 613 | ||
614 | impl HasVisibility for Union { | ||
615 | fn visibility(&self, db: &dyn HirDatabase) -> Visibility { | ||
616 | db.union_data(self.id).visibility.resolve(db.upcast(), &self.id.resolver(db.upcast())) | ||
617 | } | ||
618 | } | ||
619 | |||
606 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 620 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
607 | pub struct Enum { | 621 | pub struct Enum { |
608 | pub(crate) id: EnumId, | 622 | pub(crate) id: EnumId, |
@@ -630,6 +644,12 @@ impl Enum { | |||
630 | } | 644 | } |
631 | } | 645 | } |
632 | 646 | ||
647 | impl HasVisibility for Enum { | ||
648 | fn visibility(&self, db: &dyn HirDatabase) -> Visibility { | ||
649 | db.enum_data(self.id).visibility.resolve(db.upcast(), &self.id.resolver(db.upcast())) | ||
650 | } | ||
651 | } | ||
652 | |||
633 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 653 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
634 | pub struct Variant { | 654 | pub struct Variant { |
635 | pub(crate) parent: Enum, | 655 | pub(crate) parent: Enum, |
@@ -821,7 +841,8 @@ impl Function { | |||
821 | db.function_data(self.id) | 841 | db.function_data(self.id) |
822 | .params | 842 | .params |
823 | .iter() | 843 | .iter() |
824 | .map(|type_ref| { | 844 | .enumerate() |
845 | .map(|(idx, type_ref)| { | ||
825 | let ty = Type { | 846 | let ty = Type { |
826 | krate, | 847 | krate, |
827 | ty: InEnvironment { | 848 | ty: InEnvironment { |
@@ -829,7 +850,7 @@ impl Function { | |||
829 | environment: environment.clone(), | 850 | environment: environment.clone(), |
830 | }, | 851 | }, |
831 | }; | 852 | }; |
832 | Param { ty } | 853 | Param { func: self, ty, idx } |
833 | }) | 854 | }) |
834 | .collect() | 855 | .collect() |
835 | } | 856 | } |
@@ -843,7 +864,7 @@ impl Function { | |||
843 | } | 864 | } |
844 | 865 | ||
845 | pub fn is_unsafe(self, db: &dyn HirDatabase) -> bool { | 866 | pub fn is_unsafe(self, db: &dyn HirDatabase) -> bool { |
846 | db.function_data(self.id).is_unsafe | 867 | db.function_data(self.id).qualifier.is_unsafe |
847 | } | 868 | } |
848 | 869 | ||
849 | pub fn diagnostics(self, db: &dyn HirDatabase, sink: &mut DiagnosticSink) { | 870 | pub fn diagnostics(self, db: &dyn HirDatabase, sink: &mut DiagnosticSink) { |
@@ -892,6 +913,9 @@ impl From<hir_ty::Mutability> for Access { | |||
892 | 913 | ||
893 | #[derive(Debug)] | 914 | #[derive(Debug)] |
894 | pub struct Param { | 915 | pub struct Param { |
916 | func: Function, | ||
917 | /// The index in parameter list, including self parameter. | ||
918 | idx: usize, | ||
895 | ty: Type, | 919 | ty: Type, |
896 | } | 920 | } |
897 | 921 | ||
@@ -899,6 +923,15 @@ impl Param { | |||
899 | pub fn ty(&self) -> &Type { | 923 | pub fn ty(&self) -> &Type { |
900 | &self.ty | 924 | &self.ty |
901 | } | 925 | } |
926 | |||
927 | pub fn pattern_source(&self, db: &dyn HirDatabase) -> Option<ast::Pat> { | ||
928 | let params = self.func.source(db)?.value.param_list()?; | ||
929 | if params.self_param().is_some() { | ||
930 | params.params().nth(self.idx.checked_sub(1)?)?.pat() | ||
931 | } else { | ||
932 | params.params().nth(self.idx)?.pat() | ||
933 | } | ||
934 | } | ||
902 | } | 935 | } |
903 | 936 | ||
904 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 937 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
@@ -921,6 +954,14 @@ impl SelfParam { | |||
921 | }) | 954 | }) |
922 | .unwrap_or(Access::Owned) | 955 | .unwrap_or(Access::Owned) |
923 | } | 956 | } |
957 | |||
958 | pub fn display(self, db: &dyn HirDatabase) -> &'static str { | ||
959 | match self.access(db) { | ||
960 | Access::Shared => "&self", | ||
961 | Access::Exclusive => "&mut self", | ||
962 | Access::Owned => "self", | ||
963 | } | ||
964 | } | ||
924 | } | 965 | } |
925 | 966 | ||
926 | impl HasVisibility for Function { | 967 | impl HasVisibility for Function { |
@@ -948,6 +989,10 @@ impl Const { | |||
948 | pub fn name(self, db: &dyn HirDatabase) -> Option<Name> { | 989 | pub fn name(self, db: &dyn HirDatabase) -> Option<Name> { |
949 | db.const_data(self.id).name.clone() | 990 | db.const_data(self.id).name.clone() |
950 | } | 991 | } |
992 | |||
993 | pub fn type_ref(self, db: &dyn HirDatabase) -> TypeRef { | ||
994 | db.const_data(self.id).type_ref.clone() | ||
995 | } | ||
951 | } | 996 | } |
952 | 997 | ||
953 | impl HasVisibility for Const { | 998 | impl HasVisibility for Const { |
@@ -981,6 +1026,12 @@ impl Static { | |||
981 | } | 1026 | } |
982 | } | 1027 | } |
983 | 1028 | ||
1029 | impl HasVisibility for Static { | ||
1030 | fn visibility(&self, db: &dyn HirDatabase) -> Visibility { | ||
1031 | db.static_data(self.id).visibility.resolve(db.upcast(), &self.id.resolver(db.upcast())) | ||
1032 | } | ||
1033 | } | ||
1034 | |||
984 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 1035 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
985 | pub struct Trait { | 1036 | pub struct Trait { |
986 | pub(crate) id: TraitId, | 1037 | pub(crate) id: TraitId, |
@@ -1000,7 +1051,13 @@ impl Trait { | |||
1000 | } | 1051 | } |
1001 | 1052 | ||
1002 | pub fn is_auto(self, db: &dyn HirDatabase) -> bool { | 1053 | pub fn is_auto(self, db: &dyn HirDatabase) -> bool { |
1003 | db.trait_data(self.id).auto | 1054 | db.trait_data(self.id).is_auto |
1055 | } | ||
1056 | } | ||
1057 | |||
1058 | impl HasVisibility for Trait { | ||
1059 | fn visibility(&self, db: &dyn HirDatabase) -> Visibility { | ||
1060 | db.trait_data(self.id).visibility.resolve(db.upcast(), &self.id.resolver(db.upcast())) | ||
1004 | } | 1061 | } |
1005 | } | 1062 | } |
1006 | 1063 | ||
@@ -1412,19 +1469,6 @@ impl TypeParam { | |||
1412 | } | 1469 | } |
1413 | } | 1470 | } |
1414 | 1471 | ||
1415 | impl HirDisplay for TypeParam { | ||
1416 | fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { | ||
1417 | write!(f, "{}", self.name(f.db))?; | ||
1418 | let bounds = f.db.generic_predicates_for_param(self.id); | ||
1419 | let substs = Substs::type_params(f.db, self.id.parent); | ||
1420 | let predicates = bounds.iter().cloned().map(|b| b.subst(&substs)).collect::<Vec<_>>(); | ||
1421 | if !(predicates.is_empty() || f.omit_verbose_types()) { | ||
1422 | write_bounds_like_dyn_trait_with_prefix(":", &predicates, f)?; | ||
1423 | } | ||
1424 | Ok(()) | ||
1425 | } | ||
1426 | } | ||
1427 | |||
1428 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] | 1472 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] |
1429 | pub struct LifetimeParam { | 1473 | pub struct LifetimeParam { |
1430 | pub(crate) id: LifetimeParamId, | 1474 | pub(crate) id: LifetimeParamId, |
@@ -1631,6 +1675,10 @@ impl Type { | |||
1631 | matches!(self.ty.value.interned(&Interner), TyKind::Ref(hir_ty::Mutability::Mut, ..)) | 1675 | matches!(self.ty.value.interned(&Interner), TyKind::Ref(hir_ty::Mutability::Mut, ..)) |
1632 | } | 1676 | } |
1633 | 1677 | ||
1678 | pub fn is_usize(&self) -> bool { | ||
1679 | matches!(self.ty.value.interned(&Interner), TyKind::Scalar(Scalar::Uint(UintTy::Usize))) | ||
1680 | } | ||
1681 | |||
1634 | pub fn remove_ref(&self) -> Option<Type> { | 1682 | pub fn remove_ref(&self) -> Option<Type> { |
1635 | match &self.ty.value.interned(&Interner) { | 1683 | match &self.ty.value.interned(&Interner) { |
1636 | TyKind::Ref(.., ty) => Some(self.derived(ty.clone())), | 1684 | TyKind::Ref(.., ty) => Some(self.derived(ty.clone())), |
@@ -2054,12 +2102,6 @@ impl Type { | |||
2054 | } | 2102 | } |
2055 | } | 2103 | } |
2056 | 2104 | ||
2057 | impl HirDisplay for Type { | ||
2058 | fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { | ||
2059 | self.ty.value.hir_fmt(f) | ||
2060 | } | ||
2061 | } | ||
2062 | |||
2063 | // FIXME: closures | 2105 | // FIXME: closures |
2064 | #[derive(Debug)] | 2106 | #[derive(Debug)] |
2065 | pub struct Callable { | 2107 | pub struct Callable { |