Unnamed repository; edit this file 'description' to name the repository.
-rw-r--r--crates/hir-def/src/attr.rs21
-rw-r--r--crates/hir-def/src/db.rs12
-rw-r--r--crates/hir-def/src/item_tree.rs625
-rw-r--r--crates/hir-def/src/item_tree/lower.rs211
-rw-r--r--crates/hir-def/src/item_tree/pretty.rs84
-rw-r--r--crates/hir-def/src/nameres.rs6
-rw-r--r--crates/hir-def/src/nameres/collector.rs334
-rw-r--r--crates/hir-def/src/nameres/tests/incremental.rs12
-rw-r--r--crates/hir-ty/src/tests/incremental.rs8
9 files changed, 558 insertions, 755 deletions
diff --git a/crates/hir-def/src/attr.rs b/crates/hir-def/src/attr.rs
index a7328809a8..b509e69b0d 100644
--- a/crates/hir-def/src/attr.rs
+++ b/crates/hir-def/src/attr.rs
@@ -26,7 +26,7 @@ use crate::{
AdtId, AstIdLoc, AttrDefId, GenericParamId, HasModule, LocalFieldId, Lookup, MacroId,
VariantId,
db::DefDatabase,
- item_tree::AttrOwner,
+ item_tree::block_item_tree_query,
lang_item::LangItem,
nameres::{ModuleOrigin, ModuleSource},
src::{HasChildSource, HasSource},
@@ -523,26 +523,25 @@ impl AttrsWithOwner {
let mod_data = &def_map[module.local_id];
let raw_attrs = match mod_data.origin {
- ModuleOrigin::File { definition, declaration_tree_id, .. } => {
+ ModuleOrigin::File { definition, declaration_tree_id, declaration, .. } => {
let decl_attrs = declaration_tree_id
.item_tree(db)
- .raw_attrs(AttrOwner::ModItem(declaration_tree_id.value.into()))
+ .raw_attrs(declaration.upcast())
.clone();
let tree = db.file_item_tree(definition.into());
- let def_attrs = tree.raw_attrs(AttrOwner::TopLevel).clone();
+ let def_attrs = tree.top_level_raw_attrs().clone();
decl_attrs.merge(def_attrs)
}
ModuleOrigin::CrateRoot { definition } => {
let tree = db.file_item_tree(definition.into());
- tree.raw_attrs(AttrOwner::TopLevel).clone()
+ tree.top_level_raw_attrs().clone()
+ }
+ ModuleOrigin::Inline { definition_tree_id, definition } => {
+ definition_tree_id.item_tree(db).raw_attrs(definition.upcast()).clone()
}
- ModuleOrigin::Inline { definition_tree_id, .. } => definition_tree_id
- .item_tree(db)
- .raw_attrs(AttrOwner::ModItem(definition_tree_id.value.into()))
- .clone(),
ModuleOrigin::BlockExpr { id, .. } => {
- let tree = db.block_item_tree(id);
- tree.raw_attrs(AttrOwner::TopLevel).clone()
+ let tree = block_item_tree_query(db, id);
+ tree.top_level_raw_attrs().clone()
}
};
Attrs::expand_cfg_attr(db, module.krate, raw_attrs)
diff --git a/crates/hir-def/src/db.rs b/crates/hir-def/src/db.rs
index 362c0daa9b..27fe62c4f0 100644
--- a/crates/hir-def/src/db.rs
+++ b/crates/hir-def/src/db.rs
@@ -24,7 +24,7 @@ use crate::{
},
hir::generics::GenericParams,
import_map::ImportMap,
- item_tree::{AttrOwner, ItemTree},
+ item_tree::{ItemTree, file_item_tree_query},
lang_item::{self, LangItem},
nameres::{
assoc::{ImplItems, TraitItems},
@@ -108,11 +108,9 @@ pub trait DefDatabase: InternDatabase + ExpandDatabase + SourceDatabase {
fn expand_proc_attr_macros(&self) -> bool;
/// Computes an [`ItemTree`] for the given file or macro expansion.
- #[salsa::invoke(ItemTree::file_item_tree_query)]
- fn file_item_tree(&self, file_id: HirFileId) -> Arc<ItemTree>;
-
- #[salsa::invoke(ItemTree::block_item_tree_query)]
- fn block_item_tree(&self, block_id: BlockId) -> Arc<ItemTree>;
+ #[salsa::invoke(file_item_tree_query)]
+ #[salsa::transparent]
+ fn file_item_tree(&self, file_id: HirFileId) -> &ItemTree;
/// Turns a MacroId into a MacroDefId, describing the macro's definition post name resolution.
#[salsa::invoke(macro_def)]
@@ -376,7 +374,7 @@ fn include_macro_invoc(
fn crate_supports_no_std(db: &dyn DefDatabase, crate_id: Crate) -> bool {
let file = crate_id.data(db).root_file_id(db);
let item_tree = db.file_item_tree(file.into());
- let attrs = item_tree.raw_attrs(AttrOwner::TopLevel);
+ let attrs = item_tree.top_level_raw_attrs();
for attr in &**attrs {
match attr.path().as_ident() {
Some(ident) if *ident == sym::no_std => return true,
diff --git a/crates/hir-def/src/item_tree.rs b/crates/hir-def/src/item_tree.rs
index 81c8f56456..bf482d33e7 100644
--- a/crates/hir-def/src/item_tree.rs
+++ b/crates/hir-def/src/item_tree.rs
@@ -37,8 +37,8 @@ mod tests;
use std::{
fmt::{self, Debug},
- hash::{Hash, Hasher},
- ops::{Index, Range},
+ hash::Hash,
+ ops::Index,
sync::OnceLock,
};
@@ -51,12 +51,12 @@ use hir_expand::{
name::Name,
};
use intern::Interned;
-use la_arena::{Arena, Idx, RawIdx};
+use la_arena::{Idx, RawIdx};
use rustc_hash::FxHashMap;
-use smallvec::SmallVec;
use span::{AstIdNode, Edition, FileAstId, SyntaxContext};
use stdx::never;
use syntax::{SyntaxKind, ast, match_ast};
+use thin_vec::ThinVec;
use triomphe::Arc;
use crate::{BlockId, Lookup, attr::Attrs, db::DefDatabase};
@@ -64,13 +64,13 @@ use crate::{BlockId, Lookup, attr::Attrs, db::DefDatabase};
pub(crate) use crate::item_tree::lower::{lower_use_tree, visibility_from_ast};
#[derive(Copy, Clone, Eq, PartialEq)]
-pub struct RawVisibilityId(u32);
+pub(crate) struct RawVisibilityId(u32);
impl RawVisibilityId {
- pub const PUB: Self = RawVisibilityId(u32::MAX);
- pub const PRIV_IMPLICIT: Self = RawVisibilityId(u32::MAX - 1);
- pub const PRIV_EXPLICIT: Self = RawVisibilityId(u32::MAX - 2);
- pub const PUB_CRATE: Self = RawVisibilityId(u32::MAX - 3);
+ const PUB: Self = RawVisibilityId(u32::MAX);
+ const PRIV_IMPLICIT: Self = RawVisibilityId(u32::MAX - 1);
+ const PRIV_EXPLICIT: Self = RawVisibilityId(u32::MAX - 2);
+ const PUB_CRATE: Self = RawVisibilityId(u32::MAX - 3);
}
impl fmt::Debug for RawVisibilityId {
@@ -86,112 +86,115 @@ impl fmt::Debug for RawVisibilityId {
}
}
-/// The item tree of a source file.
-#[derive(Debug, Default, Eq, PartialEq)]
-pub struct ItemTree {
- top_level: SmallVec<[ModItem; 1]>,
- attrs: FxHashMap<AttrOwner, RawAttrs>,
+#[salsa_macros::tracked(returns(ref))]
+pub(crate) fn file_item_tree_query(db: &dyn DefDatabase, file_id: HirFileId) -> ItemTree {
+ let _p = tracing::info_span!("file_item_tree_query", ?file_id).entered();
+
+ let ctx = lower::Ctx::new(db, file_id);
+ let syntax = db.parse_or_expand(file_id);
+ let mut item_tree = match_ast! {
+ match syntax {
+ ast::SourceFile(file) => {
+ let top_attrs = RawAttrs::new(db, &file, ctx.span_map());
+ let mut item_tree = ctx.lower_module_items(&file);
+ item_tree.top_attrs = top_attrs;
+ item_tree
+ },
+ ast::MacroItems(items) => {
+ ctx.lower_module_items(&items)
+ },
+ ast::MacroStmts(stmts) => {
+ // The produced statements can include items, which should be added as top-level
+ // items.
+ ctx.lower_macro_stmts(stmts)
+ },
+ _ => {
+ if never!(syntax.kind() == SyntaxKind::ERROR, "{:?} from {:?} {}", file_id, syntax, syntax) {
+ return Default::default();
+ }
+ panic!("cannot create item tree for file {file_id:?} from {syntax:?} {syntax}");
+ },
+ }
+ };
- data: Option<Box<ItemTreeData>>,
+ item_tree.shrink_to_fit();
+ item_tree
}
-impl ItemTree {
- pub(crate) fn file_item_tree_query(db: &dyn DefDatabase, file_id: HirFileId) -> Arc<ItemTree> {
- let _p = tracing::info_span!("file_item_tree_query", ?file_id).entered();
- static EMPTY: OnceLock<Arc<ItemTree>> = OnceLock::new();
-
- let ctx = lower::Ctx::new(db, file_id);
- let syntax = db.parse_or_expand(file_id);
- let mut top_attrs = None;
- let mut item_tree = match_ast! {
- match syntax {
- ast::SourceFile(file) => {
- top_attrs = Some(RawAttrs::new(db, &file, ctx.span_map()));
- ctx.lower_module_items(&file)
- },
- ast::MacroItems(items) => {
- ctx.lower_module_items(&items)
- },
- ast::MacroStmts(stmts) => {
- // The produced statements can include items, which should be added as top-level
- // items.
- ctx.lower_macro_stmts(stmts)
- },
- _ => {
- if never!(syntax.kind() == SyntaxKind::ERROR, "{:?} from {:?} {}", file_id, syntax, syntax) {
- return Default::default();
- }
- panic!("cannot create item tree for file {file_id:?} from {syntax:?} {syntax}");
- },
- }
- };
+#[salsa_macros::tracked(returns(ref))]
+pub(crate) fn block_item_tree_query(db: &dyn DefDatabase, block: BlockId) -> Arc<ItemTree> {
+ let _p = tracing::info_span!("block_item_tree_query", ?block).entered();
+ // Blocks have a tendency to be empty due to macro calls that do not expand to items,
+ // so deduplicate this case via `Arc` to reduce the size of the query storage here.
+ static EMPTY: OnceLock<Arc<ItemTree>> = OnceLock::new();
- if let Some(attrs) = top_attrs {
- item_tree.attrs.insert(AttrOwner::TopLevel, attrs);
- }
- if item_tree.data.is_none() && item_tree.top_level.is_empty() && item_tree.attrs.is_empty()
- {
- EMPTY
- .get_or_init(|| {
- Arc::new(ItemTree {
- top_level: SmallVec::new_const(),
- attrs: FxHashMap::default(),
- data: None,
- })
- })
- .clone()
- } else {
- item_tree.shrink_to_fit();
- Arc::new(item_tree)
- }
- }
+ let loc = block.lookup(db);
+ let block = loc.ast_id.to_node(db);
- pub(crate) fn block_item_tree_query(db: &dyn DefDatabase, block: BlockId) -> Arc<ItemTree> {
- let _p = tracing::info_span!("block_item_tree_query", ?block).entered();
- static EMPTY: OnceLock<Arc<ItemTree>> = OnceLock::new();
-
- let loc = block.lookup(db);
- let block = loc.ast_id.to_node(db);
-
- let ctx = lower::Ctx::new(db, loc.ast_id.file_id);
- let mut item_tree = ctx.lower_block(&block);
- if item_tree.data.is_none() && item_tree.top_level.is_empty() && item_tree.attrs.is_empty()
- {
- EMPTY
- .get_or_init(|| {
- Arc::new(ItemTree {
- top_level: SmallVec::new_const(),
- attrs: FxHashMap::default(),
- data: None,
- })
+ let ctx = lower::Ctx::new(db, loc.ast_id.file_id);
+ let mut item_tree = ctx.lower_block(&block);
+ if item_tree.small_data.is_empty()
+ && item_tree.big_data.is_empty()
+ && item_tree.top_level.is_empty()
+ && item_tree.attrs.is_empty()
+ && item_tree.top_attrs.is_empty()
+ {
+ EMPTY
+ .get_or_init(|| {
+ Arc::new(ItemTree {
+ top_level: Box::new([]),
+ attrs: FxHashMap::default(),
+ small_data: FxHashMap::default(),
+ big_data: FxHashMap::default(),
+ top_attrs: RawAttrs::EMPTY,
+ vis: ItemVisibilities { arena: ThinVec::new() },
})
- .clone()
- } else {
- item_tree.shrink_to_fit();
- Arc::new(item_tree)
- }
+ })
+ .clone()
+ } else {
+ item_tree.shrink_to_fit();
+ Arc::new(item_tree)
}
+}
+/// The item tree of a source file.
+#[derive(Debug, Default, Eq, PartialEq)]
+pub struct ItemTree {
+ top_level: Box<[ModItemId]>,
+ top_attrs: RawAttrs,
+ attrs: FxHashMap<FileAstId<ast::Item>, RawAttrs>,
+ vis: ItemVisibilities,
+ // FIXME: They values store the key, turn this into a FxHashSet<ModItem> instead?
+ big_data: FxHashMap<FileAstId<ast::Item>, BigModItem>,
+ small_data: FxHashMap<FileAstId<ast::Item>, SmallModItem>,
+}
+impl ItemTree {
/// Returns an iterator over all items located at the top level of the `HirFileId` this
/// `ItemTree` was created from.
- pub fn top_level_items(&self) -> &[ModItem] {
+ pub(crate) fn top_level_items(&self) -> &[ModItemId] {
&self.top_level
}
/// Returns the inner attributes of the source file.
- pub fn top_level_attrs(&self, db: &dyn DefDatabase, krate: Crate) -> Attrs {
- Attrs::expand_cfg_attr(
- db,
- krate,
- self.attrs.get(&AttrOwner::TopLevel).unwrap_or(&RawAttrs::EMPTY).clone(),
- )
+ pub(crate) fn top_level_raw_attrs(&self) -> &RawAttrs {
+ &self.top_attrs
}
- pub(crate) fn raw_attrs(&self, of: AttrOwner) -> &RawAttrs {
+ /// Returns the inner attributes of the source file.
+ pub(crate) fn top_level_attrs(&self, db: &dyn DefDatabase, krate: Crate) -> Attrs {
+ Attrs::expand_cfg_attr(db, krate, self.top_attrs.clone())
+ }
+
+ pub(crate) fn raw_attrs(&self, of: FileAstId<ast::Item>) -> &RawAttrs {
self.attrs.get(&of).unwrap_or(&RawAttrs::EMPTY)
}
- pub(crate) fn attrs(&self, db: &dyn DefDatabase, krate: Crate, of: AttrOwner) -> Attrs {
+ pub(crate) fn attrs(
+ &self,
+ db: &dyn DefDatabase,
+ krate: Crate,
+ of: FileAstId<ast::Item>,
+ ) -> Attrs {
Attrs::expand_cfg_attr(db, krate, self.raw_attrs(of).clone())
}
@@ -199,105 +202,79 @@ impl ItemTree {
///
/// For more detail, see [`ItemTreeDataStats`].
pub fn item_tree_stats(&self) -> ItemTreeDataStats {
- match self.data {
- Some(ref data) => ItemTreeDataStats {
- traits: data.traits.len(),
- impls: data.impls.len(),
- mods: data.mods.len(),
- macro_calls: data.macro_calls.len(),
- macro_rules: data.macro_rules.len(),
- },
- None => ItemTreeDataStats::default(),
+ let mut traits = 0;
+ let mut impls = 0;
+ let mut mods = 0;
+ let mut macro_calls = 0;
+ let mut macro_rules = 0;
+ for item in self.small_data.values() {
+ match item {
+ SmallModItem::Trait(_) => traits += 1,
+ SmallModItem::Impl(_) => impls += 1,
+ SmallModItem::MacroRules(_) => macro_rules += 1,
+ SmallModItem::MacroCall(_) => macro_calls += 1,
+ _ => {}
+ }
+ }
+ for item in self.big_data.values() {
+ match item {
+ BigModItem::Mod(_) => mods += 1,
+ _ => {}
+ }
}
+ ItemTreeDataStats { traits, impls, mods, macro_calls, macro_rules }
}
pub fn pretty_print(&self, db: &dyn DefDatabase, edition: Edition) -> String {
pretty::print_item_tree(db, self, edition)
}
- fn data(&self) -> &ItemTreeData {
- self.data.as_ref().expect("attempted to access data of empty ItemTree")
- }
-
- fn data_mut(&mut self) -> &mut ItemTreeData {
- self.data.get_or_insert_with(Box::default)
- }
-
fn shrink_to_fit(&mut self) {
- let ItemTree { top_level, attrs, data } = self;
- top_level.shrink_to_fit();
+ let ItemTree { top_level: _, attrs, big_data, small_data, vis: _, top_attrs: _ } = self;
attrs.shrink_to_fit();
- if let Some(data) = data {
- let ItemTreeData {
- uses,
- extern_crates,
- extern_blocks,
- functions,
- structs,
- unions,
- enums,
- consts,
- statics,
- traits,
- trait_aliases,
- impls,
- type_aliases,
- mods,
- macro_calls,
- macro_rules,
- macro_defs,
- vis: _,
- } = &mut **data;
-
- uses.shrink_to_fit();
- extern_crates.shrink_to_fit();
- extern_blocks.shrink_to_fit();
- functions.shrink_to_fit();
- structs.shrink_to_fit();
- unions.shrink_to_fit();
- enums.shrink_to_fit();
- consts.shrink_to_fit();
- statics.shrink_to_fit();
- traits.shrink_to_fit();
- trait_aliases.shrink_to_fit();
- impls.shrink_to_fit();
- type_aliases.shrink_to_fit();
- mods.shrink_to_fit();
- macro_calls.shrink_to_fit();
- macro_rules.shrink_to_fit();
- macro_defs.shrink_to_fit();
- }
+ big_data.shrink_to_fit();
+ small_data.shrink_to_fit();
}
}
#[derive(Default, Debug, Eq, PartialEq)]
struct ItemVisibilities {
- arena: Box<[RawVisibility]>,
+ arena: ThinVec<RawVisibility>,
}
-#[derive(Default, Debug, Eq, PartialEq)]
-struct ItemTreeData {
- uses: Arena<Use>,
- extern_crates: Arena<ExternCrate>,
- extern_blocks: Arena<ExternBlock>,
- functions: Arena<Function>,
- structs: Arena<Struct>,
- unions: Arena<Union>,
- enums: Arena<Enum>,
- consts: Arena<Const>,
- statics: Arena<Static>,
- traits: Arena<Trait>,
- trait_aliases: Arena<TraitAlias>,
- impls: Arena<Impl>,
- type_aliases: Arena<TypeAlias>,
- mods: Arena<Mod>,
- macro_calls: Arena<MacroCall>,
- macro_rules: Arena<MacroRules>,
- macro_defs: Arena<Macro2>,
+#[derive(Debug, Clone, Eq, PartialEq)]
+enum SmallModItem {
+ Const(Const),
+ Enum(Enum),
+ ExternBlock(ExternBlock),
+ Function(Function),
+ Impl(Impl),
+ Macro2(Macro2),
+ MacroCall(MacroCall),
+ MacroRules(MacroRules),
+ Static(Static),
+ Struct(Struct),
+ Trait(Trait),
+ TraitAlias(TraitAlias),
+ TypeAlias(TypeAlias),
+ Union(Union),
+}
- vis: ItemVisibilities,
+#[derive(Debug, Clone, Eq, PartialEq)]
+enum BigModItem {
+ ExternCrate(ExternCrate),
+ Mod(Mod),
+ Use(Use),
}
+// `ModItem` is stored a bunch in `ItemTree`'s so we pay the max for each item. It should stay as
+// small as possible which is why we split them in two, most common ones are 3 usize but some rarer
+// ones are 5.
+#[cfg(target_pointer_width = "64")]
+const _: [(); std::mem::size_of::<BigModItem>()] = [(); std::mem::size_of::<[usize; 5]>()];
+#[cfg(target_pointer_width = "64")]
+const _: [(); std::mem::size_of::<SmallModItem>()] = [(); std::mem::size_of::<[usize; 3]>()];
+
#[derive(Default, Debug, Eq, PartialEq)]
pub struct ItemTreeDataStats {
pub traits: usize,
@@ -307,73 +284,13 @@ pub struct ItemTreeDataStats {
pub macro_rules: usize,
}
-#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
-pub enum AttrOwner {
- /// Attributes on an item.
- ModItem(ModItem),
- /// Inner attributes of the source file.
- TopLevel,
-}
-
-impl From<ModItem> for AttrOwner {
- #[inline]
- fn from(value: ModItem) -> Self {
- AttrOwner::ModItem(value)
- }
-}
-
/// Trait implemented by all nodes in the item tree.
-pub trait ItemTreeNode: Clone {
+pub(crate) trait ItemTreeNode: Clone {
type Source: AstIdNode;
-
- fn ast_id(&self) -> FileAstId<Self::Source>;
-
- /// Looks up an instance of `Self` in an item tree.
- fn lookup(tree: &ItemTree, index: Idx<Self>) -> &Self;
}
-pub struct FileItemTreeId<N>(Idx<N>);
-
-impl<N> FileItemTreeId<N> {
- pub fn range_iter(range: Range<Self>) -> impl Iterator<Item = Self> + Clone {
- (range.start.index().into_raw().into_u32()..range.end.index().into_raw().into_u32())
- .map(RawIdx::from_u32)
- .map(Idx::from_raw)
- .map(Self)
- }
-}
-
-impl<N> FileItemTreeId<N> {
- pub fn index(&self) -> Idx<N> {
- self.0
- }
-}
-
-impl<N> Clone for FileItemTreeId<N> {
- fn clone(&self) -> Self {
- *self
- }
-}
-impl<N> Copy for FileItemTreeId<N> {}
-
-impl<N> PartialEq for FileItemTreeId<N> {
- fn eq(&self, other: &FileItemTreeId<N>) -> bool {
- self.0 == other.0
- }
-}
-impl<N> Eq for FileItemTreeId<N> {}
-
-impl<N> Hash for FileItemTreeId<N> {
- fn hash<H: Hasher>(&self, state: &mut H) {
- self.0.hash(state)
- }
-}
-
-impl<N> fmt::Debug for FileItemTreeId<N> {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- self.0.fmt(f)
- }
-}
+#[allow(type_alias_bounds)]
+pub(crate) type ItemTreeAstId<T: ItemTreeNode> = FileAstId<T::Source>;
/// Identifies a particular [`ItemTree`].
#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)]
@@ -383,14 +300,14 @@ pub struct TreeId {
}
impl TreeId {
- pub fn new(file: HirFileId, block: Option<BlockId>) -> Self {
+ pub(crate) fn new(file: HirFileId, block: Option<BlockId>) -> Self {
Self { file, block }
}
- pub fn item_tree(&self, db: &dyn DefDatabase) -> Arc<ItemTree> {
+ pub(crate) fn item_tree<'db>(&self, db: &'db dyn DefDatabase) -> &'db ItemTree {
match self.block {
- Some(block) => db.block_item_tree(block),
- None => db.file_item_tree(self.file),
+ Some(block) => block_item_tree_query(db, block),
+ None => file_item_tree_query(db, self.file),
}
}
@@ -399,85 +316,32 @@ impl TreeId {
self.file
}
- pub fn is_block(self) -> bool {
+ pub(crate) fn is_block(self) -> bool {
self.block.is_some()
}
}
-#[derive(Debug)]
-pub struct ItemTreeId<N> {
- tree: TreeId,
- pub value: FileItemTreeId<N>,
-}
-
-impl<N> ItemTreeId<N> {
- pub fn new(tree: TreeId, idx: FileItemTreeId<N>) -> Self {
- Self { tree, value: idx }
- }
-
- pub fn file_id(self) -> HirFileId {
- self.tree.file
- }
-
- pub fn tree_id(self) -> TreeId {
- self.tree
- }
-
- pub fn item_tree(self, db: &dyn DefDatabase) -> Arc<ItemTree> {
- self.tree.item_tree(db)
- }
-
- pub fn resolved<R>(self, db: &dyn DefDatabase, cb: impl FnOnce(&N) -> R) -> R
- where
- ItemTree: Index<FileItemTreeId<N>, Output = N>,
- {
- cb(&self.tree.item_tree(db)[self.value])
- }
-}
-
-impl<N> Copy for ItemTreeId<N> {}
-impl<N> Clone for ItemTreeId<N> {
- fn clone(&self) -> Self {
- *self
- }
-}
-
-impl<N> PartialEq for ItemTreeId<N> {
- fn eq(&self, other: &Self) -> bool {
- self.tree == other.tree && self.value == other.value
- }
-}
-
-impl<N> Eq for ItemTreeId<N> {}
-
-impl<N> Hash for ItemTreeId<N> {
- fn hash<H: Hasher>(&self, state: &mut H) {
- self.tree.hash(state);
- self.value.hash(state);
- }
-}
-
macro_rules! mod_items {
- ( $( $typ:ident in $fld:ident -> $ast:ty ),+ $(,)? ) => {
+ ($mod_item:ident -> $( $typ:ident in $fld:ident -> $ast:ty ),+ $(,)? ) => {
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
- pub enum ModItem {
+ pub(crate) enum $mod_item {
$(
- $typ(FileItemTreeId<$typ>),
+ $typ(FileAstId<$ast>),
)+
}
- impl ModItem {
- pub fn ast_id(&self, tree: &ItemTree) -> FileAstId<ast::Item> {
+ impl $mod_item {
+ pub(crate) fn ast_id(self) -> FileAstId<ast::Item> {
match self {
- $(ModItem::$typ(it) => tree[it.index()].ast_id().upcast()),+
+ $($mod_item::$typ(it) => it.upcast()),+
}
}
}
$(
- impl From<FileItemTreeId<$typ>> for ModItem {
- fn from(id: FileItemTreeId<$typ>) -> ModItem {
- ModItem::$typ(id)
+ impl From<FileAstId<$ast>> for $mod_item {
+ fn from(id: FileAstId<$ast>) -> $mod_item {
+ ModItemId::$typ(id)
}
}
)+
@@ -485,21 +349,19 @@ macro_rules! mod_items {
$(
impl ItemTreeNode for $typ {
type Source = $ast;
-
- fn ast_id(&self) -> FileAstId<Self::Source> {
- self.ast_id
- }
-
- fn lookup(tree: &ItemTree, index: Idx<Self>) -> &Self {
- &tree.data().$fld[index]
- }
}
- impl Index<Idx<$typ>> for ItemTree {
+ impl Index<FileAstId<$ast>> for ItemTree {
type Output = $typ;
- fn index(&self, index: Idx<$typ>) -> &Self::Output {
- &self.data().$fld[index]
+ #[allow(unused_imports)]
+ fn index(&self, index: FileAstId<$ast>) -> &Self::Output {
+ use BigModItem::*;
+ use SmallModItem::*;
+ match &self.$fld[&index.upcast()] {
+ $typ(item) => item,
+ _ => panic!("expected item of type `{}` at index `{:?}`", stringify!($typ), index),
+ }
}
}
)+
@@ -507,23 +369,24 @@ macro_rules! mod_items {
}
mod_items! {
- Use in uses -> ast::Use,
- ExternCrate in extern_crates -> ast::ExternCrate,
- ExternBlock in extern_blocks -> ast::ExternBlock,
- Function in functions -> ast::Fn,
- Struct in structs -> ast::Struct,
- Union in unions -> ast::Union,
- Enum in enums -> ast::Enum,
- Const in consts -> ast::Const,
- Static in statics -> ast::Static,
- Trait in traits -> ast::Trait,
- TraitAlias in trait_aliases -> ast::TraitAlias,
- Impl in impls -> ast::Impl,
- TypeAlias in type_aliases -> ast::TypeAlias,
- Mod in mods -> ast::Module,
- MacroCall in macro_calls -> ast::MacroCall,
- MacroRules in macro_rules -> ast::MacroRules,
- Macro2 in macro_defs -> ast::MacroDef,
+ModItemId ->
+ Const in small_data -> ast::Const,
+ Enum in small_data -> ast::Enum,
+ ExternBlock in small_data -> ast::ExternBlock,
+ ExternCrate in big_data -> ast::ExternCrate,
+ Function in small_data -> ast::Fn,
+ Impl in small_data -> ast::Impl,
+ Macro2 in small_data -> ast::MacroDef,
+ MacroCall in small_data -> ast::MacroCall,
+ MacroRules in small_data -> ast::MacroRules,
+ Mod in big_data -> ast::Module,
+ Static in small_data -> ast::Static,
+ Struct in small_data -> ast::Struct,
+ Trait in small_data -> ast::Trait,
+ TraitAlias in small_data -> ast::TraitAlias,
+ TypeAlias in small_data -> ast::TypeAlias,
+ Union in small_data -> ast::Union,
+ Use in big_data -> ast::Use,
}
impl Index<RawVisibilityId> for ItemTree {
@@ -554,31 +417,24 @@ impl Index<RawVisibilityId> for ItemTree {
VisibilityExplicitness::Explicit,
)
}),
- _ => &self.data().vis.arena[index.0 as usize],
+ _ => &self.vis.arena[index.0 as usize],
}
}
}
-impl<N: ItemTreeNode> Index<FileItemTreeId<N>> for ItemTree {
- type Output = N;
- fn index(&self, id: FileItemTreeId<N>) -> &N {
- N::lookup(self, id.index())
- }
-}
-
#[derive(Debug, Clone, Eq, PartialEq)]
pub struct Use {
- pub visibility: RawVisibilityId,
- pub ast_id: FileAstId<ast::Use>,
- pub use_tree: UseTree,
+ pub(crate) visibility: RawVisibilityId,
+ pub(crate) use_tree: UseTree,
}
#[derive(Debug, Clone, Eq, PartialEq)]
pub struct UseTree {
- pub index: Idx<ast::UseTree>,
kind: UseTreeKind,
}
+// FIXME: Would be nice to encode `None` into this
+// We could just use a `Name` where `_` well means `_` ..
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum ImportAlias {
/// Unnamed alias, as in `use Foo as _;`
@@ -632,43 +488,37 @@ pub enum UseTreeKind {
pub struct ExternCrate {
pub name: Name,
pub alias: Option<ImportAlias>,
- pub visibility: RawVisibilityId,
- pub ast_id: FileAstId<ast::ExternCrate>,
+ pub(crate) visibility: RawVisibilityId,
}
#[derive(Debug, Clone, Eq, PartialEq)]
pub struct ExternBlock {
- pub ast_id: FileAstId<ast::ExternBlock>,
- pub children: Box<[ModItem]>,
+ pub(crate) children: Box<[ModItemId]>,
}
#[derive(Debug, Clone, Eq, PartialEq)]
pub struct Function {
pub name: Name,
- pub visibility: RawVisibilityId,
- pub ast_id: FileAstId<ast::Fn>,
+ pub(crate) visibility: RawVisibilityId,
}
#[derive(Debug, Clone, Eq, PartialEq)]
pub struct Struct {
pub name: Name,
- pub visibility: RawVisibilityId,
+ pub(crate) visibility: RawVisibilityId,
pub shape: FieldsShape,
- pub ast_id: FileAstId<ast::Struct>,
}
#[derive(Debug, Clone, Eq, PartialEq)]
pub struct Union {
pub name: Name,
- pub visibility: RawVisibilityId,
- pub ast_id: FileAstId<ast::Union>,
+ pub(crate) visibility: RawVisibilityId,
}
#[derive(Debug, Clone, Eq, PartialEq)]
pub struct Enum {
pub name: Name,
- pub visibility: RawVisibilityId,
- pub ast_id: FileAstId<ast::Enum>,
+ pub(crate) visibility: RawVisibilityId,
}
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
@@ -706,55 +556,47 @@ impl VisibilityExplicitness {
pub struct Const {
/// `None` for `const _: () = ();`
pub name: Option<Name>,
- pub visibility: RawVisibilityId,
- pub ast_id: FileAstId<ast::Const>,
+ pub(crate) visibility: RawVisibilityId,
}
#[derive(Debug, Clone, Eq, PartialEq)]
pub struct Static {
pub name: Name,
- pub visibility: RawVisibilityId,
- pub ast_id: FileAstId<ast::Static>,
+ pub(crate) visibility: RawVisibilityId,
}
#[derive(Debug, Clone, Eq, PartialEq)]
pub struct Trait {
pub name: Name,
- pub visibility: RawVisibilityId,
- pub ast_id: FileAstId<ast::Trait>,
+ pub(crate) visibility: RawVisibilityId,
}
#[derive(Debug, Clone, Eq, PartialEq)]
pub struct TraitAlias {
pub name: Name,
- pub visibility: RawVisibilityId,
- pub ast_id: FileAstId<ast::TraitAlias>,
+ pub(crate) visibility: RawVisibilityId,
}
#[derive(Debug, Clone, Eq, PartialEq)]
-pub struct Impl {
- pub ast_id: FileAstId<ast::Impl>,
-}
+pub struct Impl {}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct TypeAlias {
pub name: Name,
- pub visibility: RawVisibilityId,
- pub ast_id: FileAstId<ast::TypeAlias>,
+ pub(crate) visibility: RawVisibilityId,
}
#[derive(Debug, Clone, Eq, PartialEq)]
pub struct Mod {
pub name: Name,
- pub visibility: RawVisibilityId,
- pub kind: ModKind,
- pub ast_id: FileAstId<ast::Module>,
+ pub(crate) visibility: RawVisibilityId,
+ pub(crate) kind: ModKind,
}
#[derive(Debug, Clone, Eq, PartialEq)]
-pub enum ModKind {
+pub(crate) enum ModKind {
/// `mod m { ... }`
- Inline { items: Box<[ModItem]> },
+ Inline { items: Box<[ModItemId]> },
/// `mod m;`
Outline,
}
@@ -763,7 +605,6 @@ pub enum ModKind {
pub struct MacroCall {
/// Path to the called macro.
pub path: Interned<ModPath>,
- pub ast_id: FileAstId<ast::MacroCall>,
pub expand_to: ExpandTo,
pub ctxt: SyntaxContext,
}
@@ -772,15 +613,13 @@ pub struct MacroCall {
pub struct MacroRules {
/// The name of the declared macro.
pub name: Name,
- pub ast_id: FileAstId<ast::MacroRules>,
}
/// "Macros 2.0" macro definition.
#[derive(Debug, Clone, Eq, PartialEq)]
pub struct Macro2 {
pub name: Name,
- pub visibility: RawVisibilityId,
- pub ast_id: FileAstId<ast::MacroDef>,
+ pub(crate) visibility: RawVisibilityId,
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
@@ -793,15 +632,17 @@ pub enum ImportKind {
TypeOnly,
}
-impl UseTree {
+impl Use {
/// Expands the `UseTree` into individually imported `ModPath`s.
pub fn expand(
&self,
mut cb: impl FnMut(Idx<ast::UseTree>, ModPath, ImportKind, Option<ImportAlias>),
) {
- self.expand_impl(None, &mut cb)
+ self.use_tree.expand_impl(None, &mut 0, &mut cb)
}
+}
+impl UseTree {
/// The [`UseTreeKind`] of this `UseTree`.
pub fn kind(&self) -> &UseTreeKind {
&self.kind
@@ -810,6 +651,7 @@ impl UseTree {
fn expand_impl(
&self,
prefix: Option<ModPath>,
+ counting_index: &mut u32,
cb: &mut impl FnMut(Idx<ast::UseTree>, ModPath, ImportKind, Option<ImportAlias>),
) {
fn concat_mod_paths(
@@ -845,17 +687,27 @@ impl UseTree {
match &self.kind {
UseTreeKind::Single { path, alias } => {
if let Some((path, kind)) = concat_mod_paths(prefix, path) {
- cb(self.index, path, kind, alias.clone());
+ cb(Idx::from_raw(RawIdx::from_u32(*counting_index)), path, kind, alias.clone());
}
}
UseTreeKind::Glob { path: Some(path) } => {
if let Some((path, _)) = concat_mod_paths(prefix, path) {
- cb(self.index, path, ImportKind::Glob, None);
+ cb(
+ Idx::from_raw(RawIdx::from_u32(*counting_index)),
+ path,
+ ImportKind::Glob,
+ None,
+ );
}
}
UseTreeKind::Glob { path: None } => {
if let Some(prefix) = prefix {
- cb(self.index, prefix, ImportKind::Glob, None);
+ cb(
+ Idx::from_raw(RawIdx::from_u32(*counting_index)),
+ prefix,
+ ImportKind::Glob,
+ None,
+ );
}
}
UseTreeKind::Prefixed { prefix: additional_prefix, list } => {
@@ -867,7 +719,8 @@ impl UseTree {
None => prefix,
};
for tree in &**list {
- tree.expand_impl(prefix.clone(), cb);
+ *counting_index += 1;
+ tree.expand_impl(prefix.clone(), counting_index, cb);
}
}
}
diff --git a/crates/hir-def/src/item_tree/lower.rs b/crates/hir-def/src/item_tree/lower.rs
index 26d209c972..fe1b8e3134 100644
--- a/crates/hir-def/src/item_tree/lower.rs
+++ b/crates/hir-def/src/item_tree/lower.rs
@@ -10,7 +10,7 @@ use hir_expand::{
span_map::{SpanMap, SpanMapRef},
};
use la_arena::Arena;
-use span::{AstIdMap, SyntaxContext};
+use span::{AstIdMap, FileAstId, SyntaxContext};
use syntax::{
AstNode,
ast::{self, HasModuleItem, HasName},
@@ -20,24 +20,21 @@ use triomphe::Arc;
use crate::{
db::DefDatabase,
item_tree::{
- AttrOwner, Const, Enum, ExternBlock, ExternCrate, FieldsShape, FileItemTreeId, Function,
- Idx, Impl, ImportAlias, Interned, ItemTree, ItemTreeData, Macro2, MacroCall, MacroRules,
- Mod, ModItem, ModKind, ModPath, RawAttrs, RawVisibility, RawVisibilityId, Static, Struct,
- StructKind, Trait, TraitAlias, TypeAlias, Union, Use, UseTree, UseTreeKind,
+ BigModItem, Const, Enum, ExternBlock, ExternCrate, FieldsShape, Function, Impl,
+ ImportAlias, Interned, ItemTree, ItemTreeAstId, Macro2, MacroCall, MacroRules, Mod,
+ ModItemId, ModKind, ModPath, RawAttrs, RawVisibility, RawVisibilityId, SmallModItem,
+ Static, Struct, StructKind, Trait, TraitAlias, TypeAlias, Union, Use, UseTree, UseTreeKind,
VisibilityExplicitness,
},
};
-fn id<N>(index: Idx<N>) -> FileItemTreeId<N> {
- FileItemTreeId(index)
-}
-
pub(super) struct Ctx<'a> {
db: &'a dyn DefDatabase,
tree: ItemTree,
source_ast_id_map: Arc<AstIdMap>,
span_map: OnceCell<SpanMap>,
file: HirFileId,
+ top_level: Vec<ModItemId>,
visibilities: FxIndexSet<RawVisibility>,
}
@@ -50,6 +47,7 @@ impl<'a> Ctx<'a> {
file,
span_map: OnceCell::new(),
visibilities: FxIndexSet::default(),
+ top_level: Vec::new(),
}
}
@@ -58,16 +56,14 @@ impl<'a> Ctx<'a> {
}
pub(super) fn lower_module_items(mut self, item_owner: &dyn HasModuleItem) -> ItemTree {
- self.tree.top_level =
- item_owner.items().flat_map(|item| self.lower_mod_item(&item)).collect();
- if let Some(data) = &mut self.tree.data {
- data.vis.arena = self.visibilities.into_iter().collect();
- }
+ self.top_level = item_owner.items().flat_map(|item| self.lower_mod_item(&item)).collect();
+ self.tree.vis.arena = self.visibilities.into_iter().collect();
+ self.tree.top_level = self.top_level.into_boxed_slice();
self.tree
}
pub(super) fn lower_macro_stmts(mut self, stmts: ast::MacroStmts) -> ItemTree {
- self.tree.top_level = stmts
+ self.top_level = stmts
.statements()
.filter_map(|stmt| {
match stmt {
@@ -91,20 +87,19 @@ impl<'a> Ctx<'a> {
if let Some(call) = tail_macro.macro_call() {
cov_mark::hit!(macro_stmt_with_trailing_macro_expr);
if let Some(mod_item) = self.lower_mod_item(&call.into()) {
- self.tree.top_level.push(mod_item);
+ self.top_level.push(mod_item);
}
}
}
- if let Some(data) = &mut self.tree.data {
- data.vis.arena = self.visibilities.into_iter().collect();
- }
+ self.tree.vis.arena = self.visibilities.into_iter().collect();
+ self.tree.top_level = self.top_level.into_boxed_slice();
self.tree
}
pub(super) fn lower_block(mut self, block: &ast::BlockExpr) -> ItemTree {
- self.tree.attrs.insert(AttrOwner::TopLevel, RawAttrs::new(self.db, block, self.span_map()));
- self.tree.top_level = block
+ self.tree.top_attrs = RawAttrs::new(self.db, block, self.span_map());
+ self.top_level = block
.statements()
.filter_map(|stmt| match stmt {
ast::Stmt::Item(item) => self.lower_mod_item(&item),
@@ -120,22 +115,17 @@ impl<'a> Ctx<'a> {
if let Some(ast::Expr::MacroExpr(expr)) = block.tail_expr() {
if let Some(call) = expr.macro_call() {
if let Some(mod_item) = self.lower_mod_item(&call.into()) {
- self.tree.top_level.push(mod_item);
+ self.top_level.push(mod_item);
}
}
}
- if let Some(data) = &mut self.tree.data {
- data.vis.arena = self.visibilities.into_iter().collect();
- }
+ self.tree.vis.arena = self.visibilities.into_iter().collect();
+ self.tree.top_level = self.top_level.into_boxed_slice();
self.tree
}
- fn data(&mut self) -> &mut ItemTreeData {
- self.tree.data_mut()
- }
-
- fn lower_mod_item(&mut self, item: &ast::Item) -> Option<ModItem> {
- let mod_item: ModItem = match item {
+ fn lower_mod_item(&mut self, item: &ast::Item) -> Option<ModItemId> {
+ let mod_item: ModItemId = match item {
ast::Item::Struct(ast) => self.lower_struct(ast)?.into(),
ast::Item::Union(ast) => self.lower_union(ast)?.into(),
ast::Item::Enum(ast) => self.lower_enum(ast)?.into(),
@@ -155,12 +145,12 @@ impl<'a> Ctx<'a> {
ast::Item::ExternBlock(ast) => self.lower_extern_block(ast).into(),
};
let attrs = RawAttrs::new(self.db, item, self.span_map());
- self.add_attrs(mod_item.into(), attrs);
+ self.add_attrs(mod_item.ast_id(), attrs);
Some(mod_item)
}
- fn add_attrs(&mut self, item: AttrOwner, attrs: RawAttrs) {
+ fn add_attrs(&mut self, item: FileAstId<ast::Item>, attrs: RawAttrs) {
if !attrs.is_empty() {
match self.tree.attrs.entry(item) {
Entry::Occupied(mut entry) => {
@@ -173,76 +163,78 @@ impl<'a> Ctx<'a> {
}
}
- fn lower_struct(&mut self, strukt: &ast::Struct) -> Option<FileItemTreeId<Struct>> {
+ fn lower_struct(&mut self, strukt: &ast::Struct) -> Option<ItemTreeAstId<Struct>> {
let visibility = self.lower_visibility(strukt);
let name = strukt.name()?.as_name();
let ast_id = self.source_ast_id_map.ast_id(strukt);
let shape = adt_shape(strukt.kind());
- let res = Struct { name, visibility, shape, ast_id };
- let id = id(self.data().structs.alloc(res));
+ let res = Struct { name, visibility, shape };
+ self.tree.small_data.insert(ast_id.upcast(), SmallModItem::Struct(res));
- Some(id)
+ Some(ast_id)
}
- fn lower_union(&mut self, union: &ast::Union) -> Option<FileItemTreeId<Union>> {
+ fn lower_union(&mut self, union: &ast::Union) -> Option<ItemTreeAstId<Union>> {
let visibility = self.lower_visibility(union);
let name = union.name()?.as_name();
let ast_id = self.source_ast_id_map.ast_id(union);
- let res = Union { name, visibility, ast_id };
- let id = id(self.data().unions.alloc(res));
- Some(id)
+ let res = Union { name, visibility };
+ self.tree.small_data.insert(ast_id.upcast(), SmallModItem::Union(res));
+ Some(ast_id)
}
- fn lower_enum(&mut self, enum_: &ast::Enum) -> Option<FileItemTreeId<Enum>> {
+ fn lower_enum(&mut self, enum_: &ast::Enum) -> Option<ItemTreeAstId<Enum>> {
let visibility = self.lower_visibility(enum_);
let name = enum_.name()?.as_name();
let ast_id = self.source_ast_id_map.ast_id(enum_);
- let res = Enum { name, visibility, ast_id };
- let id = id(self.data().enums.alloc(res));
- Some(id)
+ let res = Enum { name, visibility };
+ self.tree.small_data.insert(ast_id.upcast(), SmallModItem::Enum(res));
+ Some(ast_id)
}
- fn lower_function(&mut self, func: &ast::Fn) -> Option<FileItemTreeId<Function>> {
+ fn lower_function(&mut self, func: &ast::Fn) -> Option<ItemTreeAstId<Function>> {
let visibility = self.lower_visibility(func);
let name = func.name()?.as_name();
let ast_id = self.source_ast_id_map.ast_id(func);
- let res = Function { name, visibility, ast_id };
+ let res = Function { name, visibility };
- let id = id(self.data().functions.alloc(res));
- Some(id)
+ self.tree.small_data.insert(ast_id.upcast(), SmallModItem::Function(res));
+ Some(ast_id)
}
fn lower_type_alias(
&mut self,
type_alias: &ast::TypeAlias,
- ) -> Option<FileItemTreeId<TypeAlias>> {
+ ) -> Option<ItemTreeAstId<TypeAlias>> {
let name = type_alias.name()?.as_name();
let visibility = self.lower_visibility(type_alias);
let ast_id = self.source_ast_id_map.ast_id(type_alias);
- let res = TypeAlias { name, visibility, ast_id };
- let id = id(self.data().type_aliases.alloc(res));
- Some(id)
+ let res = TypeAlias { name, visibility };
+ self.tree.small_data.insert(ast_id.upcast(), SmallModItem::TypeAlias(res));
+ Some(ast_id)
}
- fn lower_static(&mut self, static_: &ast::Static) -> Option<FileItemTreeId<Static>> {
+ fn lower_static(&mut self, static_: &ast::Static) -> Option<ItemTreeAstId<Static>> {
let name = static_.name()?.as_name();
let visibility = self.lower_visibility(static_);
let ast_id = self.source_ast_id_map.ast_id(static_);
- let res = Static { name, visibility, ast_id };
- Some(id(self.data().statics.alloc(res)))
+ let res = Static { name, visibility };
+ self.tree.small_data.insert(ast_id.upcast(), SmallModItem::Static(res));
+ Some(ast_id)
}
- fn lower_const(&mut self, konst: &ast::Const) -> FileItemTreeId<Const> {
+ fn lower_const(&mut self, konst: &ast::Const) -> ItemTreeAstId<Const> {
let name = konst.name().map(|it| it.as_name());
let visibility = self.lower_visibility(konst);
let ast_id = self.source_ast_id_map.ast_id(konst);
- let res = Const { name, visibility, ast_id };
- id(self.data().consts.alloc(res))
+ let res = Const { name, visibility };
+ self.tree.small_data.insert(ast_id.upcast(), SmallModItem::Const(res));
+ ast_id
}
- fn lower_module(&mut self, module: &ast::Module) -> Option<FileItemTreeId<Mod>> {
+ fn lower_module(&mut self, module: &ast::Module) -> Option<ItemTreeAstId<Mod>> {
let name = module.name()?.as_name();
let visibility = self.lower_visibility(module);
let kind = if module.semicolon_token().is_some() {
@@ -259,56 +251,59 @@ impl<'a> Ctx<'a> {
}
};
let ast_id = self.source_ast_id_map.ast_id(module);
- let res = Mod { name, visibility, kind, ast_id };
- Some(id(self.data().mods.alloc(res)))
+ let res = Mod { name, visibility, kind };
+ self.tree.big_data.insert(ast_id.upcast(), BigModItem::Mod(res));
+ Some(ast_id)
}
- fn lower_trait(&mut self, trait_def: &ast::Trait) -> Option<FileItemTreeId<Trait>> {
+ fn lower_trait(&mut self, trait_def: &ast::Trait) -> Option<ItemTreeAstId<Trait>> {
let name = trait_def.name()?.as_name();
let visibility = self.lower_visibility(trait_def);
let ast_id = self.source_ast_id_map.ast_id(trait_def);
- let def = Trait { name, visibility, ast_id };
- let id = id(self.data().traits.alloc(def));
- Some(id)
+ let def = Trait { name, visibility };
+ self.tree.small_data.insert(ast_id.upcast(), SmallModItem::Trait(def));
+ Some(ast_id)
}
fn lower_trait_alias(
&mut self,
trait_alias_def: &ast::TraitAlias,
- ) -> Option<FileItemTreeId<TraitAlias>> {
+ ) -> Option<ItemTreeAstId<TraitAlias>> {
let name = trait_alias_def.name()?.as_name();
let visibility = self.lower_visibility(trait_alias_def);
let ast_id = self.source_ast_id_map.ast_id(trait_alias_def);
- let alias = TraitAlias { name, visibility, ast_id };
- let id = id(self.data().trait_aliases.alloc(alias));
- Some(id)
+ let alias = TraitAlias { name, visibility };
+ self.tree.small_data.insert(ast_id.upcast(), SmallModItem::TraitAlias(alias));
+ Some(ast_id)
}
- fn lower_impl(&mut self, impl_def: &ast::Impl) -> FileItemTreeId<Impl> {
+ fn lower_impl(&mut self, impl_def: &ast::Impl) -> ItemTreeAstId<Impl> {
let ast_id = self.source_ast_id_map.ast_id(impl_def);
// Note that trait impls don't get implicit `Self` unlike traits, because here they are a
// type alias rather than a type parameter, so this is handled by the resolver.
- let res = Impl { ast_id };
- id(self.data().impls.alloc(res))
+ let res = Impl {};
+ self.tree.small_data.insert(ast_id.upcast(), SmallModItem::Impl(res));
+ ast_id
}
- fn lower_use(&mut self, use_item: &ast::Use) -> Option<FileItemTreeId<Use>> {
+ fn lower_use(&mut self, use_item: &ast::Use) -> Option<ItemTreeAstId<Use>> {
let visibility = self.lower_visibility(use_item);
let ast_id = self.source_ast_id_map.ast_id(use_item);
let (use_tree, _) = lower_use_tree(self.db, use_item.use_tree()?, &mut |range| {
self.span_map().span_for_range(range).ctx
})?;
- let res = Use { visibility, ast_id, use_tree };
- Some(id(self.data().uses.alloc(res)))
+ let res = Use { visibility, use_tree };
+ self.tree.big_data.insert(ast_id.upcast(), BigModItem::Use(res));
+ Some(ast_id)
}
fn lower_extern_crate(
&mut self,
extern_crate: &ast::ExternCrate,
- ) -> Option<FileItemTreeId<ExternCrate>> {
+ ) -> Option<ItemTreeAstId<ExternCrate>> {
let name = extern_crate.name_ref()?.as_name();
let alias = extern_crate.rename().map(|a| {
a.name().map(|it| it.as_name()).map_or(ImportAlias::Underscore, ImportAlias::Alias)
@@ -316,11 +311,12 @@ impl<'a> Ctx<'a> {
let visibility = self.lower_visibility(extern_crate);
let ast_id = self.source_ast_id_map.ast_id(extern_crate);
- let res = ExternCrate { name, alias, visibility, ast_id };
- Some(id(self.data().extern_crates.alloc(res)))
+ let res = ExternCrate { name, alias, visibility };
+ self.tree.big_data.insert(ast_id.upcast(), BigModItem::ExternCrate(res));
+ Some(ast_id)
}
- fn lower_macro_call(&mut self, m: &ast::MacroCall) -> Option<FileItemTreeId<MacroCall>> {
+ fn lower_macro_call(&mut self, m: &ast::MacroCall) -> Option<ItemTreeAstId<MacroCall>> {
let span_map = self.span_map();
let path = m.path()?;
let range = path.syntax().text_range();
@@ -329,29 +325,32 @@ impl<'a> Ctx<'a> {
})?);
let ast_id = self.source_ast_id_map.ast_id(m);
let expand_to = hir_expand::ExpandTo::from_call_site(m);
- let res = MacroCall { path, ast_id, expand_to, ctxt: span_map.span_for_range(range).ctx };
- Some(id(self.data().macro_calls.alloc(res)))
+ let res = MacroCall { path, expand_to, ctxt: span_map.span_for_range(range).ctx };
+ self.tree.small_data.insert(ast_id.upcast(), SmallModItem::MacroCall(res));
+ Some(ast_id)
}
- fn lower_macro_rules(&mut self, m: &ast::MacroRules) -> Option<FileItemTreeId<MacroRules>> {
+ fn lower_macro_rules(&mut self, m: &ast::MacroRules) -> Option<ItemTreeAstId<MacroRules>> {
let name = m.name()?;
let ast_id = self.source_ast_id_map.ast_id(m);
- let res = MacroRules { name: name.as_name(), ast_id };
- Some(id(self.data().macro_rules.alloc(res)))
+ let res = MacroRules { name: name.as_name() };
+ self.tree.small_data.insert(ast_id.upcast(), SmallModItem::MacroRules(res));
+ Some(ast_id)
}
- fn lower_macro_def(&mut self, m: &ast::MacroDef) -> Option<FileItemTreeId<Macro2>> {
+ fn lower_macro_def(&mut self, m: &ast::MacroDef) -> Option<ItemTreeAstId<Macro2>> {
let name = m.name()?;
let ast_id = self.source_ast_id_map.ast_id(m);
let visibility = self.lower_visibility(m);
- let res = Macro2 { name: name.as_name(), ast_id, visibility };
- Some(id(self.data().macro_defs.alloc(res)))
+ let res = Macro2 { name: name.as_name(), visibility };
+ self.tree.small_data.insert(ast_id.upcast(), SmallModItem::Macro2(res));
+ Some(ast_id)
}
- fn lower_extern_block(&mut self, block: &ast::ExternBlock) -> FileItemTreeId<ExternBlock> {
+ fn lower_extern_block(&mut self, block: &ast::ExternBlock) -> ItemTreeAstId<ExternBlock> {
let ast_id = self.source_ast_id_map.ast_id(block);
let children: Box<[_]> = block.extern_item_list().map_or(Box::new([]), |list| {
list.extern_items()
@@ -360,21 +359,22 @@ impl<'a> Ctx<'a> {
// (in other words, the knowledge that they're in an extern block must not be used).
// This is because an extern block can contain macros whose ItemTree's top-level items
// should be considered to be in an extern block too.
- let mod_item: ModItem = match &item {
+ let mod_item: ModItemId = match &item {
ast::ExternItem::Fn(ast) => self.lower_function(ast)?.into(),
ast::ExternItem::Static(ast) => self.lower_static(ast)?.into(),
ast::ExternItem::TypeAlias(ty) => self.lower_type_alias(ty)?.into(),
ast::ExternItem::MacroCall(call) => self.lower_macro_call(call)?.into(),
};
let attrs = RawAttrs::new(self.db, &item, self.span_map());
- self.add_attrs(mod_item.into(), attrs);
+ self.add_attrs(mod_item.ast_id(), attrs);
Some(mod_item)
})
.collect()
});
- let res = ExternBlock { ast_id, children };
- id(self.data().extern_blocks.alloc(res))
+ let res = ExternBlock { children };
+ self.tree.small_data.insert(ast_id.upcast(), SmallModItem::ExternBlock(res));
+ ast_id
}
fn lower_visibility(&mut self, item: &dyn ast::HasVisibility) -> RawVisibilityId {
@@ -425,17 +425,15 @@ impl UseTreeLowering<'_> {
}
};
+ self.mapping.alloc(tree.clone());
let list = use_tree_list
.use_trees()
.filter_map(|tree| self.lower_use_tree(tree, span_for_range))
.collect();
- Some(
- self.use_tree(
- UseTreeKind::Prefixed { prefix: prefix.map(Interned::new), list },
- tree,
- ),
- )
+ Some(UseTree {
+ kind: UseTreeKind::Prefixed { prefix: prefix.map(Interned::new), list },
+ })
} else {
let is_glob = tree.star_token().is_some();
let path = match tree.path() {
@@ -454,23 +452,20 @@ impl UseTreeLowering<'_> {
if path.is_none() {
cov_mark::hit!(glob_enum_group);
}
- Some(self.use_tree(UseTreeKind::Glob { path: path.map(Interned::new) }, tree))
+ self.mapping.alloc(tree.clone());
+ Some(UseTree { kind: UseTreeKind::Glob { path: path.map(Interned::new) } })
}
// Globs can't be renamed
(_, Some(_), true) | (None, None, false) => None,
// `bla::{ as Name}` is invalid
(None, Some(_), false) => None,
- (Some(path), alias, false) => Some(
- self.use_tree(UseTreeKind::Single { path: Interned::new(path), alias }, tree),
- ),
+ (Some(path), alias, false) => {
+ self.mapping.alloc(tree.clone());
+ Some(UseTree { kind: UseTreeKind::Single { path: Interned::new(path), alias } })
+ }
}
}
}
-
- fn use_tree(&mut self, kind: UseTreeKind, ast: ast::UseTree) -> UseTree {
- let index = self.mapping.alloc(ast);
- UseTree { index, kind }
- }
}
pub(crate) fn lower_use_tree(
diff --git a/crates/hir-def/src/item_tree/pretty.rs b/crates/hir-def/src/item_tree/pretty.rs
index 0c62b86dae..eb97081128 100644
--- a/crates/hir-def/src/item_tree/pretty.rs
+++ b/crates/hir-def/src/item_tree/pretty.rs
@@ -6,9 +6,9 @@ use span::{Edition, ErasedFileAstId};
use crate::{
item_tree::{
- AttrOwner, Const, DefDatabase, Enum, ExternBlock, ExternCrate, FieldsShape, Function, Impl,
- ItemTree, Macro2, MacroCall, MacroRules, Mod, ModItem, ModKind, RawAttrs, RawVisibilityId,
- Static, Struct, Trait, TraitAlias, TypeAlias, Union, Use, UseTree, UseTreeKind,
+ Const, DefDatabase, Enum, ExternBlock, ExternCrate, FieldsShape, Function, Impl, ItemTree,
+ Macro2, MacroCall, MacroRules, Mod, ModItemId, ModKind, RawAttrs, RawVisibilityId, Static,
+ Struct, Trait, TraitAlias, TypeAlias, Union, Use, UseTree, UseTreeKind,
},
visibility::RawVisibility,
};
@@ -17,9 +17,7 @@ pub(super) fn print_item_tree(db: &dyn DefDatabase, tree: &ItemTree, edition: Ed
let mut p =
Printer { db, tree, buf: String::new(), indent_level: 0, needs_indent: true, edition };
- if let Some(attrs) = tree.attrs.get(&AttrOwner::TopLevel) {
- p.print_attrs(attrs, true, "\n");
- }
+ p.print_attrs(&tree.top_attrs, true, "\n");
p.blank();
for item in tree.top_level_items() {
@@ -101,8 +99,8 @@ impl Printer<'_> {
}
}
- fn print_attrs_of(&mut self, of: impl Into<AttrOwner>, separated_by: &str) {
- if let Some(attrs) = self.tree.attrs.get(&of.into()) {
+ fn print_attrs_of(&mut self, of: ModItemId, separated_by: &str) {
+ if let Some(attrs) = self.tree.attrs.get(&of.ast_id()) {
self.print_attrs(attrs, false, separated_by);
}
}
@@ -159,20 +157,20 @@ impl Printer<'_> {
}
}
- fn print_mod_item(&mut self, item: ModItem) {
+ fn print_mod_item(&mut self, item: ModItemId) {
self.print_attrs_of(item, "\n");
match item {
- ModItem::Use(it) => {
- let Use { visibility, use_tree, ast_id } = &self.tree[it];
+ ModItemId::Use(ast_id) => {
+ let Use { visibility, use_tree } = &self.tree[ast_id];
self.print_ast_id(ast_id.erase());
self.print_visibility(*visibility);
w!(self, "use ");
self.print_use_tree(use_tree);
wln!(self, ";");
}
- ModItem::ExternCrate(it) => {
- let ExternCrate { name, alias, visibility, ast_id } = &self.tree[it];
+ ModItemId::ExternCrate(ast_id) => {
+ let ExternCrate { name, alias, visibility } = &self.tree[ast_id];
self.print_ast_id(ast_id.erase());
self.print_visibility(*visibility);
w!(self, "extern crate {}", name.display(self.db, self.edition));
@@ -181,8 +179,8 @@ impl Printer<'_> {
}
wln!(self, ";");
}
- ModItem::ExternBlock(it) => {
- let ExternBlock { ast_id, children } = &self.tree[it];
+ ModItemId::ExternBlock(ast_id) => {
+ let ExternBlock { children } = &self.tree[ast_id];
self.print_ast_id(ast_id.erase());
w!(self, "extern {{");
self.indented(|this| {
@@ -192,14 +190,14 @@ impl Printer<'_> {
});
wln!(self, "}}");
}
- ModItem::Function(it) => {
- let Function { name, visibility, ast_id } = &self.tree[it];
+ ModItemId::Function(ast_id) => {
+ let Function { name, visibility } = &self.tree[ast_id];
self.print_ast_id(ast_id.erase());
self.print_visibility(*visibility);
wln!(self, "fn {};", name.display(self.db, self.edition));
}
- ModItem::Struct(it) => {
- let Struct { visibility, name, shape: kind, ast_id } = &self.tree[it];
+ ModItemId::Struct(ast_id) => {
+ let Struct { visibility, name, shape: kind } = &self.tree[ast_id];
self.print_ast_id(ast_id.erase());
self.print_visibility(*visibility);
w!(self, "struct {}", name.display(self.db, self.edition));
@@ -210,22 +208,22 @@ impl Printer<'_> {
wln!(self, ";");
}
}
- ModItem::Union(it) => {
- let Union { name, visibility, ast_id } = &self.tree[it];
+ ModItemId::Union(ast_id) => {
+ let Union { name, visibility } = &self.tree[ast_id];
self.print_ast_id(ast_id.erase());
self.print_visibility(*visibility);
w!(self, "union {}", name.display(self.db, self.edition));
self.print_fields(FieldsShape::Record);
wln!(self);
}
- ModItem::Enum(it) => {
- let Enum { name, visibility, ast_id } = &self.tree[it];
+ ModItemId::Enum(ast_id) => {
+ let Enum { name, visibility } = &self.tree[ast_id];
self.print_ast_id(ast_id.erase());
self.print_visibility(*visibility);
w!(self, "enum {} {{ ... }}", name.display(self.db, self.edition));
}
- ModItem::Const(it) => {
- let Const { name, visibility, ast_id } = &self.tree[it];
+ ModItemId::Const(ast_id) => {
+ let Const { name, visibility } = &self.tree[ast_id];
self.print_ast_id(ast_id.erase());
self.print_visibility(*visibility);
w!(self, "const ");
@@ -235,8 +233,8 @@ impl Printer<'_> {
}
wln!(self, " = _;");
}
- ModItem::Static(it) => {
- let Static { name, visibility, ast_id } = &self.tree[it];
+ ModItemId::Static(ast_id) => {
+ let Static { name, visibility } = &self.tree[ast_id];
self.print_ast_id(ast_id.erase());
self.print_visibility(*visibility);
w!(self, "static ");
@@ -244,33 +242,33 @@ impl Printer<'_> {
w!(self, " = _;");
wln!(self);
}
- ModItem::Trait(it) => {
- let Trait { name, visibility, ast_id } = &self.tree[it];
+ ModItemId::Trait(ast_id) => {
+ let Trait { name, visibility } = &self.tree[ast_id];
self.print_ast_id(ast_id.erase());
self.print_visibility(*visibility);
w!(self, "trait {} {{ ... }}", name.display(self.db, self.edition));
}
- ModItem::TraitAlias(it) => {
- let TraitAlias { name, visibility, ast_id } = &self.tree[it];
+ ModItemId::TraitAlias(ast_id) => {
+ let TraitAlias { name, visibility } = &self.tree[ast_id];
self.print_ast_id(ast_id.erase());
self.print_visibility(*visibility);
wln!(self, "trait {} = ..;", name.display(self.db, self.edition));
}
- ModItem::Impl(it) => {
- let Impl { ast_id } = &self.tree[it];
+ ModItemId::Impl(ast_id) => {
+ let Impl {} = &self.tree[ast_id];
self.print_ast_id(ast_id.erase());
w!(self, "impl {{ ... }}");
}
- ModItem::TypeAlias(it) => {
- let TypeAlias { name, visibility, ast_id } = &self.tree[it];
+ ModItemId::TypeAlias(ast_id) => {
+ let TypeAlias { name, visibility } = &self.tree[ast_id];
self.print_ast_id(ast_id.erase());
self.print_visibility(*visibility);
w!(self, "type {}", name.display(self.db, self.edition));
w!(self, ";");
wln!(self);
}
- ModItem::Mod(it) => {
- let Mod { name, visibility, kind, ast_id } = &self.tree[it];
+ ModItemId::Mod(ast_id) => {
+ let Mod { name, visibility, kind } = &self.tree[ast_id];
self.print_ast_id(ast_id.erase());
self.print_visibility(*visibility);
w!(self, "mod {}", name.display(self.db, self.edition));
@@ -289,8 +287,8 @@ impl Printer<'_> {
}
}
}
- ModItem::MacroCall(it) => {
- let MacroCall { path, ast_id, expand_to, ctxt } = &self.tree[it];
+ ModItemId::MacroCall(ast_id) => {
+ let MacroCall { path, expand_to, ctxt } = &self.tree[ast_id];
let _ = writeln!(
self,
"// AstId: {:#?}, SyntaxContextId: {}, ExpandTo: {:?}",
@@ -300,13 +298,13 @@ impl Printer<'_> {
);
wln!(self, "{}!(...);", path.display(self.db, self.edition));
}
- ModItem::MacroRules(it) => {
- let MacroRules { name, ast_id } = &self.tree[it];
+ ModItemId::MacroRules(ast_id) => {
+ let MacroRules { name } = &self.tree[ast_id];
self.print_ast_id(ast_id.erase());
wln!(self, "macro_rules! {} {{ ... }}", name.display(self.db, self.edition));
}
- ModItem::Macro2(it) => {
- let Macro2 { name, visibility, ast_id } = &self.tree[it];
+ ModItemId::Macro2(ast_id) => {
+ let Macro2 { name, visibility } = &self.tree[ast_id];
self.print_ast_id(ast_id.erase());
self.print_visibility(*visibility);
wln!(self, "macro {} {{ ... }}", name.display(self.db, self.edition));
diff --git a/crates/hir-def/src/nameres.rs b/crates/hir-def/src/nameres.rs
index c908e45754..610bb6b00b 100644
--- a/crates/hir-def/src/nameres.rs
+++ b/crates/hir-def/src/nameres.rs
@@ -80,7 +80,7 @@ use crate::{
LocalModuleId, Lookup, MacroExpander, MacroId, ModuleId, ProcMacroId, UseId,
db::DefDatabase,
item_scope::{BuiltinShadowMode, ItemScope},
- item_tree::{ItemTreeId, Mod, TreeId},
+ item_tree::TreeId,
nameres::{diagnostics::DefDiagnostic, path_resolution::ResolveMode},
per_ns::PerNs,
visibility::{Visibility, VisibilityExplicitness},
@@ -289,11 +289,11 @@ pub enum ModuleOrigin {
File {
is_mod_rs: bool,
declaration: FileAstId<ast::Module>,
- declaration_tree_id: ItemTreeId<Mod>,
+ declaration_tree_id: TreeId,
definition: EditionedFileId,
},
Inline {
- definition_tree_id: ItemTreeId<Mod>,
+ definition_tree_id: TreeId,
definition: FileAstId<ast::Module>,
},
/// Pseudo-module introduced by a block scope (contains only inner items).
diff --git a/crates/hir-def/src/nameres/collector.rs b/crates/hir-def/src/nameres/collector.rs
index 34a129a88e..29f94ac2dc 100644
--- a/crates/hir-def/src/nameres/collector.rs
+++ b/crates/hir-def/src/nameres/collector.rs
@@ -35,8 +35,8 @@ use crate::{
db::DefDatabase,
item_scope::{GlobId, ImportId, ImportOrExternCrate, PerNsGlobImports},
item_tree::{
- self, FieldsShape, FileItemTreeId, ImportAlias, ImportKind, ItemTree, ItemTreeId,
- ItemTreeNode, Macro2, MacroCall, MacroRules, Mod, ModItem, ModKind, TreeId, UseTreeKind,
+ self, FieldsShape, ImportAlias, ImportKind, ItemTree, ItemTreeAstId, Macro2, MacroCall,
+ MacroRules, Mod, ModItemId, ModKind, TreeId,
},
macro_call_as_call_id,
nameres::{
@@ -140,7 +140,6 @@ struct ImportSource {
id: UseId,
is_prelude: bool,
kind: ImportKind,
- item_tree_id: ItemTreeId<item_tree::Use>,
}
#[derive(Debug, Eq, PartialEq)]
@@ -154,19 +153,19 @@ struct Import {
impl Import {
fn from_use(
tree: &ItemTree,
- item_tree_id: ItemTreeId<item_tree::Use>,
+ item: FileAstId<ast::Use>,
id: UseId,
is_prelude: bool,
mut cb: impl FnMut(Self),
) {
- let it = &tree[item_tree_id.value];
+ let it = &tree[item];
let visibility = &tree[it.visibility];
- it.use_tree.expand(|idx, path, kind, alias| {
+ it.expand(|idx, path, kind, alias| {
cb(Self {
path,
alias,
visibility: visibility.clone(),
- source: ImportSource { use_tree: idx, id, is_prelude, kind, item_tree_id },
+ source: ImportSource { use_tree: idx, id, is_prelude, kind },
});
});
}
@@ -181,15 +180,15 @@ struct ImportDirective {
}
#[derive(Clone, Debug, Eq, PartialEq)]
-struct MacroDirective {
+struct MacroDirective<'db> {
module_id: LocalModuleId,
depth: usize,
- kind: MacroDirectiveKind,
+ kind: MacroDirectiveKind<'db>,
container: ItemContainerId,
}
#[derive(Clone, Debug, Eq, PartialEq)]
-enum MacroDirectiveKind {
+enum MacroDirectiveKind<'db> {
FnLike {
ast_id: AstIdWithPath<ast::MacroCall>,
expand_to: ExpandTo,
@@ -206,30 +205,31 @@ enum MacroDirectiveKind {
Attr {
ast_id: AstIdWithPath<ast::Item>,
attr: Attr,
- mod_item: ModItem,
+ mod_item: ModItemId,
/* is this needed? */ tree: TreeId,
+ item_tree: &'db ItemTree,
},
}
/// Walks the tree of module recursively
-struct DefCollector<'a> {
- db: &'a dyn DefDatabase,
+struct DefCollector<'db> {
+ db: &'db dyn DefDatabase,
def_map: DefMap,
local_def_map: LocalDefMap,
/// Set only in case of blocks.
- crate_local_def_map: Option<&'a LocalDefMap>,
+ crate_local_def_map: Option<&'db LocalDefMap>,
// The dependencies of the current crate, including optional deps like `test`.
deps: FxHashMap<Name, BuiltDependency>,
glob_imports: FxHashMap<LocalModuleId, Vec<(LocalModuleId, Visibility, GlobId)>>,
unresolved_imports: Vec<ImportDirective>,
indeterminate_imports: Vec<(ImportDirective, PerNs)>,
- unresolved_macros: Vec<MacroDirective>,
+ unresolved_macros: Vec<MacroDirective<'db>>,
// We'd like to avoid emitting a diagnostics avalanche when some `extern crate` doesn't
// resolve. When we emit diagnostics for unresolved imports, we only do so if the import
// doesn't start with an unresolved crate's name.
unresolved_extern_crates: FxHashSet<Name>,
mod_dirs: FxHashMap<LocalModuleId, ModDir>,
- cfg_options: &'a CfgOptions,
+ cfg_options: &'db CfgOptions,
/// List of procedural macros defined by this crate. This is read from the dynamic library
/// built by the build system, and is the list of proc-macros we can actually expand. It is
/// empty when proc-macro support is disabled (in which case we still do name resolution for
@@ -244,10 +244,10 @@ struct DefCollector<'a> {
/// This also stores the attributes to skip when we resolve derive helpers and non-macro
/// non-builtin attributes in general.
// FIXME: There has to be a better way to do this
- skip_attrs: FxHashMap<InFile<ModItem>, AttrId>,
+ skip_attrs: FxHashMap<InFile<FileAstId<ast::Item>>, AttrId>,
}
-impl DefCollector<'_> {
+impl<'db> DefCollector<'db> {
fn seed_with_top_level(&mut self) {
let _p = tracing::info_span!("seed_with_top_level").entered();
@@ -355,7 +355,7 @@ impl DefCollector<'_> {
macro_depth: 0,
module_id: DefMap::ROOT,
tree_id: TreeId::new(file_id.into(), None),
- item_tree: &item_tree,
+ item_tree,
mod_dir: ModDir::root(),
}
.collect_in_top_module(item_tree.top_level_items());
@@ -376,7 +376,7 @@ impl DefCollector<'_> {
macro_depth: 0,
module_id: DefMap::ROOT,
tree_id,
- item_tree: &item_tree,
+ item_tree,
mod_dir: ModDir::root(),
}
.collect_in_top_module(item_tree.top_level_items());
@@ -459,7 +459,7 @@ impl DefCollector<'_> {
self.unresolved_macros.iter().enumerate().find_map(|(idx, directive)| match &directive
.kind
{
- MacroDirectiveKind::Attr { ast_id, mod_item, attr, tree } => {
+ MacroDirectiveKind::Attr { ast_id, mod_item, attr, tree, item_tree } => {
self.def_map.diagnostics.push(DefDiagnostic::unresolved_macro_call(
directive.module_id,
MacroCallKind::Attr {
@@ -470,16 +470,22 @@ impl DefCollector<'_> {
attr.path().clone(),
));
- self.skip_attrs.insert(ast_id.ast_id.with_value(*mod_item), attr.id);
+ self.skip_attrs.insert(ast_id.ast_id.with_value(mod_item.ast_id()), attr.id);
- Some((idx, directive, *mod_item, *tree))
+ Some((idx, directive, *mod_item, *tree, *item_tree))
}
_ => None,
});
match unresolved_attr {
- Some((pos, &MacroDirective { module_id, depth, container, .. }, mod_item, tree_id)) => {
- let item_tree = &tree_id.item_tree(self.db);
+ Some((
+ pos,
+ &MacroDirective { module_id, depth, container, .. },
+ mod_item,
+ tree_id,
+ item_tree,
+ )) => {
+ // FIXME: Remove this clone
let mod_dir = self.mod_dirs[&module_id].clone();
ModCollector {
def_collector: self,
@@ -860,7 +866,6 @@ impl DefCollector<'_> {
kind: kind @ (ImportKind::Plain | ImportKind::TypeOnly),
id,
use_tree,
- item_tree_id,
..
} => {
let name = match &import.alias {
@@ -893,13 +898,11 @@ impl DefCollector<'_> {
let Some(ImportOrExternCrate::ExternCrate(_)) = def.import else {
return false;
};
- let item_tree = item_tree_id.item_tree(self.db);
- let use_kind = item_tree[item_tree_id.value].use_tree.kind();
- let UseTreeKind::Single { path, .. } = use_kind else {
+ if kind == ImportKind::Glob {
return false;
- };
- matches!(path.kind, PathKind::Plain | PathKind::SELF)
- && path.segments().len() < 2
+ }
+ matches!(import.path.kind, PathKind::Plain | PathKind::SELF)
+ && import.path.segments().len() < 2
};
if is_extern_crate_reimport_without_prefix() {
def.vis = vis;
@@ -1253,7 +1256,7 @@ impl DefCollector<'_> {
fn resolve_macros(&mut self) -> ReachedFixedPoint {
let mut macros = mem::take(&mut self.unresolved_macros);
let mut resolved = Vec::new();
- let mut push_resolved = |directive: &MacroDirective, call_id| {
+ let mut push_resolved = |directive: &MacroDirective<'_>, call_id| {
resolved.push((directive.module_id, directive.depth, directive.container, call_id));
};
@@ -1266,7 +1269,7 @@ impl DefCollector<'_> {
let mut eager_callback_buffer = vec![];
let mut res = ReachedFixedPoint::Yes;
// Retain unresolved macros after this round of resolution.
- let mut retain = |directive: &MacroDirective| {
+ let mut retain = |directive: &MacroDirective<'db>| {
let subns = match &directive.kind {
MacroDirectiveKind::FnLike { .. } => MacroSubNs::Bang,
MacroDirectiveKind::Attr { .. } | MacroDirectiveKind::Derive { .. } => {
@@ -1361,22 +1364,29 @@ impl DefCollector<'_> {
return Resolved::Yes;
}
}
- MacroDirectiveKind::Attr { ast_id: file_ast_id, mod_item, attr, tree } => {
+ MacroDirectiveKind::Attr {
+ ast_id: file_ast_id,
+ mod_item,
+ attr,
+ tree,
+ item_tree,
+ } => {
let &AstIdWithPath { ast_id, ref path } = file_ast_id;
let file_id = ast_id.file_id;
let mut recollect_without = |collector: &mut Self| {
// Remove the original directive since we resolved it.
let mod_dir = collector.mod_dirs[&directive.module_id].clone();
- collector.skip_attrs.insert(InFile::new(file_id, *mod_item), attr.id);
+ collector
+ .skip_attrs
+ .insert(InFile::new(file_id, mod_item.ast_id()), attr.id);
- let item_tree = tree.item_tree(self.db);
ModCollector {
def_collector: collector,
macro_depth: directive.depth,
module_id: directive.module_id,
tree_id: *tree,
- item_tree: &item_tree,
+ item_tree,
mod_dir,
}
.collect(&[*mod_item], directive.container);
@@ -1429,11 +1439,10 @@ impl DefCollector<'_> {
// normal (as that would just be an identity expansion with extra output)
// Instead we treat derive attributes special and apply them separately.
- let item_tree = tree.item_tree(self.db);
let ast_adt_id: FileAstId<ast::Adt> = match *mod_item {
- ModItem::Struct(strukt) => item_tree[strukt].ast_id().upcast(),
- ModItem::Union(union) => item_tree[union].ast_id().upcast(),
- ModItem::Enum(enum_) => item_tree[enum_].ast_id().upcast(),
+ ModItemId::Struct(ast_id) => ast_id.upcast(),
+ ModItemId::Union(ast_id) => ast_id.upcast(),
+ ModItemId::Enum(ast_id) => ast_id.upcast(),
_ => {
let diag = DefDiagnostic::invalid_derive_target(
directive.module_id,
@@ -1565,7 +1574,7 @@ impl DefCollector<'_> {
macro_depth: depth,
tree_id: TreeId::new(file_id, None),
module_id,
- item_tree: &item_tree,
+ item_tree,
mod_dir,
}
.collect(item_tree.top_level_items(), container);
@@ -1642,8 +1651,7 @@ impl DefCollector<'_> {
import:
Import {
ref path,
- source:
- ImportSource { use_tree, id, is_prelude: _, kind: _, item_tree_id: _ },
+ source: ImportSource { use_tree, id, is_prelude: _, kind: _ },
..
},
..
@@ -1667,22 +1675,22 @@ impl DefCollector<'_> {
}
/// Walks a single module, populating defs, imports and macros
-struct ModCollector<'a, 'b> {
- def_collector: &'a mut DefCollector<'b>,
+struct ModCollector<'a, 'db> {
+ def_collector: &'a mut DefCollector<'db>,
macro_depth: usize,
module_id: LocalModuleId,
tree_id: TreeId,
- item_tree: &'a ItemTree,
+ item_tree: &'db ItemTree,
mod_dir: ModDir,
}
impl ModCollector<'_, '_> {
- fn collect_in_top_module(&mut self, items: &[ModItem]) {
+ fn collect_in_top_module(&mut self, items: &[ModItemId]) {
let module = self.def_collector.def_map.module_id(self.module_id);
self.collect(items, module.into())
}
- fn collect(&mut self, items: &[ModItem], container: ItemContainerId) {
+ fn collect(&mut self, items: &[ModItemId], container: ItemContainerId) {
let krate = self.def_collector.def_map.krate;
let is_crate_root =
self.module_id == DefMap::ROOT && self.def_collector.def_map.block.is_none();
@@ -1721,29 +1729,11 @@ impl ModCollector<'_, '_> {
.unwrap_or(Visibility::Public)
};
- let mut process_mod_item = |item: ModItem| {
- let attrs = self.item_tree.attrs(db, krate, item.into());
+ let mut process_mod_item = |item: ModItemId| {
+ let attrs = self.item_tree.attrs(db, krate, item.ast_id());
if let Some(cfg) = attrs.cfg() {
if !self.is_cfg_enabled(&cfg) {
- let ast_id = match item {
- ModItem::Use(it) => self.item_tree[it].ast_id.erase(),
- ModItem::ExternCrate(it) => self.item_tree[it].ast_id.erase(),
- ModItem::ExternBlock(it) => self.item_tree[it].ast_id.erase(),
- ModItem::Function(it) => self.item_tree[it].ast_id.erase(),
- ModItem::Struct(it) => self.item_tree[it].ast_id.erase(),
- ModItem::Union(it) => self.item_tree[it].ast_id.erase(),
- ModItem::Enum(it) => self.item_tree[it].ast_id.erase(),
- ModItem::Const(it) => self.item_tree[it].ast_id.erase(),
- ModItem::Static(it) => self.item_tree[it].ast_id.erase(),
- ModItem::Trait(it) => self.item_tree[it].ast_id.erase(),
- ModItem::TraitAlias(it) => self.item_tree[it].ast_id.erase(),
- ModItem::Impl(it) => self.item_tree[it].ast_id.erase(),
- ModItem::TypeAlias(it) => self.item_tree[it].ast_id.erase(),
- ModItem::Mod(it) => self.item_tree[it].ast_id.erase(),
- ModItem::MacroCall(it) => self.item_tree[it].ast_id.erase(),
- ModItem::MacroRules(it) => self.item_tree[it].ast_id.erase(),
- ModItem::Macro2(it) => self.item_tree[it].ast_id.erase(),
- };
+ let ast_id = item.ast_id().erase();
self.emit_unconfigured_diagnostic(InFile::new(self.file_id(), ast_id), &cfg);
return;
}
@@ -1761,35 +1751,27 @@ impl ModCollector<'_, '_> {
self.def_collector.crate_local_def_map.unwrap_or(&self.def_collector.local_def_map);
match item {
- ModItem::Mod(m) => self.collect_module(m, &attrs),
- ModItem::Use(item_tree_id) => {
- let id = UseLoc {
- container: module,
- id: InFile::new(self.file_id(), self.item_tree[item_tree_id].ast_id),
- }
- .intern(db);
+ ModItemId::Mod(m) => self.collect_module(m, &attrs),
+ ModItemId::Use(item_tree_id) => {
+ let id =
+ UseLoc { container: module, id: InFile::new(self.file_id(), item_tree_id) }
+ .intern(db);
let is_prelude = attrs.by_key(sym::prelude_import).exists();
- Import::from_use(
- self.item_tree,
- ItemTreeId::new(self.tree_id, item_tree_id),
- id,
- is_prelude,
- |import| {
- self.def_collector.unresolved_imports.push(ImportDirective {
- module_id: self.module_id,
- import,
- status: PartialResolvedImport::Unresolved,
- });
- },
- )
+ Import::from_use(self.item_tree, item_tree_id, id, is_prelude, |import| {
+ self.def_collector.unresolved_imports.push(ImportDirective {
+ module_id: self.module_id,
+ import,
+ status: PartialResolvedImport::Unresolved,
+ });
+ })
}
- ModItem::ExternCrate(item_tree_id) => {
- let item_tree::ExternCrate { name, visibility, alias, ast_id } =
+ ModItemId::ExternCrate(item_tree_id) => {
+ let item_tree::ExternCrate { name, visibility, alias } =
&self.item_tree[item_tree_id];
let id = ExternCrateLoc {
container: module,
- id: InFile::new(self.tree_id.file_id(), *ast_id),
+ id: InFile::new(self.tree_id.file_id(), item_tree_id),
}
.intern(db);
def_map.modules[self.module_id].scope.define_extern_crate_decl(id);
@@ -1852,15 +1834,15 @@ impl ModCollector<'_, '_> {
self.def_collector.def_map.diagnostics.push(
DefDiagnostic::unresolved_extern_crate(
module_id,
- InFile::new(self.file_id(), *ast_id),
+ InFile::new(self.file_id(), item_tree_id),
),
);
}
}
- ModItem::ExternBlock(block) => {
+ ModItemId::ExternBlock(block) => {
let extern_block_id = ExternBlockLoc {
container: module,
- id: InFile::new(self.file_id(), self.item_tree[block].ast_id),
+ id: InFile::new(self.file_id(), block),
}
.intern(db);
self.def_collector.def_map.modules[self.module_id]
@@ -1871,24 +1853,20 @@ impl ModCollector<'_, '_> {
ItemContainerId::ExternBlockId(extern_block_id),
)
}
- ModItem::MacroCall(mac) => self.collect_macro_call(&self.item_tree[mac], container),
- ModItem::MacroRules(id) => self.collect_macro_rules(id, module),
- ModItem::Macro2(id) => self.collect_macro_def(id, module),
- ModItem::Impl(imp) => {
- let impl_id = ImplLoc {
- container: module,
- id: InFile::new(self.file_id(), self.item_tree[imp].ast_id),
- }
- .intern(db);
+ ModItemId::MacroCall(mac) => self.collect_macro_call(mac, container),
+ ModItemId::MacroRules(id) => self.collect_macro_rules(id, module),
+ ModItemId::Macro2(id) => self.collect_macro_def(id, module),
+ ModItemId::Impl(imp) => {
+ let impl_id =
+ ImplLoc { container: module, id: InFile::new(self.file_id(), imp) }
+ .intern(db);
self.def_collector.def_map.modules[self.module_id].scope.define_impl(impl_id)
}
- ModItem::Function(id) => {
+ ModItemId::Function(id) => {
let it = &self.item_tree[id];
- let fn_id = FunctionLoc {
- container,
- id: InFile::new(self.tree_id.file_id(), it.ast_id),
- }
- .intern(db);
+ let fn_id =
+ FunctionLoc { container, id: InFile::new(self.tree_id.file_id(), id) }
+ .intern(db);
let vis = resolve_vis(def_map, local_def_map, &self.item_tree[it.visibility]);
@@ -1899,7 +1877,7 @@ impl ModCollector<'_, '_> {
if let Some(proc_macro) = attrs.parse_proc_macro_decl(&it.name) {
self.def_collector.export_proc_macro(
proc_macro,
- InFile::new(self.file_id(), self.item_tree[id].ast_id()),
+ InFile::new(self.file_id(), id),
fn_id,
);
}
@@ -1907,13 +1885,13 @@ impl ModCollector<'_, '_> {
update_def(self.def_collector, fn_id.into(), &it.name, vis, false);
}
- ModItem::Struct(id) => {
+ ModItemId::Struct(id) => {
let it = &self.item_tree[id];
let vis = resolve_vis(def_map, local_def_map, &self.item_tree[it.visibility]);
update_def(
self.def_collector,
- StructLoc { container: module, id: InFile::new(self.file_id(), it.ast_id) }
+ StructLoc { container: module, id: InFile::new(self.file_id(), id) }
.intern(db)
.into(),
&it.name,
@@ -1921,13 +1899,13 @@ impl ModCollector<'_, '_> {
!matches!(it.shape, FieldsShape::Record),
);
}
- ModItem::Union(id) => {
+ ModItemId::Union(id) => {
let it = &self.item_tree[id];
let vis = resolve_vis(def_map, local_def_map, &self.item_tree[it.visibility]);
update_def(
self.def_collector,
- UnionLoc { container: module, id: InFile::new(self.file_id(), it.ast_id) }
+ UnionLoc { container: module, id: InFile::new(self.file_id(), id) }
.intern(db)
.into(),
&it.name,
@@ -1935,21 +1913,19 @@ impl ModCollector<'_, '_> {
false,
);
}
- ModItem::Enum(id) => {
+ ModItemId::Enum(id) => {
let it = &self.item_tree[id];
- let enum_ = EnumLoc {
- container: module,
- id: InFile::new(self.tree_id.file_id(), it.ast_id),
- }
- .intern(db);
+ let enum_ =
+ EnumLoc { container: module, id: InFile::new(self.tree_id.file_id(), id) }
+ .intern(db);
let vis = resolve_vis(def_map, local_def_map, &self.item_tree[it.visibility]);
update_def(self.def_collector, enum_.into(), &it.name, vis, false);
}
- ModItem::Const(id) => {
+ ModItemId::Const(id) => {
let it = &self.item_tree[id];
let const_id =
- ConstLoc { container, id: InFile::new(self.tree_id.file_id(), it.ast_id) }
+ ConstLoc { container, id: InFile::new(self.tree_id.file_id(), id) }
.intern(db);
match &it.name {
@@ -1966,13 +1942,13 @@ impl ModCollector<'_, '_> {
}
}
}
- ModItem::Static(id) => {
+ ModItemId::Static(id) => {
let it = &self.item_tree[id];
let vis = resolve_vis(def_map, local_def_map, &self.item_tree[it.visibility]);
update_def(
self.def_collector,
- StaticLoc { container, id: InFile::new(self.file_id(), it.ast_id) }
+ StaticLoc { container, id: InFile::new(self.file_id(), id) }
.intern(db)
.into(),
&it.name,
@@ -1980,13 +1956,13 @@ impl ModCollector<'_, '_> {
false,
);
}
- ModItem::Trait(id) => {
+ ModItemId::Trait(id) => {
let it = &self.item_tree[id];
let vis = resolve_vis(def_map, local_def_map, &self.item_tree[it.visibility]);
update_def(
self.def_collector,
- TraitLoc { container: module, id: InFile::new(self.file_id(), it.ast_id) }
+ TraitLoc { container: module, id: InFile::new(self.file_id(), id) }
.intern(db)
.into(),
&it.name,
@@ -1994,30 +1970,27 @@ impl ModCollector<'_, '_> {
false,
);
}
- ModItem::TraitAlias(id) => {
+ ModItemId::TraitAlias(id) => {
let it = &self.item_tree[id];
let vis = resolve_vis(def_map, local_def_map, &self.item_tree[it.visibility]);
update_def(
self.def_collector,
- TraitAliasLoc {
- container: module,
- id: InFile::new(self.file_id(), it.ast_id),
- }
- .intern(db)
- .into(),
+ TraitAliasLoc { container: module, id: InFile::new(self.file_id(), id) }
+ .intern(db)
+ .into(),
&it.name,
vis,
false,
);
}
- ModItem::TypeAlias(id) => {
+ ModItemId::TypeAlias(id) => {
let it = &self.item_tree[id];
let vis = resolve_vis(def_map, local_def_map, &self.item_tree[it.visibility]);
update_def(
self.def_collector,
- TypeAliasLoc { container, id: InFile::new(self.file_id(), it.ast_id) }
+ TypeAliasLoc { container, id: InFile::new(self.file_id(), id) }
.intern(db)
.into(),
&it.name,
@@ -2034,12 +2007,12 @@ impl ModCollector<'_, '_> {
if is_crate_root {
items
.iter()
- .filter(|it| matches!(it, ModItem::ExternCrate(..)))
+ .filter(|it| matches!(it, ModItemId::ExternCrate(..)))
.copied()
.for_each(&mut process_mod_item);
items
.iter()
- .filter(|it| !matches!(it, ModItem::ExternCrate(..)))
+ .filter(|it| !matches!(it, ModItemId::ExternCrate(..)))
.copied()
.for_each(process_mod_item);
} else {
@@ -2080,19 +2053,18 @@ impl ModCollector<'_, '_> {
);
}
- fn collect_module(&mut self, module_id: FileItemTreeId<Mod>, attrs: &Attrs) {
+ fn collect_module(&mut self, module_ast_id: ItemTreeAstId<Mod>, attrs: &Attrs) {
let path_attr = attrs.by_key(sym::path).string_value_unescape();
let is_macro_use = attrs.by_key(sym::macro_use).exists();
- let module = &self.item_tree[module_id];
+ let module = &self.item_tree[module_ast_id];
match &module.kind {
// inline module, just recurse
ModKind::Inline { items } => {
let module_id = self.push_child_module(
module.name.clone(),
- module.ast_id,
+ module_ast_id,
None,
&self.item_tree[module.visibility],
- module_id,
);
let Some(mod_dir) =
@@ -2115,7 +2087,7 @@ impl ModCollector<'_, '_> {
}
// out of line module, resolve, parse and recurse
ModKind::Outline => {
- let ast_id = AstId::new(self.file_id(), module.ast_id);
+ let ast_id = AstId::new(self.file_id(), module_ast_id);
let db = self.def_collector.db;
match self.mod_dir.resolve_declaration(
db,
@@ -2134,10 +2106,7 @@ impl ModCollector<'_, '_> {
match is_enabled {
Err(cfg) => {
self.emit_unconfigured_diagnostic(
- InFile::new(
- self.file_id(),
- self.item_tree[module_id].ast_id.erase(),
- ),
+ InFile::new(self.file_id(), module_ast_id.erase()),
&cfg,
);
}
@@ -2147,14 +2116,13 @@ impl ModCollector<'_, '_> {
ast_id.value,
Some((file_id, is_mod_rs)),
&self.item_tree[module.visibility],
- module_id,
);
ModCollector {
def_collector: self.def_collector,
macro_depth: self.macro_depth,
module_id,
tree_id: TreeId::new(file_id.into(), None),
- item_tree: &item_tree,
+ item_tree,
mod_dir,
}
.collect_in_top_module(item_tree.top_level_items());
@@ -2175,7 +2143,6 @@ impl ModCollector<'_, '_> {
ast_id.value,
None,
&self.item_tree[module.visibility],
- module_id,
);
self.def_collector.def_map.diagnostics.push(
DefDiagnostic::unresolved_module(self.module_id, ast_id, candidates),
@@ -2192,7 +2159,6 @@ impl ModCollector<'_, '_> {
declaration: FileAstId<ast::Module>,
definition: Option<(EditionedFileId, bool)>,
visibility: &crate::visibility::RawVisibility,
- mod_tree_id: FileItemTreeId<Mod>,
) -> LocalModuleId {
let def_map = &mut self.def_collector.def_map;
let vis = def_map
@@ -2205,15 +2171,14 @@ impl ModCollector<'_, '_> {
)
.unwrap_or(Visibility::Public);
let origin = match definition {
- None => ModuleOrigin::Inline {
- definition: declaration,
- definition_tree_id: ItemTreeId::new(self.tree_id, mod_tree_id),
- },
+ None => {
+ ModuleOrigin::Inline { definition: declaration, definition_tree_id: self.tree_id }
+ }
Some((definition, is_mod_rs)) => ModuleOrigin::File {
declaration,
definition,
is_mod_rs,
- declaration_tree_id: ItemTreeId::new(self.tree_id, mod_tree_id),
+ declaration_tree_id: self.tree_id,
},
};
@@ -2254,11 +2219,14 @@ impl ModCollector<'_, '_> {
fn resolve_attributes(
&mut self,
attrs: &Attrs,
- mod_item: ModItem,
+ mod_item: ModItemId,
container: ItemContainerId,
) -> Result<(), ()> {
- let mut ignore_up_to =
- self.def_collector.skip_attrs.get(&InFile::new(self.file_id(), mod_item)).copied();
+ let mut ignore_up_to = self
+ .def_collector
+ .skip_attrs
+ .get(&InFile::new(self.file_id(), mod_item.ast_id()))
+ .copied();
let iter = attrs
.iter()
.dedup_by(|a, b| {
@@ -2288,11 +2256,7 @@ impl ModCollector<'_, '_> {
attr.path.display(self.def_collector.db, Edition::LATEST)
);
- let ast_id = AstIdWithPath::new(
- self.file_id(),
- mod_item.ast_id(self.item_tree),
- attr.path.clone(),
- );
+ let ast_id = AstIdWithPath::new(self.file_id(), mod_item.ast_id(), attr.path.clone());
self.def_collector.unresolved_macros.push(MacroDirective {
module_id: self.module_id,
depth: self.macro_depth + 1,
@@ -2301,6 +2265,7 @@ impl ModCollector<'_, '_> {
attr: attr.clone(),
mod_item,
tree: self.tree_id,
+ item_tree: self.item_tree,
},
container,
});
@@ -2311,11 +2276,11 @@ impl ModCollector<'_, '_> {
Ok(())
}
- fn collect_macro_rules(&mut self, id: FileItemTreeId<MacroRules>, module: ModuleId) {
+ fn collect_macro_rules(&mut self, ast_id: ItemTreeAstId<MacroRules>, module: ModuleId) {
let krate = self.def_collector.def_map.krate;
- let mac = &self.item_tree[id];
- let attrs = self.item_tree.attrs(self.def_collector.db, krate, ModItem::from(id).into());
- let ast_id = InFile::new(self.file_id(), mac.ast_id.upcast());
+ let mac = &self.item_tree[ast_id];
+ let attrs = self.item_tree.attrs(self.def_collector.db, krate, ast_id.upcast());
+ let f_ast_id = InFile::new(self.file_id(), ast_id.upcast());
let export_attr = || attrs.by_key(sym::macro_export);
@@ -2362,7 +2327,7 @@ impl ModCollector<'_, '_> {
self.def_collector
.def_map
.diagnostics
- .push(DefDiagnostic::unimplemented_builtin_macro(self.module_id, ast_id));
+ .push(DefDiagnostic::unimplemented_builtin_macro(self.module_id, f_ast_id));
return;
}
}
@@ -2378,16 +2343,13 @@ impl ModCollector<'_, '_> {
let macro_id = MacroRulesLoc {
container: module,
- id: InFile::new(self.file_id(), mac.ast_id),
+ id: InFile::new(self.file_id(), ast_id),
flags,
expander,
edition: self.def_collector.def_map.data.edition,
}
.intern(self.def_collector.db);
- self.def_collector.def_map.macro_def_to_macro_id.insert(
- InFile::new(self.file_id(), self.item_tree[id].ast_id()).erase(),
- macro_id.into(),
- );
+ self.def_collector.def_map.macro_def_to_macro_id.insert(f_ast_id.erase(), macro_id.into());
self.def_collector.define_macro_rules(
self.module_id,
mac.name.clone(),
@@ -2396,14 +2358,14 @@ impl ModCollector<'_, '_> {
);
}
- fn collect_macro_def(&mut self, id: FileItemTreeId<Macro2>, module: ModuleId) {
+ fn collect_macro_def(&mut self, ast_id: ItemTreeAstId<Macro2>, module: ModuleId) {
let krate = self.def_collector.def_map.krate;
- let mac = &self.item_tree[id];
- let ast_id = InFile::new(self.file_id(), mac.ast_id.upcast());
+ let mac = &self.item_tree[ast_id];
+ let attrs = self.item_tree.attrs(self.def_collector.db, krate, ast_id.upcast());
+ let f_ast_id = InFile::new(self.file_id(), ast_id.upcast());
// Case 1: builtin macros
let mut helpers_opt = None;
- let attrs = self.item_tree.attrs(self.def_collector.db, krate, ModItem::from(id).into());
let expander = if attrs.by_key(sym::rustc_builtin_macro).exists() {
if let Some(expander) = find_builtin_macro(&mac.name) {
match expander {
@@ -2435,7 +2397,7 @@ impl ModCollector<'_, '_> {
self.def_collector
.def_map
.diagnostics
- .push(DefDiagnostic::unimplemented_builtin_macro(self.module_id, ast_id));
+ .push(DefDiagnostic::unimplemented_builtin_macro(self.module_id, f_ast_id));
return;
}
} else {
@@ -2446,16 +2408,13 @@ impl ModCollector<'_, '_> {
let macro_id = Macro2Loc {
container: module,
- id: InFile::new(self.file_id(), mac.ast_id),
+ id: InFile::new(self.file_id(), ast_id),
expander,
allow_internal_unsafe,
edition: self.def_collector.def_map.data.edition,
}
.intern(self.def_collector.db);
- self.def_collector.def_map.macro_def_to_macro_id.insert(
- InFile::new(self.file_id(), self.item_tree[id].ast_id()).erase(),
- macro_id.into(),
- );
+ self.def_collector.def_map.macro_def_to_macro_id.insert(f_ast_id.erase(), macro_id.into());
self.def_collector.define_macro_def(
self.module_id,
mac.name.clone(),
@@ -2474,9 +2433,10 @@ impl ModCollector<'_, '_> {
fn collect_macro_call(
&mut self,
- &MacroCall { ref path, ast_id, expand_to, ctxt }: &MacroCall,
+ ast_id: FileAstId<ast::MacroCall>,
container: ItemContainerId,
) {
+ let &MacroCall { ref path, expand_to, ctxt } = &self.item_tree[ast_id];
let ast_id = AstIdWithPath::new(self.file_id(), ast_id, path.clone());
let db = self.def_collector.db;
diff --git a/crates/hir-def/src/nameres/tests/incremental.rs b/crates/hir-def/src/nameres/tests/incremental.rs
index 948e8bed66..7a4ea62f12 100644
--- a/crates/hir-def/src/nameres/tests/incremental.rs
+++ b/crates/hir-def/src/nameres/tests/incremental.rs
@@ -348,7 +348,7 @@ m!(Z);
assert_eq!(module_data.scope.resolutions().count(), 4);
});
let n_recalculated_item_trees =
- events.iter().filter(|it| it.contains("file_item_tree_shim")).count();
+ events.iter().filter(|it| it.contains("file_item_tree_query")).count();
assert_eq!(n_recalculated_item_trees, 6);
let n_reparsed_macros =
events.iter().filter(|it| it.contains("parse_macro_expansion_shim")).count();
@@ -370,7 +370,7 @@ m!(Z);
assert_eq!(module_data.scope.resolutions().count(), 4);
});
let n_recalculated_item_trees =
- events.iter().filter(|it| it.contains("file_item_tree_shim")).count();
+ events.iter().filter(|it| it.contains("file_item_tree_query")).count();
assert_eq!(n_recalculated_item_trees, 1, "{events:#?}");
let n_reparsed_macros =
events.iter().filter(|it| it.contains("parse_macro_expansion_shim")).count();
@@ -405,10 +405,10 @@ pub type Ty = ();
db.file_item_tree(pos.file_id.into());
});
let n_calculated_item_trees =
- events.iter().filter(|it| it.contains("file_item_tree_shim")).count();
- assert_eq!(n_calculated_item_trees, 1);
+ events.iter().filter(|it| it.contains("file_item_tree_query")).count();
+ assert_eq!(n_calculated_item_trees, 1, "{events:#?}");
let n_parsed_files = events.iter().filter(|it| it.contains("parse")).count();
- assert_eq!(n_parsed_files, 1);
+ assert_eq!(n_parsed_files, 1, "{events:#?}");
}
// FIXME(salsa-transition): bring this back
@@ -446,6 +446,6 @@ pub type Ty = ();
}
});
let n_reparsed_files = events.iter().filter(|it| it.contains("parse(")).count();
- assert_eq!(n_reparsed_files, 0);
+ assert_eq!(n_reparsed_files, 0, "{events:?}");
}
}
diff --git a/crates/hir-ty/src/tests/incremental.rs b/crates/hir-ty/src/tests/incremental.rs
index a055ef879d..74f6bbb030 100644
--- a/crates/hir-ty/src/tests/incremental.rs
+++ b/crates/hir-ty/src/tests/incremental.rs
@@ -156,7 +156,7 @@ pub struct NewStruct {
let expected = vec![
"parse_shim".to_owned(),
"ast_id_map_shim".to_owned(),
- "file_item_tree_shim".to_owned(),
+ "file_item_tree_query".to_owned(),
"real_span_map_shim".to_owned(),
"crate_local_def_map".to_owned(),
"trait_impls_in_crate_shim".to_owned(),
@@ -216,7 +216,7 @@ pub enum SomeEnum {
let expected = vec![
"parse_shim".to_owned(),
"ast_id_map_shim".to_owned(),
- "file_item_tree_shim".to_owned(),
+ "file_item_tree_query".to_owned(),
"real_span_map_shim".to_owned(),
"crate_local_def_map".to_owned(),
"trait_impls_in_crate_shim".to_owned(),
@@ -273,7 +273,7 @@ fn bar() -> f32 {
let expected = vec![
"parse_shim".to_owned(),
"ast_id_map_shim".to_owned(),
- "file_item_tree_shim".to_owned(),
+ "file_item_tree_query".to_owned(),
"real_span_map_shim".to_owned(),
"crate_local_def_map".to_owned(),
"trait_impls_in_crate_shim".to_owned(),
@@ -342,7 +342,7 @@ impl SomeStruct {
let expected = vec![
"parse_shim".to_owned(),
"ast_id_map_shim".to_owned(),
- "file_item_tree_shim".to_owned(),
+ "file_item_tree_query".to_owned(),
"real_span_map_shim".to_owned(),
"crate_local_def_map".to_owned(),
"trait_impls_in_crate_shim".to_owned(),