aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir')
-rw-r--r--crates/ra_hir/src/code_model.rs37
-rw-r--r--crates/ra_hir/src/semantics.rs42
2 files changed, 66 insertions, 13 deletions
diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs
index fb788736d..af59aa1b6 100644
--- a/crates/ra_hir/src/code_model.rs
+++ b/crates/ra_hir/src/code_model.rs
@@ -953,6 +953,16 @@ impl TypeParam {
953 pub fn module(self, db: &dyn HirDatabase) -> Module { 953 pub fn module(self, db: &dyn HirDatabase) -> Module {
954 self.id.parent.module(db.upcast()).into() 954 self.id.parent.module(db.upcast()).into()
955 } 955 }
956
957 pub fn ty(self, db: &dyn HirDatabase) -> Type {
958 let resolver = self.id.parent.resolver(db.upcast());
959 let environment = TraitEnvironment::lower(db, &resolver);
960 let ty = Ty::Placeholder(self.id);
961 Type {
962 krate: self.id.parent.module(db.upcast()).krate,
963 ty: InEnvironment { value: ty, environment },
964 }
965 }
956} 966}
957 967
958// FIXME: rename from `ImplDef` to `Impl` 968// FIXME: rename from `ImplDef` to `Impl`
@@ -1157,18 +1167,21 @@ impl Type {
1157 1167
1158 pub fn fields(&self, db: &dyn HirDatabase) -> Vec<(Field, Type)> { 1168 pub fn fields(&self, db: &dyn HirDatabase) -> Vec<(Field, Type)> {
1159 if let Ty::Apply(a_ty) = &self.ty.value { 1169 if let Ty::Apply(a_ty) = &self.ty.value {
1160 if let TypeCtor::Adt(AdtId::StructId(s)) = a_ty.ctor { 1170 let variant_id = match a_ty.ctor {
1161 let var_def = s.into(); 1171 TypeCtor::Adt(AdtId::StructId(s)) => s.into(),
1162 return db 1172 TypeCtor::Adt(AdtId::UnionId(u)) => u.into(),
1163 .field_types(var_def) 1173 _ => return Vec::new(),
1164 .iter() 1174 };
1165 .map(|(local_id, ty)| { 1175
1166 let def = Field { parent: var_def.into(), id: local_id }; 1176 return db
1167 let ty = ty.clone().subst(&a_ty.parameters); 1177 .field_types(variant_id)
1168 (def, self.derived(ty)) 1178 .iter()
1169 }) 1179 .map(|(local_id, ty)| {
1170 .collect(); 1180 let def = Field { parent: variant_id.into(), id: local_id };
1171 } 1181 let ty = ty.clone().subst(&a_ty.parameters);
1182 (def, self.derived(ty))
1183 })
1184 .collect();
1172 }; 1185 };
1173 Vec::new() 1186 Vec::new()
1174 } 1187 }
diff --git a/crates/ra_hir/src/semantics.rs b/crates/ra_hir/src/semantics.rs
index 86bfb416c..a0a0f234b 100644
--- a/crates/ra_hir/src/semantics.rs
+++ b/crates/ra_hir/src/semantics.rs
@@ -9,6 +9,7 @@ use hir_def::{
9 AsMacroCall, TraitId, 9 AsMacroCall, TraitId,
10}; 10};
11use hir_expand::ExpansionInfo; 11use hir_expand::ExpansionInfo;
12use hir_ty::associated_type_shorthand_candidates;
12use itertools::Itertools; 13use itertools::Itertools;
13use ra_db::{FileId, FileRange}; 14use ra_db::{FileId, FileRange};
14use ra_prof::profile; 15use ra_prof::profile;
@@ -24,8 +25,9 @@ use crate::{
24 semantics::source_to_def::{ChildContainer, SourceToDefCache, SourceToDefCtx}, 25 semantics::source_to_def::{ChildContainer, SourceToDefCache, SourceToDefCtx},
25 source_analyzer::{resolve_hir_path, SourceAnalyzer}, 26 source_analyzer::{resolve_hir_path, SourceAnalyzer},
26 AssocItem, Field, Function, HirFileId, ImplDef, InFile, Local, MacroDef, Module, ModuleDef, 27 AssocItem, Field, Function, HirFileId, ImplDef, InFile, Local, MacroDef, Module, ModuleDef,
27 Name, Origin, Path, ScopeDef, Trait, Type, TypeParam, 28 Name, Origin, Path, ScopeDef, Trait, Type, TypeAlias, TypeParam,
28}; 29};
30use resolver::TypeNs;
29 31
30#[derive(Debug, Clone, PartialEq, Eq)] 32#[derive(Debug, Clone, PartialEq, Eq)]
31pub enum PathResolution { 33pub enum PathResolution {
@@ -40,6 +42,44 @@ pub enum PathResolution {
40 AssocItem(AssocItem), 42 AssocItem(AssocItem),
41} 43}
42 44
45impl PathResolution {
46 fn in_type_ns(&self) -> Option<TypeNs> {
47 match self {
48 PathResolution::Def(ModuleDef::Adt(adt)) => Some(TypeNs::AdtId((*adt).into())),
49 PathResolution::Def(ModuleDef::BuiltinType(builtin)) => {
50 Some(TypeNs::BuiltinType(*builtin))
51 }
52 PathResolution::Def(ModuleDef::Const(_))
53 | PathResolution::Def(ModuleDef::EnumVariant(_))
54 | PathResolution::Def(ModuleDef::Function(_))
55 | PathResolution::Def(ModuleDef::Module(_))
56 | PathResolution::Def(ModuleDef::Static(_))
57 | PathResolution::Def(ModuleDef::Trait(_)) => None,
58 PathResolution::Def(ModuleDef::TypeAlias(alias)) => {
59 Some(TypeNs::TypeAliasId((*alias).into()))
60 }
61 PathResolution::Local(_) | PathResolution::Macro(_) => None,
62 PathResolution::TypeParam(param) => Some(TypeNs::GenericParam((*param).into())),
63 PathResolution::SelfType(impl_def) => Some(TypeNs::SelfType((*impl_def).into())),
64 PathResolution::AssocItem(AssocItem::Const(_))
65 | PathResolution::AssocItem(AssocItem::Function(_)) => None,
66 PathResolution::AssocItem(AssocItem::TypeAlias(alias)) => {
67 Some(TypeNs::TypeAliasId((*alias).into()))
68 }
69 }
70 }
71
72 /// Returns an iterator over associated types that may be specified after this path (using
73 /// `Ty::Assoc` syntax).
74 pub fn assoc_type_shorthand_candidates<R>(
75 &self,
76 db: &dyn HirDatabase,
77 mut cb: impl FnMut(TypeAlias) -> Option<R>,
78 ) -> Option<R> {
79 associated_type_shorthand_candidates(db, self.in_type_ns()?, |_, _, id| cb(id.into()))
80 }
81}
82
43/// Primary API to get semantic information, like types, from syntax trees. 83/// Primary API to get semantic information, like types, from syntax trees.
44pub struct Semantics<'db, DB> { 84pub struct Semantics<'db, DB> {
45 pub db: &'db DB, 85 pub db: &'db DB,