ItemTree's ItemVisibilities has no identity, so deduplicate

This commit is contained in:
Lukas Wirth 2025-06-12 08:52:19 +02:00
parent c15fc9a344
commit 13494f4cac
7 changed files with 39 additions and 38 deletions

View file

@ -7,6 +7,7 @@ mod path;
use std::mem;
use base_db::FxIndexSet;
use cfg::CfgOptions;
use either::Either;
use hir_expand::{
@ -66,8 +67,6 @@ use crate::{
pub use self::path::hir_segment_to_ast_segment;
type FxIndexSet<K> = indexmap::IndexSet<K, std::hash::BuildHasherDefault<rustc_hash::FxHasher>>;
pub(super) fn lower_body(
db: &dyn DefDatabase,
owner: DefWithBodyId,

View file

@ -246,7 +246,7 @@ impl ItemTree {
macro_calls,
macro_rules,
macro_defs,
vis,
vis: _,
} = &mut **data;
uses.shrink_to_fit();
@ -266,36 +266,13 @@ impl ItemTree {
macro_calls.shrink_to_fit();
macro_rules.shrink_to_fit();
macro_defs.shrink_to_fit();
vis.arena.shrink_to_fit();
}
}
}
#[derive(Default, Debug, Eq, PartialEq)]
struct ItemVisibilities {
arena: Arena<RawVisibility>,
}
impl ItemVisibilities {
fn alloc(&mut self, vis: RawVisibility) -> RawVisibilityId {
match &vis {
RawVisibility::Public => RawVisibilityId::PUB,
RawVisibility::Module(path, explicitiy) if path.segments().is_empty() => {
match (path.kind, explicitiy) {
(PathKind::SELF, VisibilityExplicitness::Explicit) => {
RawVisibilityId::PRIV_EXPLICIT
}
(PathKind::SELF, VisibilityExplicitness::Implicit) => {
RawVisibilityId::PRIV_IMPLICIT
}
(PathKind::Crate, _) => RawVisibilityId::PUB_CRATE,
_ => RawVisibilityId(self.arena.alloc(vis).into_raw().into()),
}
}
_ => RawVisibilityId(self.arena.alloc(vis).into_raw().into()),
}
}
arena: Box<[RawVisibility]>,
}
#[derive(Default, Debug, Eq, PartialEq)]
@ -577,7 +554,7 @@ impl Index<RawVisibilityId> for ItemTree {
VisibilityExplicitness::Explicit,
)
}),
_ => &self.data().vis.arena[Idx::from_raw(index.0.into())],
_ => &self.data().vis.arena[index.0 as usize],
}
}
}
@ -702,7 +679,7 @@ pub enum FieldsShape {
}
/// Visibility of an item, not yet resolved.
#[derive(Debug, Clone, PartialEq, Eq)]
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum RawVisibility {
/// `pub(in module)`, `pub(crate)` or `pub(super)`. Also private, which is
/// equivalent to `pub(self)`.

View file

@ -2,6 +2,7 @@
use std::{cell::OnceCell, collections::hash_map::Entry};
use base_db::FxIndexSet;
use hir_expand::{
HirFileId,
mod_path::PathKind,
@ -37,6 +38,7 @@ pub(super) struct Ctx<'a> {
source_ast_id_map: Arc<AstIdMap>,
span_map: OnceCell<SpanMap>,
file: HirFileId,
visibilities: FxIndexSet<RawVisibility>,
}
impl<'a> Ctx<'a> {
@ -47,6 +49,7 @@ impl<'a> Ctx<'a> {
source_ast_id_map: db.ast_id_map(file),
file,
span_map: OnceCell::new(),
visibilities: FxIndexSet::default(),
}
}
@ -57,6 +60,9 @@ 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.tree
}
@ -90,6 +96,9 @@ impl<'a> Ctx<'a> {
}
}
if let Some(data) = &mut self.tree.data {
data.vis.arena = self.visibilities.into_iter().collect();
}
self.tree
}
@ -115,7 +124,9 @@ impl<'a> Ctx<'a> {
}
}
}
if let Some(data) = &mut self.tree.data {
data.vis.arena = self.visibilities.into_iter().collect();
}
self.tree
}
@ -370,7 +381,22 @@ impl<'a> Ctx<'a> {
let vis = visibility_from_ast(self.db, item.visibility(), &mut |range| {
self.span_map().span_for_range(range).ctx
});
self.data().vis.alloc(vis)
match &vis {
RawVisibility::Public => RawVisibilityId::PUB,
RawVisibility::Module(path, explicitiy) if path.segments().is_empty() => {
match (path.kind, explicitiy) {
(PathKind::SELF, VisibilityExplicitness::Explicit) => {
RawVisibilityId::PRIV_EXPLICIT
}
(PathKind::SELF, VisibilityExplicitness::Implicit) => {
RawVisibilityId::PRIV_IMPLICIT
}
(PathKind::Crate, _) => RawVisibilityId::PUB_CRATE,
_ => RawVisibilityId(self.visibilities.insert_full(vis).0 as u32),
}
}
_ => RawVisibilityId(self.visibilities.insert_full(vis).0 as u32),
}
}
}