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 | |
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')
-rw-r--r-- | crates/hir_def/src/generics.rs | 49 | ||||
-rw-r--r-- | crates/hir_def/src/item_tree/lower.rs | 5 | ||||
-rw-r--r-- | crates/hir_def/src/keys.rs | 5 |
3 files changed, 33 insertions, 26 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 | } |
diff --git a/crates/hir_def/src/item_tree/lower.rs b/crates/hir_def/src/item_tree/lower.rs index f7ce2e26d..2939c6b1e 100644 --- a/crates/hir_def/src/item_tree/lower.rs +++ b/crates/hir_def/src/item_tree/lower.rs | |||
@@ -2,7 +2,6 @@ | |||
2 | 2 | ||
3 | use std::{collections::hash_map::Entry, mem, sync::Arc}; | 3 | use std::{collections::hash_map::Entry, mem, sync::Arc}; |
4 | 4 | ||
5 | use arena::map::ArenaMap; | ||
6 | use hir_expand::{ast_id_map::AstIdMap, hygiene::Hygiene, name::known, HirFileId}; | 5 | use hir_expand::{ast_id_map::AstIdMap, hygiene::Hygiene, name::known, HirFileId}; |
7 | use smallvec::SmallVec; | 6 | use smallvec::SmallVec; |
8 | use syntax::{ | 7 | use syntax::{ |
@@ -607,7 +606,7 @@ impl Ctx { | |||
607 | owner: GenericsOwner<'_>, | 606 | owner: GenericsOwner<'_>, |
608 | node: &impl ast::GenericParamsOwner, | 607 | node: &impl ast::GenericParamsOwner, |
609 | ) -> GenericParamsId { | 608 | ) -> GenericParamsId { |
610 | let mut sm = &mut ArenaMap::default(); | 609 | let mut sm = &mut Default::default(); |
611 | let mut generics = GenericParams::default(); | 610 | let mut generics = GenericParams::default(); |
612 | match owner { | 611 | match owner { |
613 | GenericsOwner::Function(func) => { | 612 | GenericsOwner::Function(func) => { |
@@ -630,7 +629,7 @@ impl Ctx { | |||
630 | default: None, | 629 | default: None, |
631 | provenance: TypeParamProvenance::TraitSelf, | 630 | provenance: TypeParamProvenance::TraitSelf, |
632 | }); | 631 | }); |
633 | sm.insert(self_param_id, Either::Left(trait_def.clone())); | 632 | sm.type_params.insert(self_param_id, Either::Left(trait_def.clone())); |
634 | // add super traits as bounds on Self | 633 | // add super traits as bounds on Self |
635 | // i.e., trait Foo: Bar is equivalent to trait Foo where Self: Bar | 634 | // i.e., trait Foo: Bar is equivalent to trait Foo where Self: Bar |
636 | let self_param = TypeRef::Path(name![Self].into()); | 635 | let self_param = TypeRef::Path(name![Self].into()); |
diff --git a/crates/hir_def/src/keys.rs b/crates/hir_def/src/keys.rs index 40a5d92b5..9c585de2c 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 | ||
9 | use crate::{ | 9 | use crate::{ |
10 | dyn_map::{DynMap, Policy}, | 10 | dyn_map::{DynMap, Policy}, |
11 | ConstId, EnumId, EnumVariantId, FieldId, FunctionId, ImplId, StaticId, StructId, TraitId, | 11 | ConstId, EnumId, EnumVariantId, FieldId, FunctionId, ImplId, LifetimeParamId, StaticId, |
12 | TypeAliasId, TypeParamId, UnionId, | 12 | StructId, TraitId, TypeAliasId, TypeParamId, UnionId, |
13 | }; | 13 | }; |
14 | 14 | ||
15 | pub type Key<K, V> = crate::dyn_map::Key<InFile<K>, V, AstPtrPolicy<K, V>>; | 15 | pub type Key<K, V> = crate::dyn_map::Key<InFile<K>, V, AstPtrPolicy<K, V>>; |
@@ -28,6 +28,7 @@ pub const VARIANT: Key<ast::Variant, EnumVariantId> = Key::new(); | |||
28 | pub const TUPLE_FIELD: Key<ast::TupleField, FieldId> = Key::new(); | 28 | pub const TUPLE_FIELD: Key<ast::TupleField, FieldId> = Key::new(); |
29 | pub const RECORD_FIELD: Key<ast::RecordField, FieldId> = Key::new(); | 29 | pub const RECORD_FIELD: Key<ast::RecordField, FieldId> = Key::new(); |
30 | pub const TYPE_PARAM: Key<ast::TypeParam, TypeParamId> = Key::new(); | 30 | pub const TYPE_PARAM: Key<ast::TypeParam, TypeParamId> = Key::new(); |
31 | pub const LIFETIME_PARAM: Key<ast::LifetimeParam, LifetimeParamId> = Key::new(); | ||
31 | 32 | ||
32 | pub const MACRO: Key<ast::MacroCall, MacroDefId> = Key::new(); | 33 | pub const MACRO: Key<ast::MacroCall, MacroDefId> = Key::new(); |
33 | 34 | ||