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 | |
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]>
-rw-r--r-- | crates/hir/src/code_model.rs | 8 | ||||
-rw-r--r-- | crates/hir/src/from_id.rs | 17 | ||||
-rw-r--r-- | crates/hir/src/has_source.rs | 14 | ||||
-rw-r--r-- | crates/hir/src/semantics.rs | 51 | ||||
-rw-r--r-- | crates/hir/src/semantics/source_to_def.rs | 21 | ||||
-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 |
8 files changed, 131 insertions, 39 deletions
diff --git a/crates/hir/src/code_model.rs b/crates/hir/src/code_model.rs index fcc42c6bb..42dc35b76 100644 --- a/crates/hir/src/code_model.rs +++ b/crates/hir/src/code_model.rs | |||
@@ -1250,6 +1250,14 @@ impl LifetimeParam { | |||
1250 | let params = db.generic_params(self.id.parent); | 1250 | let params = db.generic_params(self.id.parent); |
1251 | params.lifetimes[self.id.local_id].name.clone() | 1251 | params.lifetimes[self.id.local_id].name.clone() |
1252 | } | 1252 | } |
1253 | |||
1254 | pub fn module(self, db: &dyn HirDatabase) -> Module { | ||
1255 | self.id.parent.module(db.upcast()).into() | ||
1256 | } | ||
1257 | |||
1258 | pub fn parent(self, _db: &dyn HirDatabase) -> GenericDef { | ||
1259 | self.id.parent.into() | ||
1260 | } | ||
1253 | } | 1261 | } |
1254 | 1262 | ||
1255 | // FIXME: rename from `ImplDef` to `Impl` | 1263 | // FIXME: rename from `ImplDef` to `Impl` |
diff --git a/crates/hir/src/from_id.rs b/crates/hir/src/from_id.rs index 265ef6d1f..dd3fcfe4a 100644 --- a/crates/hir/src/from_id.rs +++ b/crates/hir/src/from_id.rs | |||
@@ -41,6 +41,7 @@ from_id![ | |||
41 | (hir_def::FunctionId, crate::Function), | 41 | (hir_def::FunctionId, crate::Function), |
42 | (hir_def::ImplId, crate::ImplDef), | 42 | (hir_def::ImplId, crate::ImplDef), |
43 | (hir_def::TypeParamId, crate::TypeParam), | 43 | (hir_def::TypeParamId, crate::TypeParam), |
44 | (hir_def::LifetimeParamId, crate::LifetimeParam), | ||
44 | (hir_expand::MacroDefId, crate::MacroDef) | 45 | (hir_expand::MacroDefId, crate::MacroDef) |
45 | ]; | 46 | ]; |
46 | 47 | ||
@@ -154,6 +155,22 @@ impl From<GenericDef> for GenericDefId { | |||
154 | } | 155 | } |
155 | } | 156 | } |
156 | 157 | ||
158 | impl From<GenericDefId> for GenericDef { | ||
159 | fn from(def: GenericDefId) -> Self { | ||
160 | match def { | ||
161 | GenericDefId::FunctionId(it) => GenericDef::Function(it.into()), | ||
162 | GenericDefId::AdtId(it) => GenericDef::Adt(it.into()), | ||
163 | GenericDefId::TraitId(it) => GenericDef::Trait(it.into()), | ||
164 | GenericDefId::TypeAliasId(it) => GenericDef::TypeAlias(it.into()), | ||
165 | GenericDefId::ImplId(it) => GenericDef::ImplDef(it.into()), | ||
166 | GenericDefId::EnumVariantId(it) => { | ||
167 | GenericDef::EnumVariant(EnumVariant { parent: it.parent.into(), id: it.local_id }) | ||
168 | } | ||
169 | GenericDefId::ConstId(it) => GenericDef::Const(it.into()), | ||
170 | } | ||
171 | } | ||
172 | } | ||
173 | |||
157 | impl From<Adt> for GenericDefId { | 174 | impl From<Adt> for GenericDefId { |
158 | fn from(id: Adt) -> Self { | 175 | fn from(id: Adt) -> Self { |
159 | match id { | 176 | match id { |
diff --git a/crates/hir/src/has_source.rs b/crates/hir/src/has_source.rs index c77494152..1e64a1614 100644 --- a/crates/hir/src/has_source.rs +++ b/crates/hir/src/has_source.rs | |||
@@ -10,8 +10,8 @@ use hir_expand::InFile; | |||
10 | use syntax::ast; | 10 | use syntax::ast; |
11 | 11 | ||
12 | use crate::{ | 12 | use crate::{ |
13 | db::HirDatabase, Const, Enum, EnumVariant, Field, FieldSource, Function, ImplDef, MacroDef, | 13 | db::HirDatabase, Const, Enum, EnumVariant, Field, FieldSource, Function, ImplDef, |
14 | Module, Static, Struct, Trait, TypeAlias, TypeParam, Union, | 14 | LifetimeParam, MacroDef, Module, Static, Struct, Trait, TypeAlias, TypeParam, Union, |
15 | }; | 15 | }; |
16 | 16 | ||
17 | pub trait HasSource { | 17 | pub trait HasSource { |
@@ -129,6 +129,14 @@ impl HasSource for TypeParam { | |||
129 | type Ast = Either<ast::Trait, ast::TypeParam>; | 129 | type Ast = Either<ast::Trait, ast::TypeParam>; |
130 | fn source(self, db: &dyn HirDatabase) -> InFile<Self::Ast> { | 130 | fn source(self, db: &dyn HirDatabase) -> InFile<Self::Ast> { |
131 | let child_source = self.id.parent.child_source(db.upcast()); | 131 | let child_source = self.id.parent.child_source(db.upcast()); |
132 | child_source.map(|it| it[self.id.local_id].clone()) | 132 | child_source.map(|it| it.type_params[self.id.local_id].clone()) |
133 | } | ||
134 | } | ||
135 | |||
136 | impl HasSource for LifetimeParam { | ||
137 | type Ast = ast::LifetimeParam; | ||
138 | fn source(self, db: &dyn HirDatabase) -> InFile<Self::Ast> { | ||
139 | let child_source = self.id.parent.child_source(db.upcast()); | ||
140 | child_source.map(|it| it.lifetime_params[self.id.local_id].clone()) | ||
133 | } | 141 | } |
134 | } | 142 | } |
diff --git a/crates/hir/src/semantics.rs b/crates/hir/src/semantics.rs index 4bd22ed27..e4fc21ced 100644 --- a/crates/hir/src/semantics.rs +++ b/crates/hir/src/semantics.rs | |||
@@ -13,7 +13,11 @@ use hir_expand::{hygiene::Hygiene, name::AsName, ExpansionInfo}; | |||
13 | use hir_ty::associated_type_shorthand_candidates; | 13 | use hir_ty::associated_type_shorthand_candidates; |
14 | use itertools::Itertools; | 14 | use itertools::Itertools; |
15 | use rustc_hash::{FxHashMap, FxHashSet}; | 15 | use rustc_hash::{FxHashMap, FxHashSet}; |
16 | use syntax::{algo::find_node_at_offset, ast, AstNode, SyntaxNode, SyntaxToken, TextSize}; | 16 | use syntax::{ |
17 | algo::find_node_at_offset, | ||
18 | ast::{self, GenericParamsOwner}, | ||
19 | match_ast, AstNode, SyntaxNode, SyntaxToken, TextSize, | ||
20 | }; | ||
17 | 21 | ||
18 | use crate::{ | 22 | use crate::{ |
19 | code_model::Access, | 23 | code_model::Access, |
@@ -21,8 +25,9 @@ use crate::{ | |||
21 | diagnostics::Diagnostic, | 25 | diagnostics::Diagnostic, |
22 | semantics::source_to_def::{ChildContainer, SourceToDefCache, SourceToDefCtx}, | 26 | semantics::source_to_def::{ChildContainer, SourceToDefCache, SourceToDefCtx}, |
23 | source_analyzer::{resolve_hir_path, SourceAnalyzer}, | 27 | source_analyzer::{resolve_hir_path, SourceAnalyzer}, |
24 | AssocItem, Callable, Crate, Field, Function, HirFileId, ImplDef, InFile, Local, MacroDef, | 28 | AssocItem, Callable, Crate, Field, Function, HirFileId, ImplDef, InFile, LifetimeParam, Local, |
25 | Module, ModuleDef, Name, Path, ScopeDef, Trait, Type, TypeAlias, TypeParam, VariantDef, | 29 | MacroDef, Module, ModuleDef, Name, Path, ScopeDef, Trait, Type, TypeAlias, TypeParam, |
30 | VariantDef, | ||
26 | }; | 31 | }; |
27 | 32 | ||
28 | #[derive(Debug, Clone, PartialEq, Eq)] | 33 | #[derive(Debug, Clone, PartialEq, Eq)] |
@@ -173,6 +178,11 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> { | |||
173 | self.imp.descend_node_at_offset(node, offset).find_map(N::cast) | 178 | self.imp.descend_node_at_offset(node, offset).find_map(N::cast) |
174 | } | 179 | } |
175 | 180 | ||
181 | // FIXME: Replace the SyntaxToken with a typed ast Node/Token | ||
182 | pub fn resolve_lifetime_param(&self, lifetime_token: &SyntaxToken) -> Option<LifetimeParam> { | ||
183 | self.imp.resolve_lifetime_param(lifetime_token) | ||
184 | } | ||
185 | |||
176 | pub fn type_of_expr(&self, expr: &ast::Expr) -> Option<Type> { | 186 | pub fn type_of_expr(&self, expr: &ast::Expr) -> Option<Type> { |
177 | self.imp.type_of_expr(expr) | 187 | self.imp.type_of_expr(expr) |
178 | } | 188 | } |
@@ -392,16 +402,44 @@ impl<'db> SemanticsImpl<'db> { | |||
392 | .kmerge_by(|node1, node2| node1.text_range().len() < node2.text_range().len()) | 402 | .kmerge_by(|node1, node2| node1.text_range().len() < node2.text_range().len()) |
393 | } | 403 | } |
394 | 404 | ||
405 | // FIXME: Replace the SyntaxToken with a typed ast Node/Token | ||
406 | fn resolve_lifetime_param(&self, lifetime_token: &SyntaxToken) -> Option<LifetimeParam> { | ||
407 | if lifetime_token.kind() != syntax::SyntaxKind::LIFETIME { | ||
408 | return None; | ||
409 | } | ||
410 | let lifetime_text = lifetime_token.text(); | ||
411 | let lifetime_param = lifetime_token.parent().ancestors().find_map(|syn| { | ||
412 | let gpl = match_ast! { | ||
413 | match syn { | ||
414 | ast::Fn(it) => it.generic_param_list()?, | ||
415 | ast::TypeAlias(it) => it.generic_param_list()?, | ||
416 | ast::Struct(it) => it.generic_param_list()?, | ||
417 | ast::Enum(it) => it.generic_param_list()?, | ||
418 | ast::Union(it) => it.generic_param_list()?, | ||
419 | ast::Trait(it) => it.generic_param_list()?, | ||
420 | ast::Impl(it) => it.generic_param_list()?, | ||
421 | ast::WherePred(it) => it.generic_param_list()?, | ||
422 | ast::ForType(it) => it.generic_param_list()?, | ||
423 | _ => return None, | ||
424 | } | ||
425 | }; | ||
426 | gpl.lifetime_params() | ||
427 | .find(|tp| tp.lifetime_token().as_ref().map(|lt| lt.text()) == Some(lifetime_text)) | ||
428 | })?; | ||
429 | let src = self.find_file(lifetime_param.syntax().clone()).with_value(lifetime_param); | ||
430 | ToDef::to_def(self, src) | ||
431 | } | ||
432 | |||
395 | fn type_of_expr(&self, expr: &ast::Expr) -> Option<Type> { | 433 | fn type_of_expr(&self, expr: &ast::Expr) -> Option<Type> { |
396 | self.analyze(expr.syntax()).type_of_expr(self.db, &expr) | 434 | self.analyze(expr.syntax()).type_of_expr(self.db, expr) |
397 | } | 435 | } |
398 | 436 | ||
399 | fn type_of_pat(&self, pat: &ast::Pat) -> Option<Type> { | 437 | fn type_of_pat(&self, pat: &ast::Pat) -> Option<Type> { |
400 | self.analyze(pat.syntax()).type_of_pat(self.db, &pat) | 438 | self.analyze(pat.syntax()).type_of_pat(self.db, pat) |
401 | } | 439 | } |
402 | 440 | ||
403 | fn type_of_self(&self, param: &ast::SelfParam) -> Option<Type> { | 441 | fn type_of_self(&self, param: &ast::SelfParam) -> Option<Type> { |
404 | self.analyze(param.syntax()).type_of_self(self.db, ¶m) | 442 | self.analyze(param.syntax()).type_of_self(self.db, param) |
405 | } | 443 | } |
406 | 444 | ||
407 | fn resolve_method_call(&self, call: &ast::MethodCallExpr) -> Option<FunctionId> { | 445 | fn resolve_method_call(&self, call: &ast::MethodCallExpr) -> Option<FunctionId> { |
@@ -684,6 +722,7 @@ to_def_impls![ | |||
684 | (crate::Field, ast::TupleField, tuple_field_to_def), | 722 | (crate::Field, ast::TupleField, tuple_field_to_def), |
685 | (crate::EnumVariant, ast::Variant, enum_variant_to_def), | 723 | (crate::EnumVariant, ast::Variant, enum_variant_to_def), |
686 | (crate::TypeParam, ast::TypeParam, type_param_to_def), | 724 | (crate::TypeParam, ast::TypeParam, type_param_to_def), |
725 | (crate::LifetimeParam, ast::LifetimeParam, lifetime_param_to_def), | ||
687 | (crate::MacroDef, ast::MacroCall, macro_call_to_def), // this one is dubious, not all calls are macros | 726 | (crate::MacroDef, ast::MacroCall, macro_call_to_def), // this one is dubious, not all calls are macros |
688 | (crate::Local, ast::IdentPat, bind_pat_to_def), | 727 | (crate::Local, ast::IdentPat, bind_pat_to_def), |
689 | ]; | 728 | ]; |
diff --git a/crates/hir/src/semantics/source_to_def.rs b/crates/hir/src/semantics/source_to_def.rs index 66fc11611..badcf0ae8 100644 --- a/crates/hir/src/semantics/source_to_def.rs +++ b/crates/hir/src/semantics/source_to_def.rs | |||
@@ -7,7 +7,8 @@ use hir_def::{ | |||
7 | expr::PatId, | 7 | expr::PatId, |
8 | keys::{self, Key}, | 8 | keys::{self, Key}, |
9 | ConstId, DefWithBodyId, EnumId, EnumVariantId, FieldId, FunctionId, GenericDefId, ImplId, | 9 | ConstId, DefWithBodyId, EnumId, EnumVariantId, FieldId, FunctionId, GenericDefId, ImplId, |
10 | ModuleId, StaticId, StructId, TraitId, TypeAliasId, TypeParamId, UnionId, VariantId, | 10 | LifetimeParamId, ModuleId, StaticId, StructId, TraitId, TypeAliasId, TypeParamId, UnionId, |
11 | VariantId, | ||
11 | }; | 12 | }; |
12 | use hir_expand::{name::AsName, AstId, MacroDefKind}; | 13 | use hir_expand::{name::AsName, AstId, MacroDefKind}; |
13 | use rustc_hash::FxHashMap; | 14 | use rustc_hash::FxHashMap; |
@@ -128,13 +129,25 @@ impl SourceToDefCtx<'_, '_> { | |||
128 | 129 | ||
129 | pub(super) fn type_param_to_def(&mut self, src: InFile<ast::TypeParam>) -> Option<TypeParamId> { | 130 | pub(super) fn type_param_to_def(&mut self, src: InFile<ast::TypeParam>) -> Option<TypeParamId> { |
130 | let container: ChildContainer = | 131 | let container: ChildContainer = |
131 | self.find_type_param_container(src.as_ref().map(|it| it.syntax()))?.into(); | 132 | self.find_generic_param_container(src.as_ref().map(|it| it.syntax()))?.into(); |
132 | let db = self.db; | 133 | let db = self.db; |
133 | let dyn_map = | 134 | let dyn_map = |
134 | &*self.cache.entry(container).or_insert_with(|| container.child_by_source(db)); | 135 | &*self.cache.entry(container).or_insert_with(|| container.child_by_source(db)); |
135 | dyn_map[keys::TYPE_PARAM].get(&src).copied() | 136 | dyn_map[keys::TYPE_PARAM].get(&src).copied() |
136 | } | 137 | } |
137 | 138 | ||
139 | pub(super) fn lifetime_param_to_def( | ||
140 | &mut self, | ||
141 | src: InFile<ast::LifetimeParam>, | ||
142 | ) -> Option<LifetimeParamId> { | ||
143 | let container: ChildContainer = | ||
144 | self.find_generic_param_container(src.as_ref().map(|it| it.syntax()))?.into(); | ||
145 | let db = self.db; | ||
146 | let dyn_map = | ||
147 | &*self.cache.entry(container).or_insert_with(|| container.child_by_source(db)); | ||
148 | dyn_map[keys::LIFETIME_PARAM].get(&src).copied() | ||
149 | } | ||
150 | |||
138 | // FIXME: use DynMap as well? | 151 | // FIXME: use DynMap as well? |
139 | pub(super) fn macro_call_to_def(&mut self, src: InFile<ast::MacroCall>) -> Option<MacroDefId> { | 152 | pub(super) fn macro_call_to_def(&mut self, src: InFile<ast::MacroCall>) -> Option<MacroDefId> { |
140 | let kind = MacroDefKind::Declarative; | 153 | let kind = MacroDefKind::Declarative; |
@@ -203,7 +216,7 @@ impl SourceToDefCtx<'_, '_> { | |||
203 | Some(def.into()) | 216 | Some(def.into()) |
204 | } | 217 | } |
205 | 218 | ||
206 | fn find_type_param_container(&mut self, src: InFile<&SyntaxNode>) -> Option<GenericDefId> { | 219 | fn find_generic_param_container(&mut self, src: InFile<&SyntaxNode>) -> Option<GenericDefId> { |
207 | for container in src.cloned().ancestors_with_macros(self.db.upcast()).skip(1) { | 220 | for container in src.cloned().ancestors_with_macros(self.db.upcast()).skip(1) { |
208 | let res: GenericDefId = match_ast! { | 221 | let res: GenericDefId = match_ast! { |
209 | match (container.value) { | 222 | match (container.value) { |
@@ -247,7 +260,7 @@ pub(crate) enum ChildContainer { | |||
247 | VariantId(VariantId), | 260 | VariantId(VariantId), |
248 | TypeAliasId(TypeAliasId), | 261 | TypeAliasId(TypeAliasId), |
249 | /// XXX: this might be the same def as, for example an `EnumId`. However, | 262 | /// XXX: this might be the same def as, for example an `EnumId`. However, |
250 | /// here the children generic parameters, and not, eg enum variants. | 263 | /// here the children are generic parameters, and not, eg enum variants. |
251 | GenericDefId(GenericDefId), | 264 | GenericDefId(GenericDefId), |
252 | } | 265 | } |
253 | impl_from! { | 266 | impl_from! { |
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 | ||