diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2020-12-14 15:15:52 +0000 |
---|---|---|
committer | GitHub <[email protected]> | 2020-12-14 15:15:52 +0000 |
commit | 817fbebbb5f9187994b1a09a603ba9c7b2755a06 (patch) | |
tree | 7f5d35fc2aad9880c6c7573d76ef0947c7b613fc /crates/hir_def/src/generics.rs | |
parent | 134c7563be05d120ffb45d9b971ba95735a0fcb5 (diff) | |
parent | c6172f3f6d3fb0982ae17f48507608609d46d179 (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.rs | 49 |
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 | ||
75 | type SourceMap = ArenaMap<LocalTypeParamId, Either<ast::Trait, ast::TypeParam>>; | 75 | #[derive(Default)] |
76 | pub struct SourceMaps { | ||
77 | pub type_params: ArenaMap<LocalTypeParamId, Either<ast::Trait, ast::TypeParam>>, | ||
78 | pub 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( |
@@ -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 | 348 | impl GenericDefId { | |
344 | impl 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 | ||
353 | impl ChildBySource for GenericDefId { | 355 | impl 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 | } |