mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-10-28 18:43:01 +00:00
Split mod items into small and big variants
This commit is contained in:
parent
ace69d93e0
commit
65e2e2c083
3 changed files with 81 additions and 66 deletions
|
|
@ -133,7 +133,8 @@ pub(crate) fn block_item_tree_query(db: &dyn DefDatabase, block: BlockId) -> Arc
|
|||
|
||||
let ctx = lower::Ctx::new(db, loc.ast_id.file_id);
|
||||
let mut item_tree = ctx.lower_block(&block);
|
||||
if item_tree.data.is_empty()
|
||||
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()
|
||||
|
|
@ -143,7 +144,8 @@ pub(crate) fn block_item_tree_query(db: &dyn DefDatabase, block: BlockId) -> Arc
|
|||
Arc::new(ItemTree {
|
||||
top_level: Box::new([]),
|
||||
attrs: FxHashMap::default(),
|
||||
data: FxHashMap::default(),
|
||||
small_data: FxHashMap::default(),
|
||||
big_data: FxHashMap::default(),
|
||||
top_attrs: RawAttrs::EMPTY,
|
||||
vis: ItemVisibilities { arena: ThinVec::new() },
|
||||
})
|
||||
|
|
@ -162,7 +164,8 @@ pub struct ItemTree {
|
|||
attrs: FxHashMap<FileAstId<ast::Item>, RawAttrs>,
|
||||
vis: ItemVisibilities,
|
||||
// FIXME: They values store the key, turn this into a FxHashSet<ModItem> instead?
|
||||
data: FxHashMap<FileAstId<ast::Item>, ModItem>,
|
||||
big_data: FxHashMap<FileAstId<ast::Item>, BigModItem>,
|
||||
small_data: FxHashMap<FileAstId<ast::Item>, SmallModItem>,
|
||||
}
|
||||
|
||||
impl ItemTree {
|
||||
|
|
@ -204,13 +207,18 @@ impl ItemTree {
|
|||
let mut mods = 0;
|
||||
let mut macro_calls = 0;
|
||||
let mut macro_rules = 0;
|
||||
for item in self.data.values() {
|
||||
for item in self.small_data.values() {
|
||||
match item {
|
||||
ModItem::Trait(_) => traits += 1,
|
||||
ModItem::Impl(_) => impls += 1,
|
||||
ModItem::Mod(_) => mods += 1,
|
||||
ModItem::MacroCall(_) => macro_calls += 1,
|
||||
ModItem::MacroRules(_) => macro_rules += 1,
|
||||
SmallModItem::Trait(_) => traits += 1,
|
||||
SmallModItem::Impl(_) => impls += 1,
|
||||
SmallModItem::MacroRules(_) => macro_rules += 1,
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
for item in self.big_data.values() {
|
||||
match item {
|
||||
BigModItem::Mod(_) => mods += 1,
|
||||
BigModItem::MacroCall(_) => macro_calls += 1,
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
|
@ -222,9 +230,10 @@ impl ItemTree {
|
|||
}
|
||||
|
||||
fn shrink_to_fit(&mut self) {
|
||||
let ItemTree { top_level: _, attrs, data, vis: _, top_attrs: _ } = self;
|
||||
let ItemTree { top_level: _, attrs, big_data, small_data, vis: _, top_attrs: _ } = self;
|
||||
attrs.shrink_to_fit();
|
||||
data.shrink_to_fit();
|
||||
big_data.shrink_to_fit();
|
||||
small_data.shrink_to_fit();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -234,35 +243,37 @@ struct ItemVisibilities {
|
|||
}
|
||||
|
||||
#[derive(Debug, Clone, Eq, PartialEq)]
|
||||
enum ModItem {
|
||||
enum SmallModItem {
|
||||
Const(Const),
|
||||
Enum(Enum),
|
||||
// 32
|
||||
ExternBlock(ExternBlock),
|
||||
// 40
|
||||
ExternCrate(ExternCrate),
|
||||
Function(Function),
|
||||
Impl(Impl),
|
||||
Macro2(Macro2),
|
||||
// 32
|
||||
MacroCall(MacroCall),
|
||||
MacroRules(MacroRules),
|
||||
// 40
|
||||
Mod(Mod),
|
||||
Static(Static),
|
||||
// 32
|
||||
Struct(Struct),
|
||||
Trait(Trait),
|
||||
TraitAlias(TraitAlias),
|
||||
TypeAlias(TypeAlias),
|
||||
Union(Union),
|
||||
// 40
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Eq, PartialEq)]
|
||||
enum BigModItem {
|
||||
ExternBlock(ExternBlock),
|
||||
ExternCrate(ExternCrate),
|
||||
MacroCall(MacroCall),
|
||||
Mod(Mod),
|
||||
Struct(Struct),
|
||||
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.
|
||||
// `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::<ModItem>()] = [(); std::mem::size_of::<[usize; 5]>()];
|
||||
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 {
|
||||
|
|
@ -343,9 +354,12 @@ macro_rules! mod_items {
|
|||
impl Index<FileAstId<$ast>> for ItemTree {
|
||||
type Output = $typ;
|
||||
|
||||
#[allow(unused_imports)]
|
||||
fn index(&self, index: FileAstId<$ast>) -> &Self::Output {
|
||||
match &self.data[&index.upcast()] {
|
||||
ModItem::$typ(item) => item,
|
||||
use BigModItem::*;
|
||||
use SmallModItem::*;
|
||||
match &self.$fld[&index.upcast()] {
|
||||
$typ(item) => item,
|
||||
_ => panic!("expected item of type `{}` at index `{:?}`", stringify!($typ), index),
|
||||
}
|
||||
}
|
||||
|
|
@ -356,23 +370,23 @@ macro_rules! mod_items {
|
|||
|
||||
mod_items! {
|
||||
ModItemId ->
|
||||
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,
|
||||
Use in big_data -> ast::Use,
|
||||
ExternCrate in big_data -> ast::ExternCrate,
|
||||
ExternBlock in big_data -> ast::ExternBlock,
|
||||
Function in small_data -> ast::Fn,
|
||||
Struct in big_data -> ast::Struct,
|
||||
Union in small_data -> ast::Union,
|
||||
Enum in small_data -> ast::Enum,
|
||||
Const in small_data -> ast::Const,
|
||||
Static in small_data -> ast::Static,
|
||||
Trait in small_data -> ast::Trait,
|
||||
TraitAlias in small_data -> ast::TraitAlias,
|
||||
Impl in small_data -> ast::Impl,
|
||||
TypeAlias in small_data -> ast::TypeAlias,
|
||||
Mod in big_data -> ast::Module,
|
||||
MacroCall in big_data -> ast::MacroCall,
|
||||
MacroRules in small_data -> ast::MacroRules,
|
||||
Macro2 in small_data -> ast::MacroDef,
|
||||
}
|
||||
|
||||
impl Index<RawVisibilityId> for ItemTree {
|
||||
|
|
@ -421,6 +435,7 @@ pub struct UseTree {
|
|||
}
|
||||
|
||||
// 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 _;`
|
||||
|
|
|
|||
|
|
@ -20,10 +20,11 @@ use triomphe::Arc;
|
|||
use crate::{
|
||||
db::DefDatabase,
|
||||
item_tree::{
|
||||
Const, Enum, ExternBlock, ExternCrate, FieldsShape, Function, Impl, ImportAlias, Interned,
|
||||
ItemTree, ItemTreeAstId, Macro2, MacroCall, MacroRules, Mod, ModItem, ModItemId, ModKind,
|
||||
ModPath, RawAttrs, RawVisibility, RawVisibilityId, Static, Struct, StructKind, Trait,
|
||||
TraitAlias, TypeAlias, Union, Use, UseTree, UseTreeKind, VisibilityExplicitness,
|
||||
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,
|
||||
},
|
||||
};
|
||||
|
||||
|
|
@ -168,7 +169,7 @@ impl<'a> Ctx<'a> {
|
|||
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 };
|
||||
self.tree.data.insert(ast_id.upcast(), ModItem::Struct(res));
|
||||
self.tree.big_data.insert(ast_id.upcast(), BigModItem::Struct(res));
|
||||
|
||||
Some(ast_id)
|
||||
}
|
||||
|
|
@ -178,7 +179,7 @@ impl<'a> Ctx<'a> {
|
|||
let name = union.name()?.as_name();
|
||||
let ast_id = self.source_ast_id_map.ast_id(union);
|
||||
let res = Union { name, visibility, ast_id };
|
||||
self.tree.data.insert(ast_id.upcast(), ModItem::Union(res));
|
||||
self.tree.small_data.insert(ast_id.upcast(), SmallModItem::Union(res));
|
||||
Some(ast_id)
|
||||
}
|
||||
|
||||
|
|
@ -187,7 +188,7 @@ impl<'a> Ctx<'a> {
|
|||
let name = enum_.name()?.as_name();
|
||||
let ast_id = self.source_ast_id_map.ast_id(enum_);
|
||||
let res = Enum { name, visibility, ast_id };
|
||||
self.tree.data.insert(ast_id.upcast(), ModItem::Enum(res));
|
||||
self.tree.small_data.insert(ast_id.upcast(), SmallModItem::Enum(res));
|
||||
Some(ast_id)
|
||||
}
|
||||
|
||||
|
|
@ -199,7 +200,7 @@ impl<'a> Ctx<'a> {
|
|||
|
||||
let res = Function { name, visibility, ast_id };
|
||||
|
||||
self.tree.data.insert(ast_id.upcast(), ModItem::Function(res));
|
||||
self.tree.small_data.insert(ast_id.upcast(), SmallModItem::Function(res));
|
||||
Some(ast_id)
|
||||
}
|
||||
|
||||
|
|
@ -211,7 +212,7 @@ impl<'a> Ctx<'a> {
|
|||
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 };
|
||||
self.tree.data.insert(ast_id.upcast(), ModItem::TypeAlias(res));
|
||||
self.tree.small_data.insert(ast_id.upcast(), SmallModItem::TypeAlias(res));
|
||||
Some(ast_id)
|
||||
}
|
||||
|
||||
|
|
@ -220,7 +221,7 @@ impl<'a> Ctx<'a> {
|
|||
let visibility = self.lower_visibility(static_);
|
||||
let ast_id = self.source_ast_id_map.ast_id(static_);
|
||||
let res = Static { name, visibility, ast_id };
|
||||
self.tree.data.insert(ast_id.upcast(), ModItem::Static(res));
|
||||
self.tree.small_data.insert(ast_id.upcast(), SmallModItem::Static(res));
|
||||
Some(ast_id)
|
||||
}
|
||||
|
||||
|
|
@ -229,7 +230,7 @@ impl<'a> Ctx<'a> {
|
|||
let visibility = self.lower_visibility(konst);
|
||||
let ast_id = self.source_ast_id_map.ast_id(konst);
|
||||
let res = Const { name, visibility, ast_id };
|
||||
self.tree.data.insert(ast_id.upcast(), ModItem::Const(res));
|
||||
self.tree.small_data.insert(ast_id.upcast(), SmallModItem::Const(res));
|
||||
ast_id
|
||||
}
|
||||
|
||||
|
|
@ -251,7 +252,7 @@ impl<'a> Ctx<'a> {
|
|||
};
|
||||
let ast_id = self.source_ast_id_map.ast_id(module);
|
||||
let res = Mod { name, visibility, kind, ast_id };
|
||||
self.tree.data.insert(ast_id.upcast(), ModItem::Mod(res));
|
||||
self.tree.big_data.insert(ast_id.upcast(), BigModItem::Mod(res));
|
||||
Some(ast_id)
|
||||
}
|
||||
|
||||
|
|
@ -261,7 +262,7 @@ impl<'a> Ctx<'a> {
|
|||
let ast_id = self.source_ast_id_map.ast_id(trait_def);
|
||||
|
||||
let def = Trait { name, visibility, ast_id };
|
||||
self.tree.data.insert(ast_id.upcast(), ModItem::Trait(def));
|
||||
self.tree.small_data.insert(ast_id.upcast(), SmallModItem::Trait(def));
|
||||
Some(ast_id)
|
||||
}
|
||||
|
||||
|
|
@ -274,7 +275,7 @@ impl<'a> Ctx<'a> {
|
|||
let ast_id = self.source_ast_id_map.ast_id(trait_alias_def);
|
||||
|
||||
let alias = TraitAlias { name, visibility, ast_id };
|
||||
self.tree.data.insert(ast_id.upcast(), ModItem::TraitAlias(alias));
|
||||
self.tree.small_data.insert(ast_id.upcast(), SmallModItem::TraitAlias(alias));
|
||||
Some(ast_id)
|
||||
}
|
||||
|
||||
|
|
@ -283,7 +284,7 @@ impl<'a> Ctx<'a> {
|
|||
// 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 };
|
||||
self.tree.data.insert(ast_id.upcast(), ModItem::Impl(res));
|
||||
self.tree.small_data.insert(ast_id.upcast(), SmallModItem::Impl(res));
|
||||
ast_id
|
||||
}
|
||||
|
||||
|
|
@ -295,7 +296,7 @@ impl<'a> Ctx<'a> {
|
|||
})?;
|
||||
|
||||
let res = Use { visibility, ast_id, use_tree };
|
||||
self.tree.data.insert(ast_id.upcast(), ModItem::Use(res));
|
||||
self.tree.big_data.insert(ast_id.upcast(), BigModItem::Use(res));
|
||||
Some(ast_id)
|
||||
}
|
||||
|
||||
|
|
@ -311,7 +312,7 @@ impl<'a> Ctx<'a> {
|
|||
let ast_id = self.source_ast_id_map.ast_id(extern_crate);
|
||||
|
||||
let res = ExternCrate { name, alias, visibility, ast_id };
|
||||
self.tree.data.insert(ast_id.upcast(), ModItem::ExternCrate(res));
|
||||
self.tree.big_data.insert(ast_id.upcast(), BigModItem::ExternCrate(res));
|
||||
Some(ast_id)
|
||||
}
|
||||
|
||||
|
|
@ -325,7 +326,7 @@ 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 };
|
||||
self.tree.data.insert(ast_id.upcast(), ModItem::MacroCall(res));
|
||||
self.tree.big_data.insert(ast_id.upcast(), BigModItem::MacroCall(res));
|
||||
Some(ast_id)
|
||||
}
|
||||
|
||||
|
|
@ -334,7 +335,7 @@ impl<'a> Ctx<'a> {
|
|||
let ast_id = self.source_ast_id_map.ast_id(m);
|
||||
|
||||
let res = MacroRules { name: name.as_name(), ast_id };
|
||||
self.tree.data.insert(ast_id.upcast(), ModItem::MacroRules(res));
|
||||
self.tree.small_data.insert(ast_id.upcast(), SmallModItem::MacroRules(res));
|
||||
Some(ast_id)
|
||||
}
|
||||
|
||||
|
|
@ -345,7 +346,7 @@ impl<'a> Ctx<'a> {
|
|||
let visibility = self.lower_visibility(m);
|
||||
|
||||
let res = Macro2 { name: name.as_name(), ast_id, visibility };
|
||||
self.tree.data.insert(ast_id.upcast(), ModItem::Macro2(res));
|
||||
self.tree.small_data.insert(ast_id.upcast(), SmallModItem::Macro2(res));
|
||||
Some(ast_id)
|
||||
}
|
||||
|
||||
|
|
@ -372,7 +373,7 @@ impl<'a> Ctx<'a> {
|
|||
});
|
||||
|
||||
let res = ExternBlock { ast_id, children };
|
||||
self.tree.data.insert(ast_id.upcast(), ModItem::ExternBlock(res));
|
||||
self.tree.big_data.insert(ast_id.upcast(), BigModItem::ExternBlock(res));
|
||||
ast_id
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -112,7 +112,6 @@ impl TaggedArcPtr {
|
|||
}
|
||||
}
|
||||
|
||||
// FIXME: This should have more than one niche
|
||||
#[derive(PartialEq, Eq, Hash)]
|
||||
pub struct Symbol {
|
||||
repr: TaggedArcPtr,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue