From 06fa3d8389c833b01f482bf35b0f850e627612b9 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 20 Nov 2019 14:22:06 +0300 Subject: Move traits to hir_def --- crates/ra_hir_def/src/traits.rs | 67 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 crates/ra_hir_def/src/traits.rs (limited to 'crates/ra_hir_def/src/traits.rs') diff --git a/crates/ra_hir_def/src/traits.rs b/crates/ra_hir_def/src/traits.rs new file mode 100644 index 000000000..a8ba31594 --- /dev/null +++ b/crates/ra_hir_def/src/traits.rs @@ -0,0 +1,67 @@ +//! HIR for trait definitions. + +use std::sync::Arc; + +use hir_expand::name::{AsName, Name}; + +use ra_syntax::ast::{self, NameOwner}; +use rustc_hash::FxHashMap; + +use crate::{ + db::DefDatabase2, AssocItemId, AstItemDef, ConstId, FunctionId, LocationCtx, ModuleDefId, + ModuleId, TraitId, TypeAliasId, +}; + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct TraitData { + pub name: Option, + pub items: Vec, + pub auto: bool, +} + +impl TraitData { + pub(crate) fn trait_data_query(db: &impl DefDatabase2, tr: TraitId) -> Arc { + let src = tr.source(db); + let name = src.value.name().map(|n| n.as_name()); + let module = tr.module(db); + let ctx = LocationCtx::new(db, module, src.file_id); + let auto = src.value.is_auto(); + let items = if let Some(item_list) = src.value.item_list() { + item_list + .impl_items() + .map(|item_node| match item_node { + ast::ImplItem::FnDef(it) => FunctionId::from_ast(ctx, &it).into(), + ast::ImplItem::ConstDef(it) => ConstId::from_ast(ctx, &it).into(), + ast::ImplItem::TypeAliasDef(it) => TypeAliasId::from_ast(ctx, &it).into(), + }) + .collect() + } else { + Vec::new() + }; + Arc::new(TraitData { name, items, auto }) + } +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct TraitItemsIndex { + traits_by_def: FxHashMap, +} + +impl TraitItemsIndex { + pub fn trait_items_index(db: &impl DefDatabase2, module: ModuleId) -> TraitItemsIndex { + let mut index = TraitItemsIndex { traits_by_def: FxHashMap::default() }; + let crate_def_map = db.crate_def_map(module.krate); + for decl in crate_def_map[module.module_id].scope.declarations() { + if let ModuleDefId::TraitId(tr) = decl { + for item in db.trait_data(tr).items.iter() { + index.traits_by_def.insert(*item, tr); + } + } + } + index + } + + pub fn get_parent_trait(&self, item: AssocItemId) -> Option { + self.traits_by_def.get(&item).cloned() + } +} -- cgit v1.2.3 From cebeedc66fc40097eae20bf1767a285d00269966 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 20 Nov 2019 16:03:59 +0300 Subject: Next gen IDs for functions The current system with AstIds has two primaraly drawbacks: * It is possible to manufacture IDs out of thin air. For example, it's possible to create IDs for items which are not considered in CrateDefMap due to cfg. Or it is possible to mixup structs and unions, because they share ID space. * Getting the ID of a parent requires a secondary index. Instead, the plan is to pursue the more traditional approach, where each items stores the id of the parent declaration. This makes `FromSource` more awkward, but also more correct: now, to get from an AST to HIR, we first do this recursively for the parent item, and the just search the children of the parent for the matching def --- crates/ra_hir_def/src/traits.rs | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) (limited to 'crates/ra_hir_def/src/traits.rs') diff --git a/crates/ra_hir_def/src/traits.rs b/crates/ra_hir_def/src/traits.rs index a8ba31594..6e36bc0d0 100644 --- a/crates/ra_hir_def/src/traits.rs +++ b/crates/ra_hir_def/src/traits.rs @@ -2,14 +2,17 @@ use std::sync::Arc; -use hir_expand::name::{AsName, Name}; +use hir_expand::{ + name::{AsName, Name}, + AstId, +}; use ra_syntax::ast::{self, NameOwner}; use rustc_hash::FxHashMap; use crate::{ - db::DefDatabase2, AssocItemId, AstItemDef, ConstId, FunctionId, LocationCtx, ModuleDefId, - ModuleId, TraitId, TypeAliasId, + db::DefDatabase2, AssocItemId, AstItemDef, ConstId, FunctionContainerId, FunctionLoc, Intern, + LocationCtx, ModuleDefId, ModuleId, TraitId, TypeAliasId, }; #[derive(Debug, Clone, PartialEq, Eq)] @@ -26,11 +29,17 @@ impl TraitData { let module = tr.module(db); let ctx = LocationCtx::new(db, module, src.file_id); let auto = src.value.is_auto(); + let ast_id_map = db.ast_id_map(src.file_id); let items = if let Some(item_list) = src.value.item_list() { item_list .impl_items() .map(|item_node| match item_node { - ast::ImplItem::FnDef(it) => FunctionId::from_ast(ctx, &it).into(), + ast::ImplItem::FnDef(it) => FunctionLoc { + container: FunctionContainerId::TraitId(tr), + ast_id: AstId::new(src.file_id, ast_id_map.ast_id(&it)), + } + .intern(db) + .into(), ast::ImplItem::ConstDef(it) => ConstId::from_ast(ctx, &it).into(), ast::ImplItem::TypeAliasDef(it) => TypeAliasId::from_ast(ctx, &it).into(), }) @@ -54,7 +63,13 @@ impl TraitItemsIndex { for decl in crate_def_map[module.module_id].scope.declarations() { if let ModuleDefId::TraitId(tr) = decl { for item in db.trait_data(tr).items.iter() { - index.traits_by_def.insert(*item, tr); + match item { + AssocItemId::FunctionId(_) => (), + _ => { + let prev = index.traits_by_def.insert(*item, tr); + assert!(prev.is_none()); + } + } } } } -- cgit v1.2.3 From 64c21ed19594b323e72605ba8c5dd4c6eee433f6 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 20 Nov 2019 17:39:58 +0300 Subject: Switch type aliases to new sources --- crates/ra_hir_def/src/traits.rs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'crates/ra_hir_def/src/traits.rs') diff --git a/crates/ra_hir_def/src/traits.rs b/crates/ra_hir_def/src/traits.rs index 6e36bc0d0..228524a57 100644 --- a/crates/ra_hir_def/src/traits.rs +++ b/crates/ra_hir_def/src/traits.rs @@ -12,7 +12,7 @@ use rustc_hash::FxHashMap; use crate::{ db::DefDatabase2, AssocItemId, AstItemDef, ConstId, FunctionContainerId, FunctionLoc, Intern, - LocationCtx, ModuleDefId, ModuleId, TraitId, TypeAliasId, + LocationCtx, ModuleDefId, ModuleId, TraitId, TypeAliasContainerId, TypeAliasLoc, }; #[derive(Debug, Clone, PartialEq, Eq)] @@ -41,7 +41,12 @@ impl TraitData { .intern(db) .into(), ast::ImplItem::ConstDef(it) => ConstId::from_ast(ctx, &it).into(), - ast::ImplItem::TypeAliasDef(it) => TypeAliasId::from_ast(ctx, &it).into(), + ast::ImplItem::TypeAliasDef(it) => TypeAliasLoc { + container: TypeAliasContainerId::TraitId(tr), + ast_id: AstId::new(src.file_id, ast_id_map.ast_id(&it)), + } + .intern(db) + .into(), }) .collect() } else { @@ -65,6 +70,7 @@ impl TraitItemsIndex { for item in db.trait_data(tr).items.iter() { match item { AssocItemId::FunctionId(_) => (), + AssocItemId::TypeAliasId(_) => (), _ => { let prev = index.traits_by_def.insert(*item, tr); assert!(prev.is_none()); -- cgit v1.2.3 From ee95a35664e6fe9153f6324cfc57872ca365887c Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 20 Nov 2019 17:49:57 +0300 Subject: Don't duplicate ContainerId type --- crates/ra_hir_def/src/traits.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'crates/ra_hir_def/src/traits.rs') diff --git a/crates/ra_hir_def/src/traits.rs b/crates/ra_hir_def/src/traits.rs index 228524a57..bb61e852a 100644 --- a/crates/ra_hir_def/src/traits.rs +++ b/crates/ra_hir_def/src/traits.rs @@ -11,8 +11,8 @@ use ra_syntax::ast::{self, NameOwner}; use rustc_hash::FxHashMap; use crate::{ - db::DefDatabase2, AssocItemId, AstItemDef, ConstId, FunctionContainerId, FunctionLoc, Intern, - LocationCtx, ModuleDefId, ModuleId, TraitId, TypeAliasContainerId, TypeAliasLoc, + db::DefDatabase2, AssocItemId, AstItemDef, ConstId, ContainerId, FunctionLoc, Intern, + LocationCtx, ModuleDefId, ModuleId, TraitId, TypeAliasLoc, }; #[derive(Debug, Clone, PartialEq, Eq)] @@ -35,14 +35,14 @@ impl TraitData { .impl_items() .map(|item_node| match item_node { ast::ImplItem::FnDef(it) => FunctionLoc { - container: FunctionContainerId::TraitId(tr), + container: ContainerId::TraitId(tr), ast_id: AstId::new(src.file_id, ast_id_map.ast_id(&it)), } .intern(db) .into(), ast::ImplItem::ConstDef(it) => ConstId::from_ast(ctx, &it).into(), ast::ImplItem::TypeAliasDef(it) => TypeAliasLoc { - container: TypeAliasContainerId::TraitId(tr), + container: ContainerId::TraitId(tr), ast_id: AstId::new(src.file_id, ast_id_map.ast_id(&it)), } .intern(db) -- cgit v1.2.3 From 111891dc2dc1d2c7ea87144e8e3ddefe23fc7b6d Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 20 Nov 2019 18:00:01 +0300 Subject: Move constants to new ID This allows us to get rid of trait item index --- crates/ra_hir_def/src/traits.rs | 45 ++++++++--------------------------------- 1 file changed, 8 insertions(+), 37 deletions(-) (limited to 'crates/ra_hir_def/src/traits.rs') diff --git a/crates/ra_hir_def/src/traits.rs b/crates/ra_hir_def/src/traits.rs index bb61e852a..877d73d66 100644 --- a/crates/ra_hir_def/src/traits.rs +++ b/crates/ra_hir_def/src/traits.rs @@ -8,11 +8,10 @@ use hir_expand::{ }; use ra_syntax::ast::{self, NameOwner}; -use rustc_hash::FxHashMap; use crate::{ - db::DefDatabase2, AssocItemId, AstItemDef, ConstId, ContainerId, FunctionLoc, Intern, - LocationCtx, ModuleDefId, ModuleId, TraitId, TypeAliasLoc, + db::DefDatabase2, AssocItemId, AstItemDef, ConstLoc, ContainerId, FunctionLoc, Intern, TraitId, + TypeAliasLoc, }; #[derive(Debug, Clone, PartialEq, Eq)] @@ -26,8 +25,6 @@ impl TraitData { pub(crate) fn trait_data_query(db: &impl DefDatabase2, tr: TraitId) -> Arc { let src = tr.source(db); let name = src.value.name().map(|n| n.as_name()); - let module = tr.module(db); - let ctx = LocationCtx::new(db, module, src.file_id); let auto = src.value.is_auto(); let ast_id_map = db.ast_id_map(src.file_id); let items = if let Some(item_list) = src.value.item_list() { @@ -40,7 +37,12 @@ impl TraitData { } .intern(db) .into(), - ast::ImplItem::ConstDef(it) => ConstId::from_ast(ctx, &it).into(), + ast::ImplItem::ConstDef(it) => ConstLoc { + container: ContainerId::TraitId(tr), + ast_id: AstId::new(src.file_id, ast_id_map.ast_id(&it)), + } + .intern(db) + .into(), ast::ImplItem::TypeAliasDef(it) => TypeAliasLoc { container: ContainerId::TraitId(tr), ast_id: AstId::new(src.file_id, ast_id_map.ast_id(&it)), @@ -55,34 +57,3 @@ impl TraitData { Arc::new(TraitData { name, items, auto }) } } - -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct TraitItemsIndex { - traits_by_def: FxHashMap, -} - -impl TraitItemsIndex { - pub fn trait_items_index(db: &impl DefDatabase2, module: ModuleId) -> TraitItemsIndex { - let mut index = TraitItemsIndex { traits_by_def: FxHashMap::default() }; - let crate_def_map = db.crate_def_map(module.krate); - for decl in crate_def_map[module.module_id].scope.declarations() { - if let ModuleDefId::TraitId(tr) = decl { - for item in db.trait_data(tr).items.iter() { - match item { - AssocItemId::FunctionId(_) => (), - AssocItemId::TypeAliasId(_) => (), - _ => { - let prev = index.traits_by_def.insert(*item, tr); - assert!(prev.is_none()); - } - } - } - } - } - index - } - - pub fn get_parent_trait(&self, item: AssocItemId) -> Option { - self.traits_by_def.get(&item).cloned() - } -} -- cgit v1.2.3