aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_def/src
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2019-12-07 12:33:08 +0000
committerGitHub <[email protected]>2019-12-07 12:33:08 +0000
commit7aac5f2b427247120025f63c4864a1b937ed20c7 (patch)
tree51a841eaac9c7416e379b23887ee97ddc541ab5c /crates/ra_hir_def/src
parent35fc983dd9e904ad4961b9c10be3397bad33da0c (diff)
parent29b5e1ec2a4bc25daddfe5137503b156b3cd283f (diff)
Merge #2492
2492: Refactor generic parameteres lowering r=flodiebold a=matklad indices and parent params seem to be concerns, specific to `hir_ty`, so move them there. Co-authored-by: Aleksey Kladov <[email protected]>
Diffstat (limited to 'crates/ra_hir_def/src')
-rw-r--r--crates/ra_hir_def/src/generics.rs97
-rw-r--r--crates/ra_hir_def/src/lib.rs10
-rw-r--r--crates/ra_hir_def/src/resolver.rs38
3 files changed, 56 insertions, 89 deletions
diff --git a/crates/ra_hir_def/src/generics.rs b/crates/ra_hir_def/src/generics.rs
index 5f648ffc3..94ce83564 100644
--- a/crates/ra_hir_def/src/generics.rs
+++ b/crates/ra_hir_def/src/generics.rs
@@ -5,20 +5,19 @@
5use std::sync::Arc; 5use std::sync::Arc;
6 6
7use hir_expand::name::{self, AsName, Name}; 7use hir_expand::name::{self, AsName, Name};
8use ra_arena::Arena;
8use ra_syntax::ast::{self, NameOwner, TypeBoundsOwner, TypeParamsOwner}; 9use ra_syntax::ast::{self, NameOwner, TypeBoundsOwner, TypeParamsOwner};
9 10
10use crate::{ 11use crate::{
11 db::DefDatabase, 12 db::DefDatabase,
12 src::HasSource, 13 src::HasSource,
13 type_ref::{TypeBound, TypeRef}, 14 type_ref::{TypeBound, TypeRef},
14 AdtId, AstItemDef, ContainerId, GenericDefId, Lookup, 15 AdtId, AstItemDef, GenericDefId, LocalGenericParamId, Lookup,
15}; 16};
16 17
17/// Data about a generic parameter (to a function, struct, impl, ...). 18/// Data about a generic parameter (to a function, struct, impl, ...).
18#[derive(Clone, PartialEq, Eq, Debug)] 19#[derive(Clone, PartialEq, Eq, Debug)]
19pub struct GenericParam { 20pub struct GenericParamData {
20 // FIXME: give generic params proper IDs
21 pub idx: u32,
22 pub name: Name, 21 pub name: Name,
23 pub default: Option<TypeRef>, 22 pub default: Option<TypeRef>,
24} 23}
@@ -26,8 +25,7 @@ pub struct GenericParam {
26/// Data about the generic parameters of a function, struct, impl, etc. 25/// Data about the generic parameters of a function, struct, impl, etc.
27#[derive(Clone, PartialEq, Eq, Debug)] 26#[derive(Clone, PartialEq, Eq, Debug)]
28pub struct GenericParams { 27pub struct GenericParams {
29 pub parent_params: Option<Arc<GenericParams>>, 28 pub params: Arena<LocalGenericParamId, GenericParamData>,
30 pub params: Vec<GenericParam>,
31 pub where_predicates: Vec<WherePredicate>, 29 pub where_predicates: Vec<WherePredicate>,
32} 30}
33 31
@@ -46,51 +44,40 @@ impl GenericParams {
46 db: &impl DefDatabase, 44 db: &impl DefDatabase,
47 def: GenericDefId, 45 def: GenericDefId,
48 ) -> Arc<GenericParams> { 46 ) -> Arc<GenericParams> {
49 let parent_generics = parent_generic_def(db, def).map(|it| db.generic_params(it)); 47 Arc::new(GenericParams::new(db, def.into()))
50 Arc::new(GenericParams::new(db, def.into(), parent_generics))
51 } 48 }
52 49
53 fn new( 50 fn new(db: &impl DefDatabase, def: GenericDefId) -> GenericParams {
54 db: &impl DefDatabase, 51 let mut generics = GenericParams { params: Arena::default(), where_predicates: Vec::new() };
55 def: GenericDefId,
56 parent_params: Option<Arc<GenericParams>>,
57 ) -> GenericParams {
58 let mut generics =
59 GenericParams { params: Vec::new(), parent_params, where_predicates: Vec::new() };
60 let start = generics.parent_params.as_ref().map(|p| p.params.len()).unwrap_or(0) as u32;
61 // FIXME: add `: Sized` bound for everything except for `Self` in traits 52 // FIXME: add `: Sized` bound for everything except for `Self` in traits
62 match def { 53 match def {
63 GenericDefId::FunctionId(it) => generics.fill(&it.lookup(db).source(db).value, start), 54 GenericDefId::FunctionId(it) => generics.fill(&it.lookup(db).source(db).value),
64 GenericDefId::AdtId(AdtId::StructId(it)) => generics.fill(&it.source(db).value, start), 55 GenericDefId::AdtId(AdtId::StructId(it)) => generics.fill(&it.source(db).value),
65 GenericDefId::AdtId(AdtId::UnionId(it)) => generics.fill(&it.source(db).value, start), 56 GenericDefId::AdtId(AdtId::UnionId(it)) => generics.fill(&it.source(db).value),
66 GenericDefId::AdtId(AdtId::EnumId(it)) => generics.fill(&it.source(db).value, start), 57 GenericDefId::AdtId(AdtId::EnumId(it)) => generics.fill(&it.source(db).value),
67 GenericDefId::TraitId(it) => { 58 GenericDefId::TraitId(it) => {
68 // traits get the Self type as an implicit first type parameter 59 // traits get the Self type as an implicit first type parameter
69 generics.params.push(GenericParam { 60 generics.params.alloc(GenericParamData { name: name::SELF_TYPE, default: None });
70 idx: start, 61 generics.fill(&it.source(db).value);
71 name: name::SELF_TYPE,
72 default: None,
73 });
74 generics.fill(&it.source(db).value, start + 1);
75 // add super traits as bounds on Self 62 // add super traits as bounds on Self
76 // 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
77 let self_param = TypeRef::Path(name::SELF_TYPE.into()); 64 let self_param = TypeRef::Path(name::SELF_TYPE.into());
78 generics.fill_bounds(&it.source(db).value, self_param); 65 generics.fill_bounds(&it.source(db).value, self_param);
79 } 66 }
80 GenericDefId::TypeAliasId(it) => generics.fill(&it.lookup(db).source(db).value, start), 67 GenericDefId::TypeAliasId(it) => generics.fill(&it.lookup(db).source(db).value),
81 // 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
82 // 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
83 // type, so this is handled by the resolver. 70 // type, so this is handled by the resolver.
84 GenericDefId::ImplId(it) => generics.fill(&it.source(db).value, start), 71 GenericDefId::ImplId(it) => generics.fill(&it.source(db).value),
85 GenericDefId::EnumVariantId(_) | GenericDefId::ConstId(_) => {} 72 GenericDefId::EnumVariantId(_) | GenericDefId::ConstId(_) => {}
86 } 73 }
87 74
88 generics 75 generics
89 } 76 }
90 77
91 fn fill(&mut self, node: &impl TypeParamsOwner, start: u32) { 78 fn fill(&mut self, node: &impl TypeParamsOwner) {
92 if let Some(params) = node.type_param_list() { 79 if let Some(params) = node.type_param_list() {
93 self.fill_params(params, start) 80 self.fill_params(params)
94 } 81 }
95 if let Some(where_clause) = node.where_clause() { 82 if let Some(where_clause) = node.where_clause() {
96 self.fill_where_predicates(where_clause); 83 self.fill_where_predicates(where_clause);
@@ -105,13 +92,13 @@ impl GenericParams {
105 } 92 }
106 } 93 }
107 94
108 fn fill_params(&mut self, params: ast::TypeParamList, start: u32) { 95 fn fill_params(&mut self, params: ast::TypeParamList) {
109 for (idx, type_param) in params.type_params().enumerate() { 96 for type_param in params.type_params() {
110 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());
111 // FIXME: Use `Path::from_src` 98 // FIXME: Use `Path::from_src`
112 let default = type_param.default_type().map(TypeRef::from_ast); 99 let default = type_param.default_type().map(TypeRef::from_ast);
113 let param = GenericParam { idx: idx as u32 + start, name: name.clone(), default }; 100 let param = GenericParamData { name: name.clone(), default };
114 self.params.push(param); 101 self.params.alloc(param);
115 102
116 let type_ref = TypeRef::Path(name.into()); 103 let type_ref = TypeRef::Path(name.into());
117 self.fill_bounds(&type_param, type_ref); 104 self.fill_bounds(&type_param, type_ref);
@@ -140,45 +127,7 @@ impl GenericParams {
140 self.where_predicates.push(WherePredicate { type_ref, bound }); 127 self.where_predicates.push(WherePredicate { type_ref, bound });
141 } 128 }
142 129
143 pub fn find_by_name(&self, name: &Name) -> Option<&GenericParam> { 130 pub fn find_by_name(&self, name: &Name) -> Option<LocalGenericParamId> {
144 self.params.iter().find(|p| &p.name == name) 131 self.params.iter().find_map(|(id, p)| if &p.name == name { Some(id) } else { None })
145 }
146
147 pub fn count_parent_params(&self) -> usize {
148 self.parent_params.as_ref().map(|p| p.count_params_including_parent()).unwrap_or(0)
149 }
150
151 pub fn count_params_including_parent(&self) -> usize {
152 let parent_count = self.count_parent_params();
153 parent_count + self.params.len()
154 }
155
156 fn for_each_param<'a>(&'a self, f: &mut impl FnMut(&'a GenericParam)) {
157 if let Some(parent) = &self.parent_params {
158 parent.for_each_param(f);
159 }
160 self.params.iter().for_each(f);
161 }
162
163 pub fn params_including_parent(&self) -> Vec<&GenericParam> {
164 let mut vec = Vec::with_capacity(self.count_params_including_parent());
165 self.for_each_param(&mut |p| vec.push(p));
166 vec
167 }
168}
169
170fn parent_generic_def(db: &impl DefDatabase, def: GenericDefId) -> Option<GenericDefId> {
171 let container = match def {
172 GenericDefId::FunctionId(it) => it.lookup(db).container,
173 GenericDefId::TypeAliasId(it) => it.lookup(db).container,
174 GenericDefId::ConstId(it) => it.lookup(db).container,
175 GenericDefId::EnumVariantId(it) => return Some(it.parent.into()),
176 GenericDefId::AdtId(_) | GenericDefId::TraitId(_) | GenericDefId::ImplId(_) => return None,
177 };
178
179 match container {
180 ContainerId::ImplId(it) => Some(it.into()),
181 ContainerId::TraitId(it) => Some(it.into()),
182 ContainerId::ModuleId(_) => None,
183 } 132 }
184} 133}
diff --git a/crates/ra_hir_def/src/lib.rs b/crates/ra_hir_def/src/lib.rs
index 68e66d276..b8dfc0ab1 100644
--- a/crates/ra_hir_def/src/lib.rs
+++ b/crates/ra_hir_def/src/lib.rs
@@ -318,6 +318,16 @@ macro_rules! impl_froms {
318} 318}
319 319
320#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 320#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
321pub struct GenericParamId {
322 pub parent: GenericDefId,
323 pub local_id: LocalGenericParamId,
324}
325
326#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
327pub struct LocalGenericParamId(RawId);
328impl_arena_id!(LocalGenericParamId);
329
330#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
321pub enum ContainerId { 331pub enum ContainerId {
322 ModuleId(ModuleId), 332 ModuleId(ModuleId),
323 ImplId(ImplId), 333 ImplId(ImplId),
diff --git a/crates/ra_hir_def/src/resolver.rs b/crates/ra_hir_def/src/resolver.rs
index 7d4df222e..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 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) => {