aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_def/src/item_tree.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/hir_def/src/item_tree.rs')
-rw-r--r--crates/hir_def/src/item_tree.rs154
1 files changed, 37 insertions, 117 deletions
diff --git a/crates/hir_def/src/item_tree.rs b/crates/hir_def/src/item_tree.rs
index ca0048b16..240662486 100644
--- a/crates/hir_def/src/item_tree.rs
+++ b/crates/hir_def/src/item_tree.rs
@@ -24,14 +24,15 @@ use la_arena::{Arena, Idx, RawIdx};
24use profile::Count; 24use profile::Count;
25use rustc_hash::FxHashMap; 25use rustc_hash::FxHashMap;
26use smallvec::SmallVec; 26use smallvec::SmallVec;
27use syntax::{ast, match_ast, SmolStr, SyntaxKind}; 27use syntax::{ast, match_ast, SyntaxKind};
28 28
29use crate::{ 29use crate::{
30 attr::{Attrs, RawAttrs}, 30 attr::{Attrs, RawAttrs},
31 db::DefDatabase, 31 db::DefDatabase,
32 generics::GenericParams, 32 generics::GenericParams,
33 intern::Interned,
33 path::{path, AssociatedTypeBinding, GenericArgs, ImportAlias, ModPath, Path, PathKind}, 34 path::{path, AssociatedTypeBinding, GenericArgs, ImportAlias, ModPath, Path, PathKind},
34 type_ref::{Mutability, TypeBound, TypeRef}, 35 type_ref::{Mutability, TraitRef, TypeBound, TypeRef},
35 visibility::RawVisibility, 36 visibility::RawVisibility,
36}; 37};
37 38
@@ -57,13 +58,6 @@ impl fmt::Debug for RawVisibilityId {
57 } 58 }
58} 59}
59 60
60#[derive(Debug, Copy, Clone, Eq, PartialEq)]
61pub struct GenericParamsId(u32);
62
63impl GenericParamsId {
64 pub const EMPTY: Self = GenericParamsId(u32::max_value());
65}
66
67/// The item tree of a source file. 61/// The item tree of a source file.
68#[derive(Debug, Default, Eq, PartialEq)] 62#[derive(Debug, Default, Eq, PartialEq)]
69pub struct ItemTree { 63pub struct ItemTree {
@@ -145,8 +139,6 @@ impl ItemTree {
145 macro_rules, 139 macro_rules,
146 macro_defs, 140 macro_defs,
147 vis, 141 vis,
148 generics,
149 type_refs,
150 inner_items, 142 inner_items,
151 } = &mut **data; 143 } = &mut **data;
152 144
@@ -170,9 +162,6 @@ impl ItemTree {
170 macro_defs.shrink_to_fit(); 162 macro_defs.shrink_to_fit();
171 163
172 vis.arena.shrink_to_fit(); 164 vis.arena.shrink_to_fit();
173 generics.arena.shrink_to_fit();
174 type_refs.arena.shrink_to_fit();
175 type_refs.map.shrink_to_fit();
176 165
177 inner_items.shrink_to_fit(); 166 inner_items.shrink_to_fit();
178 } 167 }
@@ -244,58 +233,6 @@ static VIS_PRIV: RawVisibility = RawVisibility::Module(ModPath::from_kind(PathKi
244static VIS_PUB_CRATE: RawVisibility = RawVisibility::Module(ModPath::from_kind(PathKind::Crate)); 233static VIS_PUB_CRATE: RawVisibility = RawVisibility::Module(ModPath::from_kind(PathKind::Crate));
245 234
246#[derive(Default, Debug, Eq, PartialEq)] 235#[derive(Default, Debug, Eq, PartialEq)]
247struct GenericParamsStorage {
248 arena: Arena<GenericParams>,
249}
250
251impl GenericParamsStorage {
252 fn alloc(&mut self, params: GenericParams) -> GenericParamsId {
253 if params.types.is_empty()
254 && params.lifetimes.is_empty()
255 && params.consts.is_empty()
256 && params.where_predicates.is_empty()
257 {
258 return GenericParamsId::EMPTY;
259 }
260
261 GenericParamsId(self.arena.alloc(params).into_raw().into())
262 }
263}
264
265static EMPTY_GENERICS: GenericParams = GenericParams {
266 types: Arena::new(),
267 lifetimes: Arena::new(),
268 consts: Arena::new(),
269 where_predicates: Vec::new(),
270};
271
272/// `TypeRef` interner.
273#[derive(Default, Debug, Eq, PartialEq)]
274struct TypeRefStorage {
275 arena: Arena<Arc<TypeRef>>,
276 map: FxHashMap<Arc<TypeRef>, Idx<Arc<TypeRef>>>,
277}
278
279impl TypeRefStorage {
280 // Note: We lie about the `Idx<TypeRef>` to hide the interner details.
281
282 fn intern(&mut self, ty: TypeRef) -> Idx<TypeRef> {
283 if let Some(id) = self.map.get(&ty) {
284 return Idx::from_raw(id.into_raw());
285 }
286
287 let ty = Arc::new(ty);
288 let idx = self.arena.alloc(ty.clone());
289 self.map.insert(ty, idx);
290 Idx::from_raw(idx.into_raw())
291 }
292
293 fn lookup(&self, id: Idx<TypeRef>) -> &TypeRef {
294 &self.arena[Idx::from_raw(id.into_raw())]
295 }
296}
297
298#[derive(Default, Debug, Eq, PartialEq)]
299struct ItemTreeData { 236struct ItemTreeData {
300 imports: Arena<Import>, 237 imports: Arena<Import>,
301 extern_crates: Arena<ExternCrate>, 238 extern_crates: Arena<ExternCrate>,
@@ -317,8 +254,6 @@ struct ItemTreeData {
317 macro_defs: Arena<MacroDef>, 254 macro_defs: Arena<MacroDef>,
318 255
319 vis: ItemVisibilities, 256 vis: ItemVisibilities,
320 generics: GenericParamsStorage,
321 type_refs: TypeRefStorage,
322 257
323 inner_items: FxHashMap<FileAstId<ast::BlockExpr>, SmallVec<[ModItem; 1]>>, 258 inner_items: FxHashMap<FileAstId<ast::BlockExpr>, SmallVec<[ModItem; 1]>>,
324} 259}
@@ -537,25 +472,6 @@ impl Index<RawVisibilityId> for ItemTree {
537 } 472 }
538} 473}
539 474
540impl Index<GenericParamsId> for ItemTree {
541 type Output = GenericParams;
542
543 fn index(&self, index: GenericParamsId) -> &Self::Output {
544 match index {
545 GenericParamsId::EMPTY => &EMPTY_GENERICS,
546 _ => &self.data().generics.arena[Idx::from_raw(index.0.into())],
547 }
548 }
549}
550
551impl Index<Idx<TypeRef>> for ItemTree {
552 type Output = TypeRef;
553
554 fn index(&self, id: Idx<TypeRef>) -> &Self::Output {
555 self.data().type_refs.lookup(id)
556 }
557}
558
559impl<N: ItemTreeNode> Index<FileItemTreeId<N>> for ItemTree { 475impl<N: ItemTreeNode> Index<FileItemTreeId<N>> for ItemTree {
560 type Output = N; 476 type Output = N;
561 fn index(&self, id: FileItemTreeId<N>) -> &N { 477 fn index(&self, id: FileItemTreeId<N>) -> &N {
@@ -566,7 +482,7 @@ impl<N: ItemTreeNode> Index<FileItemTreeId<N>> for ItemTree {
566/// A desugared `use` import. 482/// A desugared `use` import.
567#[derive(Debug, Clone, Eq, PartialEq)] 483#[derive(Debug, Clone, Eq, PartialEq)]
568pub struct Import { 484pub struct Import {
569 pub path: ModPath, 485 pub path: Interned<ModPath>,
570 pub alias: Option<ImportAlias>, 486 pub alias: Option<ImportAlias>,
571 pub visibility: RawVisibilityId, 487 pub visibility: RawVisibilityId,
572 pub is_glob: bool, 488 pub is_glob: bool,
@@ -592,38 +508,42 @@ pub struct ExternCrate {
592pub struct Function { 508pub struct Function {
593 pub name: Name, 509 pub name: Name,
594 pub visibility: RawVisibilityId, 510 pub visibility: RawVisibilityId,
595 pub generic_params: GenericParamsId, 511 pub generic_params: Interned<GenericParams>,
596 pub has_self_param: bool, 512 pub abi: Option<Interned<str>>,
597 pub has_body: bool,
598 pub qualifier: FunctionQualifier,
599 /// Whether the function is located in an `extern` block (*not* whether it is an
600 /// `extern "abi" fn`).
601 pub is_in_extern_block: bool,
602 pub params: IdRange<Param>, 513 pub params: IdRange<Param>,
603 pub ret_type: Idx<TypeRef>, 514 pub ret_type: Interned<TypeRef>,
604 pub ast_id: FileAstId<ast::Fn>, 515 pub ast_id: FileAstId<ast::Fn>,
516 pub(crate) flags: FnFlags,
605} 517}
606 518
607#[derive(Debug, Clone, Eq, PartialEq)] 519#[derive(Debug, Clone, Eq, PartialEq)]
608pub enum Param { 520pub enum Param {
609 Normal(Idx<TypeRef>), 521 Normal(Interned<TypeRef>),
610 Varargs, 522 Varargs,
611} 523}
612 524
613#[derive(Debug, Clone, PartialEq, Eq)] 525#[derive(Debug, Clone, Copy, Eq, PartialEq, Default)]
614pub struct FunctionQualifier { 526pub(crate) struct FnFlags {
615 pub is_default: bool, 527 pub(crate) bits: u8,
616 pub is_const: bool, 528}
617 pub is_async: bool, 529impl FnFlags {
618 pub is_unsafe: bool, 530 pub(crate) const HAS_SELF_PARAM: u8 = 1 << 0;
619 pub abi: Option<SmolStr>, 531 pub(crate) const HAS_BODY: u8 = 1 << 1;
532 pub(crate) const IS_DEFAULT: u8 = 1 << 2;
533 pub(crate) const IS_CONST: u8 = 1 << 3;
534 pub(crate) const IS_ASYNC: u8 = 1 << 4;
535 pub(crate) const IS_UNSAFE: u8 = 1 << 5;
536 /// Whether the function is located in an `extern` block (*not* whether it is an
537 /// `extern "abi" fn`).
538 pub(crate) const IS_IN_EXTERN_BLOCK: u8 = 1 << 6;
539 pub(crate) const IS_VARARGS: u8 = 1 << 7;
620} 540}
621 541
622#[derive(Debug, Clone, Eq, PartialEq)] 542#[derive(Debug, Clone, Eq, PartialEq)]
623pub struct Struct { 543pub struct Struct {
624 pub name: Name, 544 pub name: Name,
625 pub visibility: RawVisibilityId, 545 pub visibility: RawVisibilityId,
626 pub generic_params: GenericParamsId, 546 pub generic_params: Interned<GenericParams>,
627 pub fields: Fields, 547 pub fields: Fields,
628 pub ast_id: FileAstId<ast::Struct>, 548 pub ast_id: FileAstId<ast::Struct>,
629 pub kind: StructDefKind, 549 pub kind: StructDefKind,
@@ -643,7 +563,7 @@ pub enum StructDefKind {
643pub struct Union { 563pub struct Union {
644 pub name: Name, 564 pub name: Name,
645 pub visibility: RawVisibilityId, 565 pub visibility: RawVisibilityId,
646 pub generic_params: GenericParamsId, 566 pub generic_params: Interned<GenericParams>,
647 pub fields: Fields, 567 pub fields: Fields,
648 pub ast_id: FileAstId<ast::Union>, 568 pub ast_id: FileAstId<ast::Union>,
649} 569}
@@ -652,7 +572,7 @@ pub struct Union {
652pub struct Enum { 572pub struct Enum {
653 pub name: Name, 573 pub name: Name,
654 pub visibility: RawVisibilityId, 574 pub visibility: RawVisibilityId,
655 pub generic_params: GenericParamsId, 575 pub generic_params: Interned<GenericParams>,
656 pub variants: IdRange<Variant>, 576 pub variants: IdRange<Variant>,
657 pub ast_id: FileAstId<ast::Enum>, 577 pub ast_id: FileAstId<ast::Enum>,
658} 578}
@@ -662,7 +582,7 @@ pub struct Const {
662 /// const _: () = (); 582 /// const _: () = ();
663 pub name: Option<Name>, 583 pub name: Option<Name>,
664 pub visibility: RawVisibilityId, 584 pub visibility: RawVisibilityId,
665 pub type_ref: Idx<TypeRef>, 585 pub type_ref: Interned<TypeRef>,
666 pub ast_id: FileAstId<ast::Const>, 586 pub ast_id: FileAstId<ast::Const>,
667} 587}
668 588
@@ -673,7 +593,7 @@ pub struct Static {
673 pub mutable: bool, 593 pub mutable: bool,
674 /// Whether the static is in an `extern` block. 594 /// Whether the static is in an `extern` block.
675 pub is_extern: bool, 595 pub is_extern: bool,
676 pub type_ref: Idx<TypeRef>, 596 pub type_ref: Interned<TypeRef>,
677 pub ast_id: FileAstId<ast::Static>, 597 pub ast_id: FileAstId<ast::Static>,
678} 598}
679 599
@@ -681,7 +601,7 @@ pub struct Static {
681pub struct Trait { 601pub struct Trait {
682 pub name: Name, 602 pub name: Name,
683 pub visibility: RawVisibilityId, 603 pub visibility: RawVisibilityId,
684 pub generic_params: GenericParamsId, 604 pub generic_params: Interned<GenericParams>,
685 pub is_auto: bool, 605 pub is_auto: bool,
686 pub is_unsafe: bool, 606 pub is_unsafe: bool,
687 pub bounds: Box<[TypeBound]>, 607 pub bounds: Box<[TypeBound]>,
@@ -691,9 +611,9 @@ pub struct Trait {
691 611
692#[derive(Debug, Clone, Eq, PartialEq)] 612#[derive(Debug, Clone, Eq, PartialEq)]
693pub struct Impl { 613pub struct Impl {
694 pub generic_params: GenericParamsId, 614 pub generic_params: Interned<GenericParams>,
695 pub target_trait: Option<Idx<TypeRef>>, 615 pub target_trait: Option<Interned<TraitRef>>,
696 pub target_type: Idx<TypeRef>, 616 pub self_ty: Interned<TypeRef>,
697 pub is_negative: bool, 617 pub is_negative: bool,
698 pub items: Box<[AssocItem]>, 618 pub items: Box<[AssocItem]>,
699 pub ast_id: FileAstId<ast::Impl>, 619 pub ast_id: FileAstId<ast::Impl>,
@@ -705,8 +625,8 @@ pub struct TypeAlias {
705 pub visibility: RawVisibilityId, 625 pub visibility: RawVisibilityId,
706 /// Bounds on the type alias itself. Only valid in trait declarations, eg. `type Assoc: Copy;`. 626 /// Bounds on the type alias itself. Only valid in trait declarations, eg. `type Assoc: Copy;`.
707 pub bounds: Box<[TypeBound]>, 627 pub bounds: Box<[TypeBound]>,
708 pub generic_params: GenericParamsId, 628 pub generic_params: Interned<GenericParams>,
709 pub type_ref: Option<Idx<TypeRef>>, 629 pub type_ref: Option<Interned<TypeRef>>,
710 pub is_extern: bool, 630 pub is_extern: bool,
711 pub ast_id: FileAstId<ast::TypeAlias>, 631 pub ast_id: FileAstId<ast::TypeAlias>,
712} 632}
@@ -731,7 +651,7 @@ pub enum ModKind {
731#[derive(Debug, Clone, Eq, PartialEq)] 651#[derive(Debug, Clone, Eq, PartialEq)]
732pub struct MacroCall { 652pub struct MacroCall {
733 /// Path to the called macro. 653 /// Path to the called macro.
734 pub path: ModPath, 654 pub path: Interned<ModPath>,
735 pub ast_id: FileAstId<ast::MacroCall>, 655 pub ast_id: FileAstId<ast::MacroCall>,
736} 656}
737 657
@@ -896,6 +816,6 @@ pub enum Fields {
896#[derive(Debug, Clone, PartialEq, Eq)] 816#[derive(Debug, Clone, PartialEq, Eq)]
897pub struct Field { 817pub struct Field {
898 pub name: Name, 818 pub name: Name,
899 pub type_ref: Idx<TypeRef>, 819 pub type_ref: Interned<TypeRef>,
900 pub visibility: RawVisibilityId, 820 pub visibility: RawVisibilityId,
901} 821}