aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_def/src/generics.rs
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2020-12-14 15:15:52 +0000
committerGitHub <[email protected]>2020-12-14 15:15:52 +0000
commit817fbebbb5f9187994b1a09a603ba9c7b2755a06 (patch)
tree7f5d35fc2aad9880c6c7573d76ef0947c7b613fc /crates/hir_def/src/generics.rs
parent134c7563be05d120ffb45d9b971ba95735a0fcb5 (diff)
parentc6172f3f6d3fb0982ae17f48507608609d46d179 (diff)
Merge #6862
6862: Add LifetimeParam resolving to Semantics r=matklad a=Veykril This is stuff required for the lifetime references/definitions PR. I pulled this out to make it easier to review as well as because there is one thing that still has to be addressed which can be found in the review comments. Co-authored-by: Lukas Wirth <[email protected]>
Diffstat (limited to 'crates/hir_def/src/generics.rs')
-rw-r--r--crates/hir_def/src/generics.rs49
1 files changed, 28 insertions, 21 deletions
diff --git a/crates/hir_def/src/generics.rs b/crates/hir_def/src/generics.rs
index 5189c7e9f..81912a454 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,
23 src::HasSource, 22 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
75type SourceMap = ArenaMap<LocalTypeParamId, Either<ast::Trait, ast::TypeParam>>; 75#[derive(Default)]
76pub struct SourceMaps {
77 pub type_params: ArenaMap<LocalTypeParamId, Either<ast::Trait, ast::TypeParam>>,
78 pub lifetime_params: ArenaMap<LocalLifetimeParamId, ast::LifetimeParam>,
79}
76 80
77impl GenericParams { 81impl GenericParams {
78 pub(crate) fn generic_params_query( 82 pub(crate) fn generic_params_query(
@@ -129,9 +133,9 @@ impl GenericParams {
129 Arc::new(generics) 133 Arc::new(generics)
130 } 134 }
131 135
132 fn new(db: &dyn DefDatabase, def: GenericDefId) -> (GenericParams, InFile<SourceMap>) { 136 fn new(db: &dyn DefDatabase, def: GenericDefId) -> (GenericParams, InFile<SourceMaps>) {
133 let mut generics = GenericParams::default(); 137 let mut generics = GenericParams::default();
134 let mut sm = ArenaMap::default(); 138 let mut sm = SourceMaps::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());
@@ -210,7 +214,7 @@ impl GenericParams {
210 pub(crate) fn fill( 214 pub(crate) fn fill(
211 &mut self, 215 &mut self,
212 lower_ctx: &LowerCtx, 216 lower_ctx: &LowerCtx,
213 sm: &mut SourceMap, 217 sm: &mut SourceMaps,
214 node: &dyn GenericParamsOwner, 218 node: &dyn GenericParamsOwner,
215 ) { 219 ) {
216 if let Some(params) = node.generic_param_list() { 220 if let Some(params) = node.generic_param_list() {
@@ -237,7 +241,7 @@ impl GenericParams {
237 fn fill_params( 241 fn fill_params(
238 &mut self, 242 &mut self,
239 lower_ctx: &LowerCtx, 243 lower_ctx: &LowerCtx,
240 sm: &mut SourceMap, 244 sm: &mut SourceMaps,
241 params: ast::GenericParamList, 245 params: ast::GenericParamList,
242 ) { 246 ) {
243 for type_param in params.type_params() { 247 for type_param in params.type_params() {
@@ -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 }
@@ -340,27 +345,29 @@ impl GenericParams {
340 }) 345 })
341 } 346 }
342} 347}
343 348impl GenericDefId {
344impl HasChildSource for GenericDefId { 349 // FIXME: Change HasChildSource's ChildId AssocItem to be a generic parameter instead
345 type ChildId = LocalTypeParamId; 350 pub fn child_source(&self, db: &dyn DefDatabase) -> InFile<SourceMaps> {
346 type Value = Either<ast::Trait, ast::TypeParam>; 351 GenericParams::new(db, *self).1
347 fn child_source(&self, db: &dyn DefDatabase) -> InFile<SourceMap> {
348 let (_, sm) = GenericParams::new(db, *self);
349 sm
350 } 352 }
351} 353}
352 354
353impl ChildBySource for GenericDefId { 355impl ChildBySource for GenericDefId {
354 fn child_by_source(&self, db: &dyn DefDatabase) -> DynMap { 356 fn child_by_source(&self, db: &dyn DefDatabase) -> DynMap {
355 let mut res = DynMap::default(); 357 let mut res = DynMap::default();
356 let arena_map = self.child_source(db); 358 let (_, sm) = GenericParams::new(db, *self);
357 let arena_map = arena_map.as_ref(); 359
358 for (local_id, src) in arena_map.value.iter() { 360 let sm = sm.as_ref();
361 for (local_id, src) in sm.value.type_params.iter() {
359 let id = TypeParamId { parent: *self, local_id }; 362 let id = TypeParamId { parent: *self, local_id };
360 if let Either::Right(type_param) = src { 363 if let Either::Right(type_param) = src {
361 res[keys::TYPE_PARAM].insert(arena_map.with_value(type_param.clone()), id) 364 res[keys::TYPE_PARAM].insert(sm.with_value(type_param.clone()), id)
362 } 365 }
363 } 366 }
367 for (local_id, src) in sm.value.lifetime_params.iter() {
368 let id = LifetimeParamId { parent: *self, local_id };
369 res[keys::LIFETIME_PARAM].insert(sm.with_value(src.clone()), id);
370 }
364 res 371 res
365 } 372 }
366} 373}