Unnamed repository; edit this file 'description' to name the repository.
-rw-r--r--crates/hir-def/src/child_by_source.rs74
-rw-r--r--crates/hir-def/src/data/adt.rs48
-rw-r--r--crates/hir-def/src/generics.rs139
-rw-r--r--crates/hir-def/src/lib.rs35
-rw-r--r--crates/hir-def/src/resolver.rs40
-rw-r--r--crates/hir-def/src/src.rs109
-rw-r--r--crates/hir-def/src/trace.rs2
7 files changed, 229 insertions, 218 deletions
diff --git a/crates/hir-def/src/child_by_source.rs b/crates/hir-def/src/child_by_source.rs
index 5efa3e8d9e..ba7d06272a 100644
--- a/crates/hir-def/src/child_by_source.rs
+++ b/crates/hir-def/src/child_by_source.rs
@@ -6,6 +6,7 @@
use either::Either;
use hir_expand::{attrs::collect_attrs, HirFileId};
+use syntax::ast;
use crate::{
db::DefDatabase,
@@ -17,8 +18,9 @@ use crate::{
item_tree::ItemTreeNode,
nameres::DefMap,
src::{HasChildSource, HasSource},
- AdtId, AssocItemId, DefWithBodyId, EnumId, FieldId, ImplId, ItemTreeLoc, Lookup, MacroId,
- ModuleDefId, ModuleId, TraitId, VariantId,
+ AdtId, AssocItemId, DefWithBodyId, EnumId, FieldId, GenericDefId, ImplId, ItemTreeLoc,
+ LifetimeParamId, Lookup, MacroId, ModuleDefId, ModuleId, TraitId, TypeOrConstParamId,
+ VariantId,
};
pub trait ChildBySource {
@@ -59,14 +61,6 @@ impl ChildBySource for ImplId {
}
}
-fn add_assoc_item(db: &dyn DefDatabase, res: &mut DynMap, file_id: HirFileId, item: AssocItemId) {
- match item {
- AssocItemId::FunctionId(func) => insert_item_loc(db, res, file_id, func, keys::FUNCTION),
- AssocItemId::ConstId(konst) => insert_item_loc(db, res, file_id, konst, keys::CONST),
- AssocItemId::TypeAliasId(ty) => insert_item_loc(db, res, file_id, ty, keys::TYPE_ALIAS),
- }
-}
-
impl ChildBySource for ModuleId {
fn child_by_source_to(&self, db: &dyn DefDatabase, res: &mut DynMap, file_id: HirFileId) {
let def_map = self.def_map(db);
@@ -118,14 +112,6 @@ impl ChildBySource for ItemScope {
file_id: HirFileId,
item: ModuleDefId,
) {
- macro_rules! insert {
- ($map:ident[$key:path].$insert:ident($id:ident)) => {{
- let loc = $id.lookup(db);
- if loc.id.file_id() == file_id {
- $map[$key].$insert(loc.source(db).value, $id)
- }
- }};
- }
match item {
ModuleDefId::FunctionId(id) => {
insert_item_loc(db, map, file_id, id, keys::FUNCTION)
@@ -145,9 +131,13 @@ impl ChildBySource for ItemScope {
AdtId::EnumId(id) => insert_item_loc(db, map, file_id, id, keys::ENUM),
},
ModuleDefId::MacroId(id) => match id {
- MacroId::Macro2Id(id) => insert!(map[keys::MACRO2].insert(id)),
- MacroId::MacroRulesId(id) => insert!(map[keys::MACRO_RULES].insert(id)),
- MacroId::ProcMacroId(id) => insert!(map[keys::PROC_MACRO].insert(id)),
+ MacroId::Macro2Id(id) => insert_item_loc(db, map, file_id, id, keys::MACRO2),
+ MacroId::MacroRulesId(id) => {
+ insert_item_loc(db, map, file_id, id, keys::MACRO_RULES)
+ }
+ MacroId::ProcMacroId(id) => {
+ insert_item_loc(db, map, file_id, id, keys::PROC_MACRO)
+ }
},
ModuleDefId::ModuleId(_)
| ModuleDefId::EnumVariantId(_)
@@ -207,6 +197,40 @@ impl ChildBySource for DefWithBodyId {
}
}
+impl ChildBySource for GenericDefId {
+ fn child_by_source_to(&self, db: &dyn DefDatabase, res: &mut DynMap, file_id: HirFileId) {
+ let (gfile_id, generic_params_list) = self.file_id_and_params_of(db);
+ if gfile_id != file_id {
+ return;
+ }
+
+ let generic_params = db.generic_params(*self);
+ let mut toc_idx_iter = generic_params.type_or_consts.iter().map(|(idx, _)| idx);
+ let lts_idx_iter = generic_params.lifetimes.iter().map(|(idx, _)| idx);
+
+ // For traits the first type index is `Self`, skip it.
+ if let GenericDefId::TraitId(_) = *self {
+ toc_idx_iter.next().unwrap(); // advance_by(1);
+ }
+
+ if let Some(generic_params_list) = generic_params_list {
+ for (local_id, ast_param) in
+ toc_idx_iter.zip(generic_params_list.type_or_const_params())
+ {
+ let id = TypeOrConstParamId { parent: *self, local_id };
+ match ast_param {
+ ast::TypeOrConstParam::Type(a) => res[keys::TYPE_PARAM].insert(a, id),
+ ast::TypeOrConstParam::Const(a) => res[keys::CONST_PARAM].insert(a, id),
+ }
+ }
+ for (local_id, ast_param) in lts_idx_iter.zip(generic_params_list.lifetime_params()) {
+ let id = LifetimeParamId { parent: *self, local_id };
+ res[keys::LIFETIME_PARAM].insert(ast_param, id);
+ }
+ }
+ }
+}
+
fn insert_item_loc<ID, N, Data>(
db: &dyn DefDatabase,
res: &mut DynMap,
@@ -224,3 +248,11 @@ fn insert_item_loc<ID, N, Data>(
res[key].insert(loc.source(db).value, id)
}
}
+
+fn add_assoc_item(db: &dyn DefDatabase, res: &mut DynMap, file_id: HirFileId, item: AssocItemId) {
+ match item {
+ AssocItemId::FunctionId(func) => insert_item_loc(db, res, file_id, func, keys::FUNCTION),
+ AssocItemId::ConstId(konst) => insert_item_loc(db, res, file_id, konst, keys::CONST),
+ AssocItemId::TypeAliasId(ty) => insert_item_loc(db, res, file_id, ty, keys::TYPE_ALIAS),
+ }
+}
diff --git a/crates/hir-def/src/data/adt.rs b/crates/hir-def/src/data/adt.rs
index 5986b7df3d..540f643ae7 100644
--- a/crates/hir-def/src/data/adt.rs
+++ b/crates/hir-def/src/data/adt.rs
@@ -10,7 +10,7 @@ use hir_expand::{
HirFileId, InFile,
};
use intern::Interned;
-use la_arena::{Arena, ArenaMap};
+use la_arena::Arena;
use rustc_abi::{Align, Integer, IntegerType, ReprFlags, ReprOptions};
use syntax::ast::{self, HasName, HasVisibility};
use triomphe::Arc;
@@ -22,13 +22,11 @@ use crate::{
lang_item::LangItem,
lower::LowerCtx,
nameres::diagnostics::{DefDiagnostic, DefDiagnostics},
- src::HasChildSource,
- src::HasSource,
trace::Trace,
tt::{Delimiter, DelimiterKind, Leaf, Subtree, TokenTree},
type_ref::TypeRef,
visibility::RawVisibility,
- EnumId, EnumVariantId, LocalFieldId, LocalModuleId, Lookup, StructId, UnionId, VariantId,
+ EnumId, EnumVariantId, LocalFieldId, LocalModuleId, Lookup, StructId, UnionId,
};
/// Note that we use `StructData` for unions as well!
@@ -387,46 +385,6 @@ impl VariantData {
}
}
-impl HasChildSource<LocalFieldId> for VariantId {
- type Value = Either<ast::TupleField, ast::RecordField>;
-
- fn child_source(&self, db: &dyn DefDatabase) -> InFile<ArenaMap<LocalFieldId, Self::Value>> {
- let item_tree;
- let (src, fields, container) = match *self {
- VariantId::EnumVariantId(it) => {
- let lookup = it.lookup(db);
- item_tree = lookup.id.item_tree(db);
- (
- lookup.source(db).map(|it| it.kind()),
- &item_tree[lookup.id.value].fields,
- lookup.parent.lookup(db).container,
- )
- }
- VariantId::StructId(it) => {
- let lookup = it.lookup(db);
- item_tree = lookup.id.item_tree(db);
- (
- lookup.source(db).map(|it| it.kind()),
- &item_tree[lookup.id.value].fields,
- lookup.container,
- )
- }
- VariantId::UnionId(it) => {
- let lookup = it.lookup(db);
- item_tree = lookup.id.item_tree(db);
- (
- lookup.source(db).map(|it| it.kind()),
- &item_tree[lookup.id.value].fields,
- lookup.container,
- )
- }
- };
- let mut trace = Trace::new_for_map();
- lower_struct(db, &mut trace, &src, container.krate, &item_tree, fields);
- src.with_value(trace.into_map())
- }
-}
-
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum StructKind {
Tuple,
@@ -434,7 +392,7 @@ pub enum StructKind {
Unit,
}
-fn lower_struct(
+pub(crate) fn lower_struct(
db: &dyn DefDatabase,
trace: &mut Trace<FieldData, Either<ast::TupleField, ast::RecordField>>,
ast: &InFile<ast::StructKind>,
diff --git a/crates/hir-def/src/generics.rs b/crates/hir-def/src/generics.rs
index 0edd5e6168..a4115d818c 100644
--- a/crates/hir-def/src/generics.rs
+++ b/crates/hir-def/src/generics.rs
@@ -3,31 +3,27 @@
//! generic parameters. See also the `Generics` type and the `generics_of` query
//! in rustc.
-use base_db::FileId;
use either::Either;
use hir_expand::{
name::{AsName, Name},
- ExpandResult, HirFileId, InFile,
+ ExpandResult,
};
use intern::Interned;
-use la_arena::{Arena, ArenaMap, Idx};
+use la_arena::{Arena, Idx};
use once_cell::unsync::Lazy;
use stdx::impl_from;
use syntax::ast::{self, HasGenericParams, HasName, HasTypeBounds};
use triomphe::Arc;
use crate::{
- child_by_source::ChildBySource,
db::DefDatabase,
- dyn_map::{keys, DynMap},
expander::Expander,
item_tree::ItemTree,
lower::LowerCtx,
nameres::{DefMap, MacroSubNs},
- src::{HasChildSource, HasSource},
type_ref::{ConstRef, LifetimeRef, TypeBound, TypeRef},
- AdtId, ConstParamId, GenericDefId, HasModule, LifetimeParamId, LocalLifetimeParamId,
- LocalTypeOrConstParamId, Lookup, TypeOrConstParamId, TypeParamId,
+ AdtId, ConstParamId, GenericDefId, HasModule, LocalTypeOrConstParamId, Lookup,
+ TypeOrConstParamId, TypeParamId,
};
/// Data about a generic type parameter (to a function, struct, impl, ...).
@@ -507,130 +503,3 @@ impl GenericParams {
})
}
}
-
-fn file_id_and_params_of(
- db: &dyn DefDatabase,
- def: GenericDefId,
-) -> (HirFileId, Option<ast::GenericParamList>) {
- match def {
- GenericDefId::FunctionId(it) => file_id_and_params_of_item_loc(db, it),
- GenericDefId::TypeAliasId(it) => file_id_and_params_of_item_loc(db, it),
- GenericDefId::ConstId(_) => (FileId::BOGUS.into(), None),
- GenericDefId::AdtId(AdtId::StructId(it)) => file_id_and_params_of_item_loc(db, it),
- GenericDefId::AdtId(AdtId::UnionId(it)) => file_id_and_params_of_item_loc(db, it),
- GenericDefId::AdtId(AdtId::EnumId(it)) => file_id_and_params_of_item_loc(db, it),
- GenericDefId::TraitId(it) => file_id_and_params_of_item_loc(db, it),
- GenericDefId::TraitAliasId(it) => file_id_and_params_of_item_loc(db, it),
- GenericDefId::ImplId(it) => file_id_and_params_of_item_loc(db, it),
- // We won't be using this ID anyway
- GenericDefId::EnumVariantId(_) => (FileId::BOGUS.into(), None),
- }
-}
-
-fn file_id_and_params_of_item_loc<Loc>(
- db: &dyn DefDatabase,
- def: impl for<'db> Lookup<Database<'db> = dyn DefDatabase + 'db, Data = Loc>,
-) -> (HirFileId, Option<ast::GenericParamList>)
-where
- Loc: HasSource,
- Loc::Value: HasGenericParams,
-{
- let src = def.lookup(db).source(db);
- (src.file_id, src.value.generic_param_list())
-}
-
-impl HasChildSource<LocalTypeOrConstParamId> for GenericDefId {
- type Value = Either<ast::TypeOrConstParam, ast::TraitOrAlias>;
- fn child_source(
- &self,
- db: &dyn DefDatabase,
- ) -> InFile<ArenaMap<LocalTypeOrConstParamId, Self::Value>> {
- let generic_params = db.generic_params(*self);
- let mut idx_iter = generic_params.type_or_consts.iter().map(|(idx, _)| idx);
-
- let (file_id, generic_params_list) = file_id_and_params_of(db, *self);
-
- let mut params = ArenaMap::default();
-
- // For traits and trait aliases the first type index is `Self`, we need to add it before
- // the other params.
- match *self {
- GenericDefId::TraitId(id) => {
- let trait_ref = id.lookup(db).source(db).value;
- let idx = idx_iter.next().unwrap();
- params.insert(idx, Either::Right(ast::TraitOrAlias::Trait(trait_ref)));
- }
- GenericDefId::TraitAliasId(id) => {
- let alias = id.lookup(db).source(db).value;
- let idx = idx_iter.next().unwrap();
- params.insert(idx, Either::Right(ast::TraitOrAlias::TraitAlias(alias)));
- }
- _ => {}
- }
-
- if let Some(generic_params_list) = generic_params_list {
- for (idx, ast_param) in idx_iter.zip(generic_params_list.type_or_const_params()) {
- params.insert(idx, Either::Left(ast_param));
- }
- }
-
- InFile::new(file_id, params)
- }
-}
-
-impl HasChildSource<LocalLifetimeParamId> for GenericDefId {
- type Value = ast::LifetimeParam;
- fn child_source(
- &self,
- db: &dyn DefDatabase,
- ) -> InFile<ArenaMap<LocalLifetimeParamId, Self::Value>> {
- let generic_params = db.generic_params(*self);
- let idx_iter = generic_params.lifetimes.iter().map(|(idx, _)| idx);
-
- let (file_id, generic_params_list) = file_id_and_params_of(db, *self);
-
- let mut params = ArenaMap::default();
-
- if let Some(generic_params_list) = generic_params_list {
- for (idx, ast_param) in idx_iter.zip(generic_params_list.lifetime_params()) {
- params.insert(idx, ast_param);
- }
- }
-
- InFile::new(file_id, params)
- }
-}
-
-impl ChildBySource for GenericDefId {
- fn child_by_source_to(&self, db: &dyn DefDatabase, res: &mut DynMap, file_id: HirFileId) {
- let (gfile_id, generic_params_list) = file_id_and_params_of(db, *self);
- if gfile_id != file_id {
- return;
- }
-
- let generic_params = db.generic_params(*self);
- let mut toc_idx_iter = generic_params.type_or_consts.iter().map(|(idx, _)| idx);
- let lts_idx_iter = generic_params.lifetimes.iter().map(|(idx, _)| idx);
-
- // For traits the first type index is `Self`, skip it.
- if let GenericDefId::TraitId(_) = *self {
- toc_idx_iter.next().unwrap(); // advance_by(1);
- }
-
- if let Some(generic_params_list) = generic_params_list {
- for (local_id, ast_param) in
- toc_idx_iter.zip(generic_params_list.type_or_const_params())
- {
- let id = TypeOrConstParamId { parent: *self, local_id };
- match ast_param {
- ast::TypeOrConstParam::Type(a) => res[keys::TYPE_PARAM].insert(a, id),
- ast::TypeOrConstParam::Const(a) => res[keys::CONST_PARAM].insert(a, id),
- }
- }
- for (local_id, ast_param) in lts_idx_iter.zip(generic_params_list.lifetime_params()) {
- let id = LifetimeParamId { parent: *self, local_id };
- res[keys::LIFETIME_PARAM].insert(ast_param, id);
- }
- }
- }
-}
diff --git a/crates/hir-def/src/lib.rs b/crates/hir-def/src/lib.rs
index df1f61ae5f..c3564ca480 100644
--- a/crates/hir-def/src/lib.rs
+++ b/crates/hir-def/src/lib.rs
@@ -87,7 +87,7 @@ use hir_expand::{
use item_tree::ExternBlock;
use la_arena::Idx;
use nameres::DefMap;
-use span::Span;
+use span::{FileId, Span};
use stdx::impl_from;
use syntax::{ast, AstNode};
@@ -892,6 +892,39 @@ impl_from!(
for GenericDefId
);
+impl GenericDefId {
+ fn file_id_and_params_of(
+ self,
+ db: &dyn DefDatabase,
+ ) -> (HirFileId, Option<ast::GenericParamList>) {
+ fn file_id_and_params_of_item_loc<Loc>(
+ db: &dyn DefDatabase,
+ def: impl for<'db> Lookup<Database<'db> = dyn DefDatabase + 'db, Data = Loc>,
+ ) -> (HirFileId, Option<ast::GenericParamList>)
+ where
+ Loc: src::HasSource,
+ Loc::Value: ast::HasGenericParams,
+ {
+ let src = def.lookup(db).source(db);
+ (src.file_id, ast::HasGenericParams::generic_param_list(&src.value))
+ }
+
+ match self {
+ GenericDefId::FunctionId(it) => file_id_and_params_of_item_loc(db, it),
+ GenericDefId::TypeAliasId(it) => file_id_and_params_of_item_loc(db, it),
+ GenericDefId::ConstId(_) => (FileId::BOGUS.into(), None),
+ GenericDefId::AdtId(AdtId::StructId(it)) => file_id_and_params_of_item_loc(db, it),
+ GenericDefId::AdtId(AdtId::UnionId(it)) => file_id_and_params_of_item_loc(db, it),
+ GenericDefId::AdtId(AdtId::EnumId(it)) => file_id_and_params_of_item_loc(db, it),
+ GenericDefId::TraitId(it) => file_id_and_params_of_item_loc(db, it),
+ GenericDefId::TraitAliasId(it) => file_id_and_params_of_item_loc(db, it),
+ GenericDefId::ImplId(it) => file_id_and_params_of_item_loc(db, it),
+ // We won't be using this ID anyway
+ GenericDefId::EnumVariantId(_) => (FileId::BOGUS.into(), None),
+ }
+ }
+}
+
impl From<AssocItemId> for GenericDefId {
fn from(item: AssocItemId) -> Self {
match item {
diff --git a/crates/hir-def/src/resolver.rs b/crates/hir-def/src/resolver.rs
index 7a9c4ea016..2c9ffbe9b9 100644
--- a/crates/hir-def/src/resolver.rs
+++ b/crates/hir-def/src/resolver.rs
@@ -27,9 +27,9 @@ use crate::{
visibility::{RawVisibility, Visibility},
AdtId, ConstId, ConstParamId, CrateRootModuleId, DefWithBodyId, EnumId, EnumVariantId,
ExternBlockId, ExternCrateId, FunctionId, GenericDefId, GenericParamId, HasModule, ImplId,
- ItemContainerId, LifetimeParamId, LocalModuleId, Lookup, Macro2Id, MacroId, MacroRulesId,
- ModuleDefId, ModuleId, ProcMacroId, StaticId, StructId, TraitAliasId, TraitId, TypeAliasId,
- TypeOrConstParamId, TypeOwnerId, TypeParamId, UseId, VariantId,
+ ItemContainerId, ItemTreeLoc, LifetimeParamId, LocalModuleId, Lookup, Macro2Id, MacroId,
+ MacroRulesId, ModuleDefId, ModuleId, ProcMacroId, StaticId, StructId, TraitAliasId, TraitId,
+ TypeAliasId, TypeOrConstParamId, TypeOwnerId, TypeParamId, UseId, VariantId,
};
#[derive(Debug, Clone)]
@@ -1014,13 +1014,13 @@ impl HasResolver for CrateRootModuleId {
impl HasResolver for TraitId {
fn resolver(self, db: &dyn DefDatabase) -> Resolver {
- self.lookup(db).container.resolver(db).push_generic_params_scope(db, self.into())
+ lookup_resolver(db, self).push_generic_params_scope(db, self.into())
}
}
impl HasResolver for TraitAliasId {
fn resolver(self, db: &dyn DefDatabase) -> Resolver {
- self.lookup(db).container.resolver(db).push_generic_params_scope(db, self.into())
+ lookup_resolver(db, self).push_generic_params_scope(db, self.into())
}
}
@@ -1036,25 +1036,25 @@ impl<T: Into<AdtId> + Copy> HasResolver for T {
impl HasResolver for FunctionId {
fn resolver(self, db: &dyn DefDatabase) -> Resolver {
- self.lookup(db).container.resolver(db).push_generic_params_scope(db, self.into())
+ lookup_resolver(db, self).push_generic_params_scope(db, self.into())
}
}
impl HasResolver for ConstId {
fn resolver(self, db: &dyn DefDatabase) -> Resolver {
- self.lookup(db).container.resolver(db)
+ lookup_resolver(db, self)
}
}
impl HasResolver for StaticId {
fn resolver(self, db: &dyn DefDatabase) -> Resolver {
- self.lookup(db).container.resolver(db)
+ lookup_resolver(db, self)
}
}
impl HasResolver for TypeAliasId {
fn resolver(self, db: &dyn DefDatabase) -> Resolver {
- self.lookup(db).container.resolver(db).push_generic_params_scope(db, self.into())
+ lookup_resolver(db, self).push_generic_params_scope(db, self.into())
}
}
@@ -1071,19 +1071,19 @@ impl HasResolver for ImplId {
impl HasResolver for ExternBlockId {
fn resolver(self, db: &dyn DefDatabase) -> Resolver {
// Same as parent's
- self.lookup(db).container.resolver(db)
+ lookup_resolver(db, self)
}
}
impl HasResolver for ExternCrateId {
fn resolver(self, db: &dyn DefDatabase) -> Resolver {
- self.lookup(db).container.resolver(db)
+ lookup_resolver(db, self)
}
}
impl HasResolver for UseId {
fn resolver(self, db: &dyn DefDatabase) -> Resolver {
- self.lookup(db).container.resolver(db)
+ lookup_resolver(db, self)
}
}
@@ -1170,18 +1170,28 @@ impl HasResolver for MacroId {
impl HasResolver for Macro2Id {
fn resolver(self, db: &dyn DefDatabase) -> Resolver {
- self.lookup(db).container.resolver(db)
+ lookup_resolver(db, self)
}
}
impl HasResolver for ProcMacroId {
fn resolver(self, db: &dyn DefDatabase) -> Resolver {
- self.lookup(db).container.resolver(db)
+ lookup_resolver(db, self)
}
}
impl HasResolver for MacroRulesId {
fn resolver(self, db: &dyn DefDatabase) -> Resolver {
- self.lookup(db).container.resolver(db)
+ lookup_resolver(db, self)
}
}
+
+fn lookup_resolver<'db>(
+ db: &(dyn DefDatabase + 'db),
+ lookup: impl Lookup<
+ Database<'db> = dyn DefDatabase + 'db,
+ Data = impl ItemTreeLoc<Container = impl HasResolver>,
+ >,
+) -> Resolver {
+ lookup.lookup(db).container().resolver(db)
+}
diff --git a/crates/hir-def/src/src.rs b/crates/hir-def/src/src.rs
index d820456b92..4283f003f8 100644
--- a/crates/hir-def/src/src.rs
+++ b/crates/hir-def/src/src.rs
@@ -1,10 +1,15 @@
//! Utilities for mapping between hir IDs and the surface syntax.
+use either::Either;
use hir_expand::InFile;
use la_arena::ArenaMap;
use syntax::ast;
-use crate::{db::DefDatabase, item_tree::ItemTreeNode, ItemTreeLoc, Lookup, UseId};
+use crate::{
+ data::adt::lower_struct, db::DefDatabase, item_tree::ItemTreeNode, trace::Trace, GenericDefId,
+ ItemTreeLoc, LocalFieldId, LocalLifetimeParamId, LocalTypeOrConstParamId, Lookup, UseId,
+ VariantId,
+};
pub trait HasSource {
type Value;
@@ -49,3 +54,105 @@ impl HasChildSource<la_arena::Idx<ast::UseTree>> for UseId {
)
}
}
+
+impl HasChildSource<LocalTypeOrConstParamId> for GenericDefId {
+ type Value = Either<ast::TypeOrConstParam, ast::TraitOrAlias>;
+ fn child_source(
+ &self,
+ db: &dyn DefDatabase,
+ ) -> InFile<ArenaMap<LocalTypeOrConstParamId, Self::Value>> {
+ let generic_params = db.generic_params(*self);
+ let mut idx_iter = generic_params.type_or_consts.iter().map(|(idx, _)| idx);
+
+ let (file_id, generic_params_list) = self.file_id_and_params_of(db);
+
+ let mut params = ArenaMap::default();
+
+ // For traits and trait aliases the first type index is `Self`, we need to add it before
+ // the other params.
+ match *self {
+ GenericDefId::TraitId(id) => {
+ let trait_ref = id.lookup(db).source(db).value;
+ let idx = idx_iter.next().unwrap();
+ params.insert(idx, Either::Right(ast::TraitOrAlias::Trait(trait_ref)));
+ }
+ GenericDefId::TraitAliasId(id) => {
+ let alias = id.lookup(db).source(db).value;
+ let idx = idx_iter.next().unwrap();
+ params.insert(idx, Either::Right(ast::TraitOrAlias::TraitAlias(alias)));
+ }
+ _ => {}
+ }
+
+ if let Some(generic_params_list) = generic_params_list {
+ for (idx, ast_param) in idx_iter.zip(generic_params_list.type_or_const_params()) {
+ params.insert(idx, Either::Left(ast_param));
+ }
+ }
+
+ InFile::new(file_id, params)
+ }
+}
+
+impl HasChildSource<LocalLifetimeParamId> for GenericDefId {
+ type Value = ast::LifetimeParam;
+ fn child_source(
+ &self,
+ db: &dyn DefDatabase,
+ ) -> InFile<ArenaMap<LocalLifetimeParamId, Self::Value>> {
+ let generic_params = db.generic_params(*self);
+ let idx_iter = generic_params.lifetimes.iter().map(|(idx, _)| idx);
+
+ let (file_id, generic_params_list) = self.file_id_and_params_of(db);
+
+ let mut params = ArenaMap::default();
+
+ if let Some(generic_params_list) = generic_params_list {
+ for (idx, ast_param) in idx_iter.zip(generic_params_list.lifetime_params()) {
+ params.insert(idx, ast_param);
+ }
+ }
+
+ InFile::new(file_id, params)
+ }
+}
+
+impl HasChildSource<LocalFieldId> for VariantId {
+ type Value = Either<ast::TupleField, ast::RecordField>;
+
+ fn child_source(&self, db: &dyn DefDatabase) -> InFile<ArenaMap<LocalFieldId, Self::Value>> {
+ let item_tree;
+ let (src, fields, container) = match *self {
+ VariantId::EnumVariantId(it) => {
+ let lookup = it.lookup(db);
+ item_tree = lookup.id.item_tree(db);
+ (
+ lookup.source(db).map(|it| it.kind()),
+ &item_tree[lookup.id.value].fields,
+ lookup.parent.lookup(db).container,
+ )
+ }
+ VariantId::StructId(it) => {
+ let lookup = it.lookup(db);
+ item_tree = lookup.id.item_tree(db);
+ (
+ lookup.source(db).map(|it| it.kind()),
+ &item_tree[lookup.id.value].fields,
+ lookup.container,
+ )
+ }
+ VariantId::UnionId(it) => {
+ let lookup = it.lookup(db);
+ item_tree = lookup.id.item_tree(db);
+ (
+ lookup.source(db).map(|it| it.kind()),
+ &item_tree[lookup.id.value].fields,
+ lookup.container,
+ )
+ }
+ };
+ let mut trace = Trace::new_for_map();
+ lower_struct(db, &mut trace, &src, container.krate, &item_tree, fields);
+ src.with_value(trace.into_map())
+ }
+}
diff --git a/crates/hir-def/src/trace.rs b/crates/hir-def/src/trace.rs
index 04d5b26619..da50ee8dc7 100644
--- a/crates/hir-def/src/trace.rs
+++ b/crates/hir-def/src/trace.rs
@@ -11,6 +11,8 @@
//! projections.
use la_arena::{Arena, ArenaMap, Idx, RawIdx};
+// FIXME: This isn't really used anymore, at least not in a way where it does anything useful.
+// Check if we should get rid of this or make proper use of it instead.
pub(crate) struct Trace<T, V> {
arena: Option<Arena<T>>,
map: Option<ArenaMap<Idx<T>, V>>,