diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2019-12-07 12:33:08 +0000 |
---|---|---|
committer | GitHub <[email protected]> | 2019-12-07 12:33:08 +0000 |
commit | 7aac5f2b427247120025f63c4864a1b937ed20c7 (patch) | |
tree | 51a841eaac9c7416e379b23887ee97ddc541ab5c /crates/ra_hir_def/src | |
parent | 35fc983dd9e904ad4961b9c10be3397bad33da0c (diff) | |
parent | 29b5e1ec2a4bc25daddfe5137503b156b3cd283f (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.rs | 97 | ||||
-rw-r--r-- | crates/ra_hir_def/src/lib.rs | 10 | ||||
-rw-r--r-- | crates/ra_hir_def/src/resolver.rs | 38 |
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 @@ | |||
5 | use std::sync::Arc; | 5 | use std::sync::Arc; |
6 | 6 | ||
7 | use hir_expand::name::{self, AsName, Name}; | 7 | use hir_expand::name::{self, AsName, Name}; |
8 | use ra_arena::Arena; | ||
8 | use ra_syntax::ast::{self, NameOwner, TypeBoundsOwner, TypeParamsOwner}; | 9 | use ra_syntax::ast::{self, NameOwner, TypeBoundsOwner, TypeParamsOwner}; |
9 | 10 | ||
10 | use crate::{ | 11 | use 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)] |
19 | pub struct GenericParam { | 20 | pub 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)] |
28 | pub struct GenericParams { | 27 | pub 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 | |||
170 | fn 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)] |
321 | pub struct GenericParamId { | ||
322 | pub parent: GenericDefId, | ||
323 | pub local_id: LocalGenericParamId, | ||
324 | } | ||
325 | |||
326 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | ||
327 | pub struct LocalGenericParamId(RawId); | ||
328 | impl_arena_id!(LocalGenericParamId); | ||
329 | |||
330 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | ||
321 | pub enum ContainerId { | 331 | pub 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)] |
26 | pub struct Resolver { | 26 | pub 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)] |
59 | pub enum TypeNs { | 60 | pub 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) => { |