aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_def
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir_def')
-rw-r--r--crates/ra_hir_def/src/generics.rs90
-rw-r--r--crates/ra_hir_def/src/resolver.rs38
2 files changed, 42 insertions, 86 deletions
diff --git a/crates/ra_hir_def/src/generics.rs b/crates/ra_hir_def/src/generics.rs
index abe749a40..94ce83564 100644
--- a/crates/ra_hir_def/src/generics.rs
+++ b/crates/ra_hir_def/src/generics.rs
@@ -12,14 +12,12 @@ use crate::{
12 db::DefDatabase, 12 db::DefDatabase,
13 src::HasSource, 13 src::HasSource,
14 type_ref::{TypeBound, TypeRef}, 14 type_ref::{TypeBound, TypeRef},
15 AdtId, AstItemDef, ContainerId, GenericDefId, LocalGenericParamId, Lookup, 15 AdtId, AstItemDef, GenericDefId, LocalGenericParamId, Lookup,
16}; 16};
17 17
18/// Data about a generic parameter (to a function, struct, impl, ...). 18/// Data about a generic parameter (to a function, struct, impl, ...).
19#[derive(Clone, PartialEq, Eq, Debug)] 19#[derive(Clone, PartialEq, Eq, Debug)]
20pub struct GenericParamData { 20pub struct GenericParamData {
21 // FIXME: give generic params proper IDs
22 pub idx: u32,
23 pub name: Name, 21 pub name: Name,
24 pub default: Option<TypeRef>, 22 pub default: Option<TypeRef>,
25} 23}
@@ -27,7 +25,6 @@ pub struct GenericParamData {
27/// Data about the generic parameters of a function, struct, impl, etc. 25/// Data about the generic parameters of a function, struct, impl, etc.
28#[derive(Clone, PartialEq, Eq, Debug)] 26#[derive(Clone, PartialEq, Eq, Debug)]
29pub struct GenericParams { 27pub struct GenericParams {
30 pub parent_params: Option<Arc<GenericParams>>,
31 pub params: Arena<LocalGenericParamId, GenericParamData>, 28 pub params: Arena<LocalGenericParamId, GenericParamData>,
32 pub where_predicates: Vec<WherePredicate>, 29 pub where_predicates: Vec<WherePredicate>,
33} 30}
@@ -47,51 +44,40 @@ impl GenericParams {
47 db: &impl DefDatabase, 44 db: &impl DefDatabase,
48 def: GenericDefId, 45 def: GenericDefId,
49 ) -> Arc<GenericParams> { 46 ) -> Arc<GenericParams> {
50 let parent_generics = parent_generic_def(db, def).map(|it| db.generic_params(it)); 47 Arc::new(GenericParams::new(db, def.into()))
51 Arc::new(GenericParams::new(db, def.into(), parent_generics))
52 } 48 }
53 49
54 fn new( 50 fn new(db: &impl DefDatabase, def: GenericDefId) -> GenericParams {
55 db: &impl DefDatabase, 51 let mut generics = GenericParams { params: Arena::default(), where_predicates: Vec::new() };
56 def: GenericDefId,
57 parent_params: Option<Arc<GenericParams>>,
58 ) -> GenericParams {
59 let mut generics =
60 GenericParams { params: Arena::default(), parent_params, where_predicates: Vec::new() };
61 let start = generics.parent_params.as_ref().map(|p| p.params.len()).unwrap_or(0) as u32;
62 // FIXME: add `: Sized` bound for everything except for `Self` in traits 52 // FIXME: add `: Sized` bound for everything except for `Self` in traits
63 match def { 53 match def {
64 GenericDefId::FunctionId(it) => generics.fill(&it.lookup(db).source(db).value, start), 54 GenericDefId::FunctionId(it) => generics.fill(&it.lookup(db).source(db).value),
65 GenericDefId::AdtId(AdtId::StructId(it)) => generics.fill(&it.source(db).value, start), 55 GenericDefId::AdtId(AdtId::StructId(it)) => generics.fill(&it.source(db).value),
66 GenericDefId::AdtId(AdtId::UnionId(it)) => generics.fill(&it.source(db).value, start), 56 GenericDefId::AdtId(AdtId::UnionId(it)) => generics.fill(&it.source(db).value),
67 GenericDefId::AdtId(AdtId::EnumId(it)) => generics.fill(&it.source(db).value, start), 57 GenericDefId::AdtId(AdtId::EnumId(it)) => generics.fill(&it.source(db).value),
68 GenericDefId::TraitId(it) => { 58 GenericDefId::TraitId(it) => {
69 // traits get the Self type as an implicit first type parameter 59 // traits get the Self type as an implicit first type parameter
70 generics.params.alloc(GenericParamData { 60 generics.params.alloc(GenericParamData { name: name::SELF_TYPE, default: None });
71 idx: start, 61 generics.fill(&it.source(db).value);
72 name: name::SELF_TYPE,
73 default: None,
74 });
75 generics.fill(&it.source(db).value, start + 1);
76 // add super traits as bounds on Self 62 // add super traits as bounds on Self
77 // i.e., trait Foo: Bar is equivalent to trait Foo where Self: Bar 63 // i.e., trait Foo: Bar is equivalent to trait Foo where Self: Bar
78 let self_param = TypeRef::Path(name::SELF_TYPE.into()); 64 let self_param = TypeRef::Path(name::SELF_TYPE.into());
79 generics.fill_bounds(&it.source(db).value, self_param); 65 generics.fill_bounds(&it.source(db).value, self_param);
80 } 66 }
81 GenericDefId::TypeAliasId(it) => generics.fill(&it.lookup(db).source(db).value, start), 67 GenericDefId::TypeAliasId(it) => generics.fill(&it.lookup(db).source(db).value),
82 // Note that we don't add `Self` here: in `impl`s, `Self` is not a 68 // Note that we don't add `Self` here: in `impl`s, `Self` is not a
83 // type-parameter, but rather is a type-alias for impl's target 69 // type-parameter, but rather is a type-alias for impl's target
84 // type, so this is handled by the resolver. 70 // type, so this is handled by the resolver.
85 GenericDefId::ImplId(it) => generics.fill(&it.source(db).value, start), 71 GenericDefId::ImplId(it) => generics.fill(&it.source(db).value),
86 GenericDefId::EnumVariantId(_) | GenericDefId::ConstId(_) => {} 72 GenericDefId::EnumVariantId(_) | GenericDefId::ConstId(_) => {}
87 } 73 }
88 74
89 generics 75 generics
90 } 76 }
91 77
92 fn fill(&mut self, node: &impl TypeParamsOwner, start: u32) { 78 fn fill(&mut self, node: &impl TypeParamsOwner) {
93 if let Some(params) = node.type_param_list() { 79 if let Some(params) = node.type_param_list() {
94 self.fill_params(params, start) 80 self.fill_params(params)
95 } 81 }
96 if let Some(where_clause) = node.where_clause() { 82 if let Some(where_clause) = node.where_clause() {
97 self.fill_where_predicates(where_clause); 83 self.fill_where_predicates(where_clause);
@@ -106,12 +92,12 @@ impl GenericParams {
106 } 92 }
107 } 93 }
108 94
109 fn fill_params(&mut self, params: ast::TypeParamList, start: u32) { 95 fn fill_params(&mut self, params: ast::TypeParamList) {
110 for (idx, type_param) in params.type_params().enumerate() { 96 for type_param in params.type_params() {
111 let name = type_param.name().map_or_else(Name::missing, |it| it.as_name()); 97 let name = type_param.name().map_or_else(Name::missing, |it| it.as_name());
112 // FIXME: Use `Path::from_src` 98 // FIXME: Use `Path::from_src`
113 let default = type_param.default_type().map(TypeRef::from_ast); 99 let default = type_param.default_type().map(TypeRef::from_ast);
114 let param = GenericParamData { idx: idx as u32 + start, name: name.clone(), default }; 100 let param = GenericParamData { name: name.clone(), default };
115 self.params.alloc(param); 101 self.params.alloc(param);
116 102
117 let type_ref = TypeRef::Path(name.into()); 103 let type_ref = TypeRef::Path(name.into());
@@ -141,45 +127,7 @@ impl GenericParams {
141 self.where_predicates.push(WherePredicate { type_ref, bound }); 127 self.where_predicates.push(WherePredicate { type_ref, bound });
142 } 128 }
143 129
144 pub fn find_by_name(&self, name: &Name) -> Option<&GenericParamData> { 130 pub fn find_by_name(&self, name: &Name) -> Option<LocalGenericParamId> {
145 self.params.iter().map(|(_id, data)| data).find(|p| &p.name == name) 131 self.params.iter().find_map(|(id, p)| if &p.name == name { Some(id) } else { None })
146 }
147
148 pub fn count_parent_params(&self) -> usize {
149 self.parent_params.as_ref().map(|p| p.count_params_including_parent()).unwrap_or(0)
150 }
151
152 pub fn count_params_including_parent(&self) -> usize {
153 let parent_count = self.count_parent_params();
154 parent_count + self.params.len()
155 }
156
157 fn for_each_param<'a>(&'a self, f: &mut impl FnMut(&'a GenericParamData)) {
158 if let Some(parent) = &self.parent_params {
159 parent.for_each_param(f);
160 }
161 self.params.iter().map(|(_id, data)| data).for_each(f);
162 }
163
164 pub fn params_including_parent(&self) -> Vec<&GenericParamData> {
165 let mut vec = Vec::with_capacity(self.count_params_including_parent());
166 self.for_each_param(&mut |p| vec.push(p));
167 vec
168 }
169}
170
171fn parent_generic_def(db: &impl DefDatabase, def: GenericDefId) -> Option<GenericDefId> {
172 let container = match def {
173 GenericDefId::FunctionId(it) => it.lookup(db).container,
174 GenericDefId::TypeAliasId(it) => it.lookup(db).container,
175 GenericDefId::ConstId(it) => it.lookup(db).container,
176 GenericDefId::EnumVariantId(it) => return Some(it.parent.into()),
177 GenericDefId::AdtId(_) | GenericDefId::TraitId(_) | GenericDefId::ImplId(_) => return None,
178 };
179
180 match container {
181 ContainerId::ImplId(it) => Some(it.into()),
182 ContainerId::TraitId(it) => Some(it.into()),
183 ContainerId::ModuleId(_) => None,
184 } 132 }
185} 133}
diff --git a/crates/ra_hir_def/src/resolver.rs b/crates/ra_hir_def/src/resolver.rs
index ee19d79a7..e00bd03d5 100644
--- a/crates/ra_hir_def/src/resolver.rs
+++ b/crates/ra_hir_def/src/resolver.rs
@@ -18,12 +18,13 @@ use crate::{
18 path::{Path, PathKind}, 18 path::{Path, PathKind},
19 per_ns::PerNs, 19 per_ns::PerNs,
20 AdtId, AstItemDef, ConstId, ContainerId, DefWithBodyId, EnumId, EnumVariantId, FunctionId, 20 AdtId, AstItemDef, ConstId, ContainerId, DefWithBodyId, EnumId, EnumVariantId, FunctionId,
21 GenericDefId, HasModule, ImplId, LocalModuleId, Lookup, ModuleDefId, ModuleId, StaticId, 21 GenericDefId, GenericParamId, HasModule, ImplId, LocalModuleId, Lookup, ModuleDefId, ModuleId,
22 StructId, TraitId, TypeAliasId, 22 StaticId, StructId, TraitId, TypeAliasId,
23}; 23};
24 24
25#[derive(Debug, Clone, Default)] 25#[derive(Debug, Clone, Default)]
26pub struct Resolver { 26pub struct Resolver {
27 // FIXME: all usages generally call `.rev`, so maybe reverse once in consturciton?
27 scopes: Vec<Scope>, 28 scopes: Vec<Scope>,
28} 29}
29 30
@@ -58,7 +59,7 @@ enum Scope {
58#[derive(Debug, Clone, PartialEq, Eq, Hash)] 59#[derive(Debug, Clone, PartialEq, Eq, Hash)]
59pub enum TypeNs { 60pub enum TypeNs {
60 SelfType(ImplId), 61 SelfType(ImplId),
61 GenericParam(u32), 62 GenericParam(GenericParamId),
62 AdtId(AdtId), 63 AdtId(AdtId),
63 AdtSelfType(AdtId), 64 AdtSelfType(AdtId),
64 // Yup, enum variants are added to the types ns, but any usage of variant as 65 // Yup, enum variants are added to the types ns, but any usage of variant as
@@ -152,10 +153,13 @@ impl Resolver {
152 Scope::ExprScope(_) => continue, 153 Scope::ExprScope(_) => continue,
153 Scope::GenericParams { .. } | Scope::ImplBlockScope(_) if skip_to_mod => continue, 154 Scope::GenericParams { .. } | Scope::ImplBlockScope(_) if skip_to_mod => continue,
154 155
155 Scope::GenericParams { params, .. } => { 156 Scope::GenericParams { params, def } => {
156 if let Some(param) = params.find_by_name(first_name) { 157 if let Some(local_id) = params.find_by_name(first_name) {
157 let idx = if path.segments.len() == 1 { None } else { Some(1) }; 158 let idx = if path.segments.len() == 1 { None } else { Some(1) };
158 return Some((TypeNs::GenericParam(param.idx), idx)); 159 return Some((
160 TypeNs::GenericParam(GenericParamId { local_id, parent: *def }),
161 idx,
162 ));
159 } 163 }
160 } 164 }
161 Scope::ImplBlockScope(impl_) => { 165 Scope::ImplBlockScope(impl_) => {
@@ -246,9 +250,9 @@ impl Resolver {
246 } 250 }
247 Scope::ExprScope(_) => continue, 251 Scope::ExprScope(_) => continue,
248 252
249 Scope::GenericParams { params, .. } if n_segments > 1 => { 253 Scope::GenericParams { params, def } if n_segments > 1 => {
250 if let Some(param) = params.find_by_name(first_name) { 254 if let Some(local_id) = params.find_by_name(first_name) {
251 let ty = TypeNs::GenericParam(param.idx); 255 let ty = TypeNs::GenericParam(GenericParamId { local_id, parent: *def });
252 return Some(ResolveValueResult::Partial(ty, 1)); 256 return Some(ResolveValueResult::Partial(ty, 1));
253 } 257 }
254 } 258 }
@@ -368,6 +372,7 @@ impl Resolver {
368 ) -> impl Iterator<Item = &'a crate::generics::WherePredicate> + 'a { 372 ) -> impl Iterator<Item = &'a crate::generics::WherePredicate> + 'a {
369 self.scopes 373 self.scopes
370 .iter() 374 .iter()
375 .rev()
371 .filter_map(|scope| match scope { 376 .filter_map(|scope| match scope {
372 Scope::GenericParams { params, .. } => Some(params), 377 Scope::GenericParams { params, .. } => Some(params),
373 _ => None, 378 _ => None,
@@ -376,14 +381,14 @@ impl Resolver {
376 } 381 }
377 382
378 pub fn generic_def(&self) -> Option<GenericDefId> { 383 pub fn generic_def(&self) -> Option<GenericDefId> {
379 self.scopes.iter().find_map(|scope| match scope { 384 self.scopes.iter().rev().find_map(|scope| match scope {
380 Scope::GenericParams { def, .. } => Some(*def), 385 Scope::GenericParams { def, .. } => Some(*def),
381 _ => None, 386 _ => None,
382 }) 387 })
383 } 388 }
384 389
385 pub fn body_owner(&self) -> Option<DefWithBodyId> { 390 pub fn body_owner(&self) -> Option<DefWithBodyId> {
386 self.scopes.iter().find_map(|scope| match scope { 391 self.scopes.iter().rev().find_map(|scope| match scope {
387 Scope::ExprScope(it) => Some(it.owner), 392 Scope::ExprScope(it) => Some(it.owner),
388 _ => None, 393 _ => None,
389 }) 394 })
@@ -394,7 +399,7 @@ pub enum ScopeDef {
394 PerNs(PerNs), 399 PerNs(PerNs),
395 ImplSelfType(ImplId), 400 ImplSelfType(ImplId),
396 AdtSelfType(AdtId), 401 AdtSelfType(AdtId),
397 GenericParam(u32), 402 GenericParam(GenericParamId),
398 Local(PatId), 403 Local(PatId),
399} 404}
400 405
@@ -425,9 +430,12 @@ impl Scope {
425 }); 430 });
426 } 431 }
427 } 432 }
428 Scope::GenericParams { params, .. } => { 433 Scope::GenericParams { params, def } => {
429 for (_id, param) in params.params.iter() { 434 for (local_id, param) in params.params.iter() {
430 f(param.name.clone(), ScopeDef::GenericParam(param.idx)) 435 f(
436 param.name.clone(),
437 ScopeDef::GenericParam(GenericParamId { local_id, parent: *def }),
438 )
431 } 439 }
432 } 440 }
433 Scope::ImplBlockScope(i) => { 441 Scope::ImplBlockScope(i) => {