diff options
Diffstat (limited to 'crates/hir_def/src/generics.rs')
-rw-r--r-- | crates/hir_def/src/generics.rs | 55 |
1 files changed, 38 insertions, 17 deletions
diff --git a/crates/hir_def/src/generics.rs b/crates/hir_def/src/generics.rs index 5189c7e9f..924046435 100644 --- a/crates/hir_def/src/generics.rs +++ b/crates/hir_def/src/generics.rs | |||
@@ -19,10 +19,10 @@ use crate::{ | |||
19 | db::DefDatabase, | 19 | db::DefDatabase, |
20 | dyn_map::DynMap, | 20 | dyn_map::DynMap, |
21 | keys, | 21 | keys, |
22 | src::HasChildSource, | 22 | src::{HasChildSource, HasSource}, |
23 | src::HasSource, | ||
24 | type_ref::{LifetimeRef, TypeBound, TypeRef}, | 23 | type_ref::{LifetimeRef, TypeBound, TypeRef}, |
25 | AdtId, GenericDefId, LocalTypeParamId, Lookup, TypeParamId, | 24 | AdtId, GenericDefId, LifetimeParamId, LocalLifetimeParamId, LocalTypeParamId, Lookup, |
25 | TypeParamId, | ||
26 | }; | 26 | }; |
27 | 27 | ||
28 | /// Data about a generic parameter (to a function, struct, impl, ...). | 28 | /// Data about a generic parameter (to a function, struct, impl, ...). |
@@ -72,7 +72,11 @@ pub enum WherePredicateTypeTarget { | |||
72 | // FIXME: ForLifetime(Vec<LifetimeParamId>, TypeRef) | 72 | // FIXME: ForLifetime(Vec<LifetimeParamId>, TypeRef) |
73 | } | 73 | } |
74 | 74 | ||
75 | type SourceMap = ArenaMap<LocalTypeParamId, Either<ast::Trait, ast::TypeParam>>; | 75 | #[derive(Default)] |
76 | pub(crate) struct SourceMap { | ||
77 | pub(crate) type_params: ArenaMap<LocalTypeParamId, Either<ast::Trait, ast::TypeParam>>, | ||
78 | lifetime_params: ArenaMap<LocalLifetimeParamId, ast::LifetimeParam>, | ||
79 | } | ||
76 | 80 | ||
77 | impl GenericParams { | 81 | impl GenericParams { |
78 | pub(crate) fn generic_params_query( | 82 | pub(crate) fn generic_params_query( |
@@ -131,7 +135,7 @@ impl GenericParams { | |||
131 | 135 | ||
132 | fn new(db: &dyn DefDatabase, def: GenericDefId) -> (GenericParams, InFile<SourceMap>) { | 136 | fn new(db: &dyn DefDatabase, def: GenericDefId) -> (GenericParams, InFile<SourceMap>) { |
133 | let mut generics = GenericParams::default(); | 137 | let mut generics = GenericParams::default(); |
134 | let mut sm = ArenaMap::default(); | 138 | let mut sm = SourceMap::default(); |
135 | 139 | ||
136 | // FIXME: add `: Sized` bound for everything except for `Self` in traits | 140 | // FIXME: add `: Sized` bound for everything except for `Self` in traits |
137 | let file_id = match def { | 141 | let file_id = match def { |
@@ -174,7 +178,7 @@ impl GenericParams { | |||
174 | default: None, | 178 | default: None, |
175 | provenance: TypeParamProvenance::TraitSelf, | 179 | provenance: TypeParamProvenance::TraitSelf, |
176 | }); | 180 | }); |
177 | sm.insert(self_param_id, Either::Left(src.value.clone())); | 181 | sm.type_params.insert(self_param_id, Either::Left(src.value.clone())); |
178 | // add super traits as bounds on Self | 182 | // add super traits as bounds on Self |
179 | // i.e., trait Foo: Bar is equivalent to trait Foo where Self: Bar | 183 | // i.e., trait Foo: Bar is equivalent to trait Foo where Self: Bar |
180 | let self_param = TypeRef::Path(name![Self].into()); | 184 | let self_param = TypeRef::Path(name![Self].into()); |
@@ -250,7 +254,7 @@ impl GenericParams { | |||
250 | provenance: TypeParamProvenance::TypeParamList, | 254 | provenance: TypeParamProvenance::TypeParamList, |
251 | }; | 255 | }; |
252 | let param_id = self.types.alloc(param); | 256 | let param_id = self.types.alloc(param); |
253 | sm.insert(param_id, Either::Right(type_param.clone())); | 257 | sm.type_params.insert(param_id, Either::Right(type_param.clone())); |
254 | 258 | ||
255 | let type_ref = TypeRef::Path(name.into()); | 259 | let type_ref = TypeRef::Path(name.into()); |
256 | self.fill_bounds(&lower_ctx, &type_param, Either::Left(type_ref)); | 260 | self.fill_bounds(&lower_ctx, &type_param, Either::Left(type_ref)); |
@@ -260,7 +264,8 @@ impl GenericParams { | |||
260 | .lifetime_token() | 264 | .lifetime_token() |
261 | .map_or_else(Name::missing, |tok| Name::new_lifetime(&tok)); | 265 | .map_or_else(Name::missing, |tok| Name::new_lifetime(&tok)); |
262 | let param = LifetimeParamData { name: name.clone() }; | 266 | let param = LifetimeParamData { name: name.clone() }; |
263 | let _param_id = self.lifetimes.alloc(param); | 267 | let param_id = self.lifetimes.alloc(param); |
268 | sm.lifetime_params.insert(param_id, lifetime_param.clone()); | ||
264 | let lifetime_ref = LifetimeRef::new_name(name); | 269 | let lifetime_ref = LifetimeRef::new_name(name); |
265 | self.fill_bounds(&lower_ctx, &lifetime_param, Either::Right(lifetime_ref)); | 270 | self.fill_bounds(&lower_ctx, &lifetime_param, Either::Right(lifetime_ref)); |
266 | } | 271 | } |
@@ -341,26 +346,42 @@ impl GenericParams { | |||
341 | } | 346 | } |
342 | } | 347 | } |
343 | 348 | ||
344 | impl HasChildSource for GenericDefId { | 349 | impl HasChildSource<LocalTypeParamId> for GenericDefId { |
345 | type ChildId = LocalTypeParamId; | ||
346 | type Value = Either<ast::Trait, ast::TypeParam>; | 350 | type Value = Either<ast::Trait, ast::TypeParam>; |
347 | fn child_source(&self, db: &dyn DefDatabase) -> InFile<SourceMap> { | 351 | fn child_source( |
348 | let (_, sm) = GenericParams::new(db, *self); | 352 | &self, |
349 | sm | 353 | db: &dyn DefDatabase, |
354 | ) -> InFile<ArenaMap<LocalTypeParamId, Self::Value>> { | ||
355 | GenericParams::new(db, *self).1.map(|source_maps| source_maps.type_params) | ||
356 | } | ||
357 | } | ||
358 | |||
359 | impl HasChildSource<LocalLifetimeParamId> for GenericDefId { | ||
360 | type Value = ast::LifetimeParam; | ||
361 | fn child_source( | ||
362 | &self, | ||
363 | db: &dyn DefDatabase, | ||
364 | ) -> InFile<ArenaMap<LocalLifetimeParamId, Self::Value>> { | ||
365 | GenericParams::new(db, *self).1.map(|source_maps| source_maps.lifetime_params) | ||
350 | } | 366 | } |
351 | } | 367 | } |
352 | 368 | ||
353 | impl ChildBySource for GenericDefId { | 369 | impl ChildBySource for GenericDefId { |
354 | fn child_by_source(&self, db: &dyn DefDatabase) -> DynMap { | 370 | fn child_by_source(&self, db: &dyn DefDatabase) -> DynMap { |
355 | let mut res = DynMap::default(); | 371 | let mut res = DynMap::default(); |
356 | let arena_map = self.child_source(db); | 372 | let (_, sm) = GenericParams::new(db, *self); |
357 | let arena_map = arena_map.as_ref(); | 373 | |
358 | for (local_id, src) in arena_map.value.iter() { | 374 | let sm = sm.as_ref(); |
375 | for (local_id, src) in sm.value.type_params.iter() { | ||
359 | let id = TypeParamId { parent: *self, local_id }; | 376 | let id = TypeParamId { parent: *self, local_id }; |
360 | if let Either::Right(type_param) = src { | 377 | if let Either::Right(type_param) = src { |
361 | res[keys::TYPE_PARAM].insert(arena_map.with_value(type_param.clone()), id) | 378 | res[keys::TYPE_PARAM].insert(sm.with_value(type_param.clone()), id) |
362 | } | 379 | } |
363 | } | 380 | } |
381 | for (local_id, src) in sm.value.lifetime_params.iter() { | ||
382 | let id = LifetimeParamId { parent: *self, local_id }; | ||
383 | res[keys::LIFETIME_PARAM].insert(sm.with_value(src.clone()), id); | ||
384 | } | ||
364 | res | 385 | res |
365 | } | 386 | } |
366 | } | 387 | } |