aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/code_model.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir/src/code_model.rs')
-rw-r--r--crates/ra_hir/src/code_model.rs94
1 files changed, 68 insertions, 26 deletions
diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs
index a132d128b..5690040a7 100644
--- a/crates/ra_hir/src/code_model.rs
+++ b/crates/ra_hir/src/code_model.rs
@@ -10,10 +10,12 @@ use hir_def::{
10 adt::VariantData, 10 adt::VariantData,
11 body::scope::ExprScopes, 11 body::scope::ExprScopes,
12 builtin_type::BuiltinType, 12 builtin_type::BuiltinType,
13 nameres::per_ns::PerNs,
14 resolver::{HasResolver, TypeNs},
13 traits::TraitData, 15 traits::TraitData,
14 type_ref::{Mutability, TypeRef}, 16 type_ref::{Mutability, TypeRef},
15 AssocItemId, ContainerId, CrateModuleId, HasModule, ImplId, LocalEnumVariantId, 17 ContainerId, CrateModuleId, HasModule, ImplId, LocalEnumVariantId, LocalStructFieldId, Lookup,
16 LocalStructFieldId, Lookup, ModuleId, UnionId, 18 ModuleId, UnionId,
17}; 19};
18use hir_expand::{ 20use hir_expand::{
19 diagnostics::DiagnosticSink, 21 diagnostics::DiagnosticSink,
@@ -25,14 +27,12 @@ use ra_syntax::ast::{self, NameOwner, TypeAscriptionOwner};
25use crate::{ 27use crate::{
26 db::{AstDatabase, DefDatabase, HirDatabase}, 28 db::{AstDatabase, DefDatabase, HirDatabase},
27 expr::{BindingAnnotation, Body, BodySourceMap, ExprValidator, Pat, PatId}, 29 expr::{BindingAnnotation, Body, BodySourceMap, ExprValidator, Pat, PatId},
28 generics::{GenericDef, HasGenericParams},
29 ids::{ 30 ids::{
30 AstItemDef, ConstId, EnumId, FunctionId, MacroDefId, StaticId, StructId, TraitId, 31 AstItemDef, ConstId, EnumId, FunctionId, MacroDefId, StaticId, StructId, TraitId,
31 TypeAliasId, 32 TypeAliasId,
32 }, 33 },
33 resolve::{HasResolver, TypeNs},
34 ty::{InferenceResult, Namespace, TraitRef}, 34 ty::{InferenceResult, Namespace, TraitRef},
35 Either, HasSource, ImportId, Name, ScopeDef, Source, Ty, 35 Either, HasSource, ImportId, Name, Source, Ty,
36}; 36};
37 37
38/// hir::Crate describes a single crate. It's the main interface with which 38/// hir::Crate describes a single crate. It's the main interface with which
@@ -829,12 +829,12 @@ impl Trait {
829 } 829 }
830 830
831 fn direct_super_traits(self, db: &impl HirDatabase) -> Vec<Trait> { 831 fn direct_super_traits(self, db: &impl HirDatabase) -> Vec<Trait> {
832 let resolver = self.resolver(db); 832 let resolver = self.id.resolver(db);
833 // returning the iterator directly doesn't easily work because of 833 // returning the iterator directly doesn't easily work because of
834 // lifetime problems, but since there usually shouldn't be more than a 834 // lifetime problems, but since there usually shouldn't be more than a
835 // few direct traits this should be fine (we could even use some kind of 835 // few direct traits this should be fine (we could even use some kind of
836 // SmallVec if performance is a concern) 836 // SmallVec if performance is a concern)
837 self.generic_params(db) 837 db.generic_params(self.id.into())
838 .where_predicates 838 .where_predicates
839 .iter() 839 .iter()
840 .filter_map(|pred| match &pred.type_ref { 840 .filter_map(|pred| match &pred.type_ref {
@@ -842,9 +842,10 @@ impl Trait {
842 _ => None, 842 _ => None,
843 }) 843 })
844 .filter_map(|path| match resolver.resolve_path_in_type_ns_fully(db, path) { 844 .filter_map(|path| match resolver.resolve_path_in_type_ns_fully(db, path) {
845 Some(TypeNs::Trait(t)) => Some(t), 845 Some(TypeNs::TraitId(t)) => Some(t),
846 _ => None, 846 _ => None,
847 }) 847 })
848 .map(Trait::from)
848 .collect() 849 .collect()
849 } 850 }
850 851
@@ -871,14 +872,9 @@ impl Trait {
871 872
872 pub fn associated_type_by_name(self, db: &impl DefDatabase, name: &Name) -> Option<TypeAlias> { 873 pub fn associated_type_by_name(self, db: &impl DefDatabase, name: &Name) -> Option<TypeAlias> {
873 let trait_data = self.trait_data(db); 874 let trait_data = self.trait_data(db);
874 trait_data 875 let res =
875 .items 876 trait_data.associated_types().map(TypeAlias::from).find(|t| &t.name(db) == name)?;
876 .iter() 877 Some(res)
877 .filter_map(|item| match item {
878 AssocItemId::TypeAliasId(t) => Some(TypeAlias::from(*t)),
879 _ => None,
880 })
881 .find(|t| &t.name(db) == name)
882 } 878 }
883 879
884 pub fn associated_type_by_name_including_super_traits( 880 pub fn associated_type_by_name_including_super_traits(
@@ -978,16 +974,6 @@ pub enum AssocItem {
978// casting them, and somehow making the constructors private, which would be annoying. 974// casting them, and somehow making the constructors private, which would be annoying.
979impl_froms!(AssocItem: Function, Const, TypeAlias); 975impl_froms!(AssocItem: Function, Const, TypeAlias);
980 976
981impl From<AssocItem> for crate::generics::GenericDef {
982 fn from(item: AssocItem) -> Self {
983 match item {
984 AssocItem::Function(f) => f.into(),
985 AssocItem::Const(c) => c.into(),
986 AssocItem::TypeAlias(t) => t.into(),
987 }
988 }
989}
990
991impl AssocItem { 977impl AssocItem {
992 pub fn module(self, db: &impl DefDatabase) -> Module { 978 pub fn module(self, db: &impl DefDatabase) -> Module {
993 match self { 979 match self {
@@ -1007,6 +993,39 @@ impl AssocItem {
1007 } 993 }
1008} 994}
1009 995
996#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
997pub enum GenericDef {
998 Function(Function),
999 Adt(Adt),
1000 Trait(Trait),
1001 TypeAlias(TypeAlias),
1002 ImplBlock(ImplBlock),
1003 // enum variants cannot have generics themselves, but their parent enums
1004 // can, and this makes some code easier to write
1005 EnumVariant(EnumVariant),
1006 // consts can have type parameters from their parents (i.e. associated consts of traits)
1007 Const(Const),
1008}
1009impl_froms!(
1010 GenericDef: Function,
1011 Adt(Struct, Enum, Union),
1012 Trait,
1013 TypeAlias,
1014 ImplBlock,
1015 EnumVariant,
1016 Const
1017);
1018
1019impl From<AssocItem> for GenericDef {
1020 fn from(item: AssocItem) -> Self {
1021 match item {
1022 AssocItem::Function(f) => f.into(),
1023 AssocItem::Const(c) => c.into(),
1024 AssocItem::TypeAlias(t) => t.into(),
1025 }
1026 }
1027}
1028
1010#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] 1029#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
1011pub struct Local { 1030pub struct Local {
1012 pub(crate) parent: DefWithBody, 1031 pub(crate) parent: DefWithBody,
@@ -1068,3 +1087,26 @@ pub struct GenericParam {
1068pub struct ImplBlock { 1087pub struct ImplBlock {
1069 pub(crate) id: ImplId, 1088 pub(crate) id: ImplId,
1070} 1089}
1090
1091/// For IDE only
1092pub enum ScopeDef {
1093 ModuleDef(ModuleDef),
1094 MacroDef(MacroDef),
1095 GenericParam(GenericParam),
1096 ImplSelfType(ImplBlock),
1097 AdtSelfType(Adt),
1098 Local(Local),
1099 Unknown,
1100}
1101
1102impl From<PerNs> for ScopeDef {
1103 fn from(def: PerNs) -> Self {
1104 def.take_types()
1105 .or_else(|| def.take_values())
1106 .map(|module_def_id| ScopeDef::ModuleDef(module_def_id.into()))
1107 .or_else(|| {
1108 def.get_macros().map(|macro_def_id| ScopeDef::MacroDef(macro_def_id.into()))
1109 })
1110 .unwrap_or(ScopeDef::Unknown)
1111 }
1112}