aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_def
diff options
context:
space:
mode:
Diffstat (limited to 'crates/hir_def')
-rw-r--r--crates/hir_def/src/generics.rs44
-rw-r--r--crates/hir_def/src/item_tree.rs9
-rw-r--r--crates/hir_def/src/keys.rs5
-rw-r--r--crates/hir_def/src/lib.rs7
-rw-r--r--crates/hir_def/src/resolver.rs17
5 files changed, 68 insertions, 14 deletions
diff --git a/crates/hir_def/src/generics.rs b/crates/hir_def/src/generics.rs
index bb8fca009..9b5b886c2 100644
--- a/crates/hir_def/src/generics.rs
+++ b/crates/hir_def/src/generics.rs
@@ -21,11 +21,11 @@ use crate::{
21 keys, 21 keys,
22 src::{HasChildSource, HasSource}, 22 src::{HasChildSource, HasSource},
23 type_ref::{LifetimeRef, TypeBound, TypeRef}, 23 type_ref::{LifetimeRef, TypeBound, TypeRef},
24 AdtId, GenericDefId, LifetimeParamId, LocalLifetimeParamId, LocalTypeParamId, Lookup, 24 AdtId, ConstParamId, GenericDefId, LifetimeParamId, LocalConstParamId, LocalLifetimeParamId,
25 TypeParamId, 25 LocalTypeParamId, Lookup, TypeParamId,
26}; 26};
27 27
28/// Data about a generic parameter (to a function, struct, impl, ...). 28/// Data about a generic type parameter (to a function, struct, impl, ...).
29#[derive(Clone, PartialEq, Eq, Debug)] 29#[derive(Clone, PartialEq, Eq, Debug)]
30pub struct TypeParamData { 30pub struct TypeParamData {
31 pub name: Option<Name>, 31 pub name: Option<Name>,
@@ -33,12 +33,19 @@ pub struct TypeParamData {
33 pub provenance: TypeParamProvenance, 33 pub provenance: TypeParamProvenance,
34} 34}
35 35
36/// Data about a generic parameter (to a function, struct, impl, ...). 36/// Data about a generic lifetime parameter (to a function, struct, impl, ...).
37#[derive(Clone, PartialEq, Eq, Debug)] 37#[derive(Clone, PartialEq, Eq, Debug)]
38pub struct LifetimeParamData { 38pub struct LifetimeParamData {
39 pub name: Name, 39 pub name: Name,
40} 40}
41 41
42/// Data about a generic const parameter (to a function, struct, impl, ...).
43#[derive(Clone, PartialEq, Eq, Debug)]
44pub struct ConstParamData {
45 pub name: Name,
46 pub ty: TypeRef,
47}
48
42#[derive(Copy, Clone, PartialEq, Eq, Debug)] 49#[derive(Copy, Clone, PartialEq, Eq, Debug)]
43pub enum TypeParamProvenance { 50pub enum TypeParamProvenance {
44 TypeParamList, 51 TypeParamList,
@@ -51,6 +58,7 @@ pub enum TypeParamProvenance {
51pub struct GenericParams { 58pub struct GenericParams {
52 pub types: Arena<TypeParamData>, 59 pub types: Arena<TypeParamData>,
53 pub lifetimes: Arena<LifetimeParamData>, 60 pub lifetimes: Arena<LifetimeParamData>,
61 pub consts: Arena<ConstParamData>,
54 pub where_predicates: Vec<WherePredicate>, 62 pub where_predicates: Vec<WherePredicate>,
55} 63}
56 64
@@ -76,6 +84,7 @@ pub enum WherePredicateTypeTarget {
76pub(crate) struct SourceMap { 84pub(crate) struct SourceMap {
77 pub(crate) type_params: ArenaMap<LocalTypeParamId, Either<ast::Trait, ast::TypeParam>>, 85 pub(crate) type_params: ArenaMap<LocalTypeParamId, Either<ast::Trait, ast::TypeParam>>,
78 lifetime_params: ArenaMap<LocalLifetimeParamId, ast::LifetimeParam>, 86 lifetime_params: ArenaMap<LocalLifetimeParamId, ast::LifetimeParam>,
87 const_params: ArenaMap<LocalConstParamId, ast::ConstParam>,
79} 88}
80 89
81impl GenericParams { 90impl GenericParams {
@@ -268,6 +277,13 @@ impl GenericParams {
268 let lifetime_ref = LifetimeRef::new_name(name); 277 let lifetime_ref = LifetimeRef::new_name(name);
269 self.fill_bounds(&lower_ctx, &lifetime_param, Either::Right(lifetime_ref)); 278 self.fill_bounds(&lower_ctx, &lifetime_param, Either::Right(lifetime_ref));
270 } 279 }
280 for const_param in params.const_params() {
281 let name = const_param.name().map_or_else(Name::missing, |it| it.as_name());
282 let ty = const_param.ty().map_or(TypeRef::Error, |it| TypeRef::from_ast(lower_ctx, it));
283 let param = ConstParamData { name, ty };
284 let param_id = self.consts.alloc(param);
285 sm.const_params.insert(param_id, const_param.clone());
286 }
271 } 287 }
272 288
273 fn fill_where_predicates(&mut self, lower_ctx: &LowerCtx, where_clause: ast::WhereClause) { 289 fn fill_where_predicates(&mut self, lower_ctx: &LowerCtx, where_clause: ast::WhereClause) {
@@ -353,12 +369,16 @@ impl GenericParams {
353 }); 369 });
354 } 370 }
355 371
356 pub fn find_by_name(&self, name: &Name) -> Option<LocalTypeParamId> { 372 pub fn find_type_by_name(&self, name: &Name) -> Option<LocalTypeParamId> {
357 self.types 373 self.types
358 .iter() 374 .iter()
359 .find_map(|(id, p)| if p.name.as_ref() == Some(name) { Some(id) } else { None }) 375 .find_map(|(id, p)| if p.name.as_ref() == Some(name) { Some(id) } else { None })
360 } 376 }
361 377
378 pub fn find_const_by_name(&self, name: &Name) -> Option<LocalConstParamId> {
379 self.consts.iter().find_map(|(id, p)| if p.name == *name { Some(id) } else { None })
380 }
381
362 pub fn find_trait_self_param(&self) -> Option<LocalTypeParamId> { 382 pub fn find_trait_self_param(&self) -> Option<LocalTypeParamId> {
363 self.types.iter().find_map(|(id, p)| { 383 self.types.iter().find_map(|(id, p)| {
364 if p.provenance == TypeParamProvenance::TraitSelf { 384 if p.provenance == TypeParamProvenance::TraitSelf {
@@ -390,6 +410,16 @@ impl HasChildSource<LocalLifetimeParamId> for GenericDefId {
390 } 410 }
391} 411}
392 412
413impl HasChildSource<LocalConstParamId> for GenericDefId {
414 type Value = ast::ConstParam;
415 fn child_source(
416 &self,
417 db: &dyn DefDatabase,
418 ) -> InFile<ArenaMap<LocalConstParamId, Self::Value>> {
419 GenericParams::new(db, *self).1.map(|source_maps| source_maps.const_params)
420 }
421}
422
393impl ChildBySource for GenericDefId { 423impl ChildBySource for GenericDefId {
394 fn child_by_source(&self, db: &dyn DefDatabase) -> DynMap { 424 fn child_by_source(&self, db: &dyn DefDatabase) -> DynMap {
395 let mut res = DynMap::default(); 425 let mut res = DynMap::default();
@@ -406,6 +436,10 @@ impl ChildBySource for GenericDefId {
406 let id = LifetimeParamId { parent: *self, local_id }; 436 let id = LifetimeParamId { parent: *self, local_id };
407 res[keys::LIFETIME_PARAM].insert(sm.with_value(src.clone()), id); 437 res[keys::LIFETIME_PARAM].insert(sm.with_value(src.clone()), id);
408 } 438 }
439 for (local_id, src) in sm.value.const_params.iter() {
440 let id = ConstParamId { parent: *self, local_id };
441 res[keys::CONST_PARAM].insert(sm.with_value(src.clone()), id);
442 }
409 res 443 res
410 } 444 }
411} 445}
diff --git a/crates/hir_def/src/item_tree.rs b/crates/hir_def/src/item_tree.rs
index 100dbf5d6..b6f510731 100644
--- a/crates/hir_def/src/item_tree.rs
+++ b/crates/hir_def/src/item_tree.rs
@@ -260,6 +260,7 @@ impl GenericParamsStorage {
260 fn alloc(&mut self, params: GenericParams) -> GenericParamsId { 260 fn alloc(&mut self, params: GenericParams) -> GenericParamsId {
261 if params.types.is_empty() 261 if params.types.is_empty()
262 && params.lifetimes.is_empty() 262 && params.lifetimes.is_empty()
263 && params.consts.is_empty()
263 && params.where_predicates.is_empty() 264 && params.where_predicates.is_empty()
264 { 265 {
265 return GenericParamsId::EMPTY; 266 return GenericParamsId::EMPTY;
@@ -269,8 +270,12 @@ impl GenericParamsStorage {
269 } 270 }
270} 271}
271 272
272static EMPTY_GENERICS: GenericParams = 273static EMPTY_GENERICS: GenericParams = GenericParams {
273 GenericParams { types: Arena::new(), lifetimes: Arena::new(), where_predicates: Vec::new() }; 274 types: Arena::new(),
275 lifetimes: Arena::new(),
276 consts: Arena::new(),
277 where_predicates: Vec::new(),
278};
274 279
275#[derive(Default, Debug, Eq, PartialEq)] 280#[derive(Default, Debug, Eq, PartialEq)]
276struct ItemTreeData { 281struct ItemTreeData {
diff --git a/crates/hir_def/src/keys.rs b/crates/hir_def/src/keys.rs
index 9c585de2c..89b3ed868 100644
--- a/crates/hir_def/src/keys.rs
+++ b/crates/hir_def/src/keys.rs
@@ -8,8 +8,8 @@ use syntax::{ast, AstNode, AstPtr};
8 8
9use crate::{ 9use crate::{
10 dyn_map::{DynMap, Policy}, 10 dyn_map::{DynMap, Policy},
11 ConstId, EnumId, EnumVariantId, FieldId, FunctionId, ImplId, LifetimeParamId, StaticId, 11 ConstId, ConstParamId, EnumId, EnumVariantId, FieldId, FunctionId, ImplId, LifetimeParamId,
12 StructId, TraitId, TypeAliasId, TypeParamId, UnionId, 12 StaticId, StructId, TraitId, TypeAliasId, TypeParamId, UnionId,
13}; 13};
14 14
15pub type Key<K, V> = crate::dyn_map::Key<InFile<K>, V, AstPtrPolicy<K, V>>; 15pub type Key<K, V> = crate::dyn_map::Key<InFile<K>, V, AstPtrPolicy<K, V>>;
@@ -29,6 +29,7 @@ pub const TUPLE_FIELD: Key<ast::TupleField, FieldId> = Key::new();
29pub const RECORD_FIELD: Key<ast::RecordField, FieldId> = Key::new(); 29pub const RECORD_FIELD: Key<ast::RecordField, FieldId> = Key::new();
30pub const TYPE_PARAM: Key<ast::TypeParam, TypeParamId> = Key::new(); 30pub const TYPE_PARAM: Key<ast::TypeParam, TypeParamId> = Key::new();
31pub const LIFETIME_PARAM: Key<ast::LifetimeParam, LifetimeParamId> = Key::new(); 31pub const LIFETIME_PARAM: Key<ast::LifetimeParam, LifetimeParamId> = Key::new();
32pub const CONST_PARAM: Key<ast::ConstParam, ConstParamId> = Key::new();
32 33
33pub const MACRO: Key<ast::MacroCall, MacroDefId> = Key::new(); 34pub const MACRO: Key<ast::MacroCall, MacroDefId> = Key::new();
34 35
diff --git a/crates/hir_def/src/lib.rs b/crates/hir_def/src/lib.rs
index ba09a9126..25f460504 100644
--- a/crates/hir_def/src/lib.rs
+++ b/crates/hir_def/src/lib.rs
@@ -232,6 +232,13 @@ pub struct LifetimeParamId {
232pub type LocalLifetimeParamId = Idx<generics::LifetimeParamData>; 232pub type LocalLifetimeParamId = Idx<generics::LifetimeParamData>;
233 233
234#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 234#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
235pub struct ConstParamId {
236 pub parent: GenericDefId,
237 pub local_id: LocalConstParamId,
238}
239pub type LocalConstParamId = Idx<generics::ConstParamData>;
240
241#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
235pub enum ContainerId { 242pub enum ContainerId {
236 ModuleId(ModuleId), 243 ModuleId(ModuleId),
237 DefWithBodyId(DefWithBodyId), 244 DefWithBodyId(DefWithBodyId),
diff --git a/crates/hir_def/src/resolver.rs b/crates/hir_def/src/resolver.rs
index f8cc5e075..129f1dbac 100644
--- a/crates/hir_def/src/resolver.rs
+++ b/crates/hir_def/src/resolver.rs
@@ -20,9 +20,9 @@ use crate::{
20 path::{ModPath, PathKind}, 20 path::{ModPath, PathKind},
21 per_ns::PerNs, 21 per_ns::PerNs,
22 visibility::{RawVisibility, Visibility}, 22 visibility::{RawVisibility, Visibility},
23 AdtId, AssocContainerId, ConstId, ContainerId, DefWithBodyId, EnumId, EnumVariantId, 23 AdtId, AssocContainerId, ConstId, ConstParamId, ContainerId, DefWithBodyId, EnumId,
24 FunctionId, GenericDefId, HasModule, ImplId, LocalModuleId, Lookup, ModuleDefId, ModuleId, 24 EnumVariantId, FunctionId, GenericDefId, HasModule, ImplId, LocalModuleId, Lookup, ModuleDefId,
25 StaticId, StructId, TraitId, TypeAliasId, TypeParamId, VariantId, 25 ModuleId, StaticId, StructId, TraitId, TypeAliasId, TypeParamId, VariantId,
26}; 26};
27 27
28#[derive(Debug, Clone, Default)] 28#[derive(Debug, Clone, Default)]
@@ -93,6 +93,7 @@ pub enum ValueNs {
93 StaticId(StaticId), 93 StaticId(StaticId),
94 StructId(StructId), 94 StructId(StructId),
95 EnumVariantId(EnumVariantId), 95 EnumVariantId(EnumVariantId),
96 GenericParam(ConstParamId),
96} 97}
97 98
98impl Resolver { 99impl Resolver {
@@ -163,7 +164,7 @@ impl Resolver {
163 } 164 }
164 165
165 Scope::GenericParams { params, def } => { 166 Scope::GenericParams { params, def } => {
166 if let Some(local_id) = params.find_by_name(first_name) { 167 if let Some(local_id) = params.find_type_by_name(first_name) {
167 let idx = if path.segments.len() == 1 { None } else { Some(1) }; 168 let idx = if path.segments.len() == 1 { None } else { Some(1) };
168 return Some(( 169 return Some((
169 TypeNs::GenericParam(TypeParamId { local_id, parent: *def }), 170 TypeNs::GenericParam(TypeParamId { local_id, parent: *def }),
@@ -285,11 +286,17 @@ impl Resolver {
285 Scope::ExprScope(_) => continue, 286 Scope::ExprScope(_) => continue,
286 287
287 Scope::GenericParams { params, def } if n_segments > 1 => { 288 Scope::GenericParams { params, def } if n_segments > 1 => {
288 if let Some(local_id) = params.find_by_name(first_name) { 289 if let Some(local_id) = params.find_type_by_name(first_name) {
289 let ty = TypeNs::GenericParam(TypeParamId { local_id, parent: *def }); 290 let ty = TypeNs::GenericParam(TypeParamId { local_id, parent: *def });
290 return Some(ResolveValueResult::Partial(ty, 1)); 291 return Some(ResolveValueResult::Partial(ty, 1));
291 } 292 }
292 } 293 }
294 Scope::GenericParams { params, def } if n_segments == 1 => {
295 if let Some(local_id) = params.find_const_by_name(first_name) {
296 let val = ValueNs::GenericParam(ConstParamId { local_id, parent: *def });
297 return Some(ResolveValueResult::ValueNs(val));
298 }
299 }
293 Scope::GenericParams { .. } => continue, 300 Scope::GenericParams { .. } => continue,
294 301
295 Scope::ImplDefScope(impl_) => { 302 Scope::ImplDefScope(impl_) => {