Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-def/src/item_tree.rs')
-rw-r--r--crates/hir-def/src/item_tree.rs177
1 files changed, 76 insertions, 101 deletions
diff --git a/crates/hir-def/src/item_tree.rs b/crates/hir-def/src/item_tree.rs
index 7650dfe9f3..28eebb286e 100644
--- a/crates/hir-def/src/item_tree.rs
+++ b/crates/hir-def/src/item_tree.rs
@@ -46,8 +46,8 @@ use ast::{AstNode, StructKind};
use base_db::CrateId;
use either::Either;
use hir_expand::{attrs::RawAttrs, name::Name, ExpandTo, HirFileId, InFile};
-use intern::Interned;
-use la_arena::{Arena, Idx, IdxRange, RawIdx};
+use intern::{Interned, Symbol};
+use la_arena::{Arena, Idx, RawIdx};
use once_cell::sync::OnceCell;
use rustc_hash::FxHashMap;
use smallvec::SmallVec;
@@ -218,9 +218,7 @@ impl ItemTree {
extern_crates,
extern_blocks,
functions,
- params,
structs,
- fields,
unions,
enums,
variants,
@@ -241,9 +239,7 @@ impl ItemTree {
extern_crates.shrink_to_fit();
extern_blocks.shrink_to_fit();
functions.shrink_to_fit();
- params.shrink_to_fit();
structs.shrink_to_fit();
- fields.shrink_to_fit();
unions.shrink_to_fit();
enums.shrink_to_fit();
variants.shrink_to_fit();
@@ -295,9 +291,7 @@ struct ItemTreeData {
extern_crates: Arena<ExternCrate>,
extern_blocks: Arena<ExternBlock>,
functions: Arena<Function>,
- params: Arena<Param>,
structs: Arena<Struct>,
- fields: Arena<Field>,
unions: Arena<Union>,
enums: Arena<Enum>,
variants: Arena<Variant>,
@@ -315,7 +309,7 @@ struct ItemTreeData {
vis: ItemVisibilities,
}
-#[derive(Debug, Eq, PartialEq, Hash)]
+#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
pub enum AttrOwner {
/// Attributes on an item.
ModItem(ModItem),
@@ -323,12 +317,28 @@ pub enum AttrOwner {
TopLevel,
Variant(FileItemTreeId<Variant>),
- Field(Idx<Field>),
- Param(Idx<Param>),
+ Field(FieldParent, ItemTreeFieldId),
+ Param(FileItemTreeId<Function>, ItemTreeParamId),
TypeOrConstParamData(GenericModItem, LocalTypeOrConstParamId),
LifetimeParamData(GenericModItem, LocalLifetimeParamId),
}
+impl AttrOwner {
+ pub fn make_field_indexed(parent: FieldParent, idx: usize) -> Self {
+ AttrOwner::Field(parent, ItemTreeFieldId::from_raw(RawIdx::from_u32(idx as u32)))
+ }
+}
+
+#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
+pub enum FieldParent {
+ Struct(FileItemTreeId<Struct>),
+ Union(FileItemTreeId<Union>),
+ Variant(FileItemTreeId<Variant>),
+}
+
+pub type ItemTreeParamId = Idx<Param>;
+pub type ItemTreeFieldId = Idx<Field>;
+
macro_rules! from_attrs {
( $( $var:ident($t:ty) ),+ $(,)? ) => {
$(
@@ -341,12 +351,7 @@ macro_rules! from_attrs {
};
}
-from_attrs!(
- ModItem(ModItem),
- Variant(FileItemTreeId<Variant>),
- Field(Idx<Field>),
- Param(Idx<Param>),
-);
+from_attrs!(ModItem(ModItem), Variant(FileItemTreeId<Variant>));
/// Trait implemented by all nodes in the item tree.
pub trait ItemTreeNode: Clone {
@@ -365,7 +370,7 @@ pub trait GenericsItemTreeNode: ItemTreeNode {
pub struct FileItemTreeId<N>(Idx<N>);
impl<N> FileItemTreeId<N> {
- pub fn range_iter(range: Range<Self>) -> impl Iterator<Item = Self> {
+ 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)
@@ -417,18 +422,18 @@ impl TreeId {
Self { file, block }
}
- pub(crate) fn item_tree(&self, db: &dyn DefDatabase) -> Arc<ItemTree> {
+ pub fn item_tree(&self, db: &dyn DefDatabase) -> Arc<ItemTree> {
match self.block {
Some(block) => db.block_item_tree(block),
None => db.file_item_tree(self.file),
}
}
- pub(crate) fn file_id(self) -> HirFileId {
+ pub fn file_id(self) -> HirFileId {
self.file
}
- pub(crate) fn is_block(self) -> bool {
+ pub fn is_block(self) -> bool {
self.block.is_some()
}
}
@@ -505,6 +510,27 @@ macro_rules! mod_items {
)+
}
+ impl ModItem {
+ pub fn ast_id(&self, tree: &ItemTree) -> FileAstId<ast::Item> {
+ match self {
+ $(ModItem::$typ(it) => tree[it.index()].ast_id().upcast()),+
+ }
+ }
+ }
+
+ impl GenericModItem {
+ pub fn ast_id(&self, tree: &ItemTree) -> FileAstId<ast::AnyHasGenericParams> {
+ match self {
+ $(
+ $(
+ #[cfg_attr(ignore_fragment, $generic_params)]
+ GenericModItem::$typ(it) => tree[it.index()].ast_id().upcast(),
+ )?
+ )+
+ }
+ }
+ }
+
impl From<GenericModItem> for ModItem {
fn from(id: GenericModItem) -> ModItem {
match id {
@@ -596,22 +622,6 @@ mod_items! {
Macro2 in macro_defs -> ast::MacroDef,
}
-macro_rules! impl_index {
- ( $($fld:ident: $t:ty),+ $(,)? ) => {
- $(
- impl Index<Idx<$t>> for ItemTree {
- type Output = $t;
-
- fn index(&self, index: Idx<$t>) -> &Self::Output {
- &self.data().$fld[index]
- }
- }
- )+
- };
-}
-
-impl_index!(fields: Field, variants: Variant, params: Param);
-
impl Index<RawVisibilityId> for ItemTree {
type Output = RawVisibility;
fn index(&self, index: RawVisibilityId) -> &Self::Output {
@@ -712,7 +722,7 @@ pub struct ExternCrate {
#[derive(Debug, Clone, Eq, PartialEq)]
pub struct ExternBlock {
- pub abi: Option<Interned<str>>,
+ pub abi: Option<Symbol>,
pub ast_id: FileAstId<ast::ExternBlock>,
pub children: Box<[ModItem]>,
}
@@ -722,8 +732,8 @@ pub struct Function {
pub name: Name,
pub visibility: RawVisibilityId,
pub explicit_generic_params: Interned<GenericParams>,
- pub abi: Option<Interned<str>>,
- pub params: IdxRange<Param>,
+ pub abi: Option<Symbol>,
+ pub params: Box<[Param]>,
pub ret_type: Interned<TypeRef>,
pub ast_id: FileAstId<ast::Fn>,
pub(crate) flags: FnFlags,
@@ -731,15 +741,7 @@ pub struct Function {
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Param {
- /// This is [`None`] for varargs
pub type_ref: Option<Interned<TypeRef>>,
- pub ast_id: ParamAstId,
-}
-
-#[derive(Debug, Clone, PartialEq, Eq)]
-pub enum ParamAstId {
- Param(FileAstId<ast::Param>),
- SelfParam(FileAstId<ast::SelfParam>),
}
bitflags::bitflags! {
@@ -760,7 +762,8 @@ pub struct Struct {
pub name: Name,
pub visibility: RawVisibilityId,
pub generic_params: Interned<GenericParams>,
- pub fields: Fields,
+ pub fields: Box<[Field]>,
+ pub shape: FieldsShape,
pub ast_id: FileAstId<ast::Struct>,
}
@@ -769,7 +772,7 @@ pub struct Union {
pub name: Name,
pub visibility: RawVisibilityId,
pub generic_params: Interned<GenericParams>,
- pub fields: Fields,
+ pub fields: Box<[Field]>,
pub ast_id: FileAstId<ast::Union>,
}
@@ -782,6 +785,29 @@ pub struct Enum {
pub ast_id: FileAstId<ast::Enum>,
}
+#[derive(Debug, Clone, PartialEq, Eq)]
+pub struct Variant {
+ pub name: Name,
+ pub fields: Box<[Field]>,
+ pub shape: FieldsShape,
+ pub ast_id: FileAstId<ast::Variant>,
+}
+
+#[derive(Debug, Copy, Clone, PartialEq, Eq)]
+pub enum FieldsShape {
+ Record,
+ Tuple,
+ Unit,
+}
+
+/// A single field of an enum variant or struct
+#[derive(Debug, Clone, PartialEq, Eq)]
+pub struct Field {
+ pub name: Name,
+ pub type_ref: Interned<TypeRef>,
+ pub visibility: RawVisibilityId,
+}
+
#[derive(Debug, Clone, Eq, PartialEq)]
pub struct Const {
/// `None` for `const _: () = ();`
@@ -1039,28 +1065,6 @@ impl ModItem {
&ModItem::Function(func) => Some(AssocItem::Function(func)),
}
}
-
- pub fn ast_id(&self, tree: &ItemTree) -> FileAstId<ast::Item> {
- match self {
- ModItem::Use(it) => tree[it.index()].ast_id().upcast(),
- ModItem::ExternCrate(it) => tree[it.index()].ast_id().upcast(),
- ModItem::ExternBlock(it) => tree[it.index()].ast_id().upcast(),
- ModItem::Function(it) => tree[it.index()].ast_id().upcast(),
- ModItem::Struct(it) => tree[it.index()].ast_id().upcast(),
- ModItem::Union(it) => tree[it.index()].ast_id().upcast(),
- ModItem::Enum(it) => tree[it.index()].ast_id().upcast(),
- ModItem::Const(it) => tree[it.index()].ast_id().upcast(),
- ModItem::Static(it) => tree[it.index()].ast_id().upcast(),
- ModItem::Trait(it) => tree[it.index()].ast_id().upcast(),
- ModItem::TraitAlias(it) => tree[it.index()].ast_id().upcast(),
- ModItem::Impl(it) => tree[it.index()].ast_id().upcast(),
- ModItem::TypeAlias(it) => tree[it.index()].ast_id().upcast(),
- ModItem::Mod(it) => tree[it.index()].ast_id().upcast(),
- ModItem::MacroCall(it) => tree[it.index()].ast_id().upcast(),
- ModItem::MacroRules(it) => tree[it.index()].ast_id().upcast(),
- ModItem::Macro2(it) => tree[it.index()].ast_id().upcast(),
- }
- }
}
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
@@ -1099,32 +1103,3 @@ impl AssocItem {
}
}
}
-
-#[derive(Debug, Clone, PartialEq, Eq)]
-pub struct Variant {
- pub name: Name,
- pub fields: Fields,
- pub ast_id: FileAstId<ast::Variant>,
-}
-
-#[derive(Debug, Clone, PartialEq, Eq)]
-pub enum Fields {
- Record(IdxRange<Field>),
- Tuple(IdxRange<Field>),
- Unit,
-}
-
-#[derive(Debug, Clone, PartialEq, Eq)]
-pub enum FieldAstId {
- Record(FileAstId<ast::RecordField>),
- Tuple(FileAstId<ast::TupleField>),
-}
-
-/// A single field of an enum variant or struct
-#[derive(Debug, Clone, PartialEq, Eq)]
-pub struct Field {
- pub name: Name,
- pub type_ref: Interned<TypeRef>,
- pub visibility: RawVisibilityId,
- pub ast_id: FieldAstId,
-}