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.rs159
1 files changed, 42 insertions, 117 deletions
diff --git a/crates/hir_def/src/item_tree.rs b/crates/hir_def/src/item_tree.rs
index ca0048b16..94e08f835 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 {
@@ -105,6 +99,11 @@ impl ItemTree {
105 // items. 99 // items.
106 ctx.lower_macro_stmts(stmts) 100 ctx.lower_macro_stmts(stmts)
107 }, 101 },
102 ast::Pat(_pat) => {
103 // FIXME: This occurs because macros in pattern position are treated as inner
104 // items and expanded during block DefMap computation
105 return Default::default();
106 },
108 ast::Expr(e) => { 107 ast::Expr(e) => {
109 // Macros can expand to expressions. We return an empty item tree in this case, but 108 // Macros can expand to expressions. We return an empty item tree in this case, but
110 // still need to collect inner items. 109 // still need to collect inner items.
@@ -145,8 +144,6 @@ impl ItemTree {
145 macro_rules, 144 macro_rules,
146 macro_defs, 145 macro_defs,
147 vis, 146 vis,
148 generics,
149 type_refs,
150 inner_items, 147 inner_items,
151 } = &mut **data; 148 } = &mut **data;
152 149
@@ -170,9 +167,6 @@ impl ItemTree {
170 macro_defs.shrink_to_fit(); 167 macro_defs.shrink_to_fit();
171 168
172 vis.arena.shrink_to_fit(); 169 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 170
177 inner_items.shrink_to_fit(); 171 inner_items.shrink_to_fit();
178 } 172 }
@@ -244,58 +238,6 @@ static VIS_PRIV: RawVisibility = RawVisibility::Module(ModPath::from_kind(PathKi
244static VIS_PUB_CRATE: RawVisibility = RawVisibility::Module(ModPath::from_kind(PathKind::Crate)); 238static VIS_PUB_CRATE: RawVisibility = RawVisibility::Module(ModPath::from_kind(PathKind::Crate));
245 239
246#[derive(Default, Debug, Eq, PartialEq)] 240#[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 { 241struct ItemTreeData {
300 imports: Arena<Import>, 242 imports: Arena<Import>,
301 extern_crates: Arena<ExternCrate>, 243 extern_crates: Arena<ExternCrate>,
@@ -317,8 +259,6 @@ struct ItemTreeData {
317 macro_defs: Arena<MacroDef>, 259 macro_defs: Arena<MacroDef>,
318 260
319 vis: ItemVisibilities, 261 vis: ItemVisibilities,
320 generics: GenericParamsStorage,
321 type_refs: TypeRefStorage,
322 262
323 inner_items: FxHashMap<FileAstId<ast::BlockExpr>, SmallVec<[ModItem; 1]>>, 263 inner_items: FxHashMap<FileAstId<ast::BlockExpr>, SmallVec<[ModItem; 1]>>,
324} 264}
@@ -537,25 +477,6 @@ impl Index<RawVisibilityId> for ItemTree {
537 } 477 }
538} 478}
539 479
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 { 480impl<N: ItemTreeNode> Index<FileItemTreeId<N>> for ItemTree {
560 type Output = N; 481 type Output = N;
561 fn index(&self, id: FileItemTreeId<N>) -> &N { 482 fn index(&self, id: FileItemTreeId<N>) -> &N {
@@ -566,7 +487,7 @@ impl<N: ItemTreeNode> Index<FileItemTreeId<N>> for ItemTree {
566/// A desugared `use` import. 487/// A desugared `use` import.
567#[derive(Debug, Clone, Eq, PartialEq)] 488#[derive(Debug, Clone, Eq, PartialEq)]
568pub struct Import { 489pub struct Import {
569 pub path: ModPath, 490 pub path: Interned<ModPath>,
570 pub alias: Option<ImportAlias>, 491 pub alias: Option<ImportAlias>,
571 pub visibility: RawVisibilityId, 492 pub visibility: RawVisibilityId,
572 pub is_glob: bool, 493 pub is_glob: bool,
@@ -592,38 +513,42 @@ pub struct ExternCrate {
592pub struct Function { 513pub struct Function {
593 pub name: Name, 514 pub name: Name,
594 pub visibility: RawVisibilityId, 515 pub visibility: RawVisibilityId,
595 pub generic_params: GenericParamsId, 516 pub generic_params: Interned<GenericParams>,
596 pub has_self_param: bool, 517 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>, 518 pub params: IdRange<Param>,
603 pub ret_type: Idx<TypeRef>, 519 pub ret_type: Interned<TypeRef>,
604 pub ast_id: FileAstId<ast::Fn>, 520 pub ast_id: FileAstId<ast::Fn>,
521 pub(crate) flags: FnFlags,
605} 522}
606 523
607#[derive(Debug, Clone, Eq, PartialEq)] 524#[derive(Debug, Clone, Eq, PartialEq)]
608pub enum Param { 525pub enum Param {
609 Normal(Idx<TypeRef>), 526 Normal(Interned<TypeRef>),
610 Varargs, 527 Varargs,
611} 528}
612 529
613#[derive(Debug, Clone, PartialEq, Eq)] 530#[derive(Debug, Clone, Copy, Eq, PartialEq, Default)]
614pub struct FunctionQualifier { 531pub(crate) struct FnFlags {
615 pub is_default: bool, 532 pub(crate) bits: u8,
616 pub is_const: bool, 533}
617 pub is_async: bool, 534impl FnFlags {
618 pub is_unsafe: bool, 535 pub(crate) const HAS_SELF_PARAM: u8 = 1 << 0;
619 pub abi: Option<SmolStr>, 536 pub(crate) const HAS_BODY: u8 = 1 << 1;
537 pub(crate) const IS_DEFAULT: u8 = 1 << 2;
538 pub(crate) const IS_CONST: u8 = 1 << 3;
539 pub(crate) const IS_ASYNC: u8 = 1 << 4;
540 pub(crate) const IS_UNSAFE: u8 = 1 << 5;
541 /// Whether the function is located in an `extern` block (*not* whether it is an
542 /// `extern "abi" fn`).
543 pub(crate) const IS_IN_EXTERN_BLOCK: u8 = 1 << 6;
544 pub(crate) const IS_VARARGS: u8 = 1 << 7;
620} 545}
621 546
622#[derive(Debug, Clone, Eq, PartialEq)] 547#[derive(Debug, Clone, Eq, PartialEq)]
623pub struct Struct { 548pub struct Struct {
624 pub name: Name, 549 pub name: Name,
625 pub visibility: RawVisibilityId, 550 pub visibility: RawVisibilityId,
626 pub generic_params: GenericParamsId, 551 pub generic_params: Interned<GenericParams>,
627 pub fields: Fields, 552 pub fields: Fields,
628 pub ast_id: FileAstId<ast::Struct>, 553 pub ast_id: FileAstId<ast::Struct>,
629 pub kind: StructDefKind, 554 pub kind: StructDefKind,
@@ -643,7 +568,7 @@ pub enum StructDefKind {
643pub struct Union { 568pub struct Union {
644 pub name: Name, 569 pub name: Name,
645 pub visibility: RawVisibilityId, 570 pub visibility: RawVisibilityId,
646 pub generic_params: GenericParamsId, 571 pub generic_params: Interned<GenericParams>,
647 pub fields: Fields, 572 pub fields: Fields,
648 pub ast_id: FileAstId<ast::Union>, 573 pub ast_id: FileAstId<ast::Union>,
649} 574}
@@ -652,7 +577,7 @@ pub struct Union {
652pub struct Enum { 577pub struct Enum {
653 pub name: Name, 578 pub name: Name,
654 pub visibility: RawVisibilityId, 579 pub visibility: RawVisibilityId,
655 pub generic_params: GenericParamsId, 580 pub generic_params: Interned<GenericParams>,
656 pub variants: IdRange<Variant>, 581 pub variants: IdRange<Variant>,
657 pub ast_id: FileAstId<ast::Enum>, 582 pub ast_id: FileAstId<ast::Enum>,
658} 583}
@@ -662,7 +587,7 @@ pub struct Const {
662 /// const _: () = (); 587 /// const _: () = ();
663 pub name: Option<Name>, 588 pub name: Option<Name>,
664 pub visibility: RawVisibilityId, 589 pub visibility: RawVisibilityId,
665 pub type_ref: Idx<TypeRef>, 590 pub type_ref: Interned<TypeRef>,
666 pub ast_id: FileAstId<ast::Const>, 591 pub ast_id: FileAstId<ast::Const>,
667} 592}
668 593
@@ -673,7 +598,7 @@ pub struct Static {
673 pub mutable: bool, 598 pub mutable: bool,
674 /// Whether the static is in an `extern` block. 599 /// Whether the static is in an `extern` block.
675 pub is_extern: bool, 600 pub is_extern: bool,
676 pub type_ref: Idx<TypeRef>, 601 pub type_ref: Interned<TypeRef>,
677 pub ast_id: FileAstId<ast::Static>, 602 pub ast_id: FileAstId<ast::Static>,
678} 603}
679 604
@@ -681,7 +606,7 @@ pub struct Static {
681pub struct Trait { 606pub struct Trait {
682 pub name: Name, 607 pub name: Name,
683 pub visibility: RawVisibilityId, 608 pub visibility: RawVisibilityId,
684 pub generic_params: GenericParamsId, 609 pub generic_params: Interned<GenericParams>,
685 pub is_auto: bool, 610 pub is_auto: bool,
686 pub is_unsafe: bool, 611 pub is_unsafe: bool,
687 pub bounds: Box<[TypeBound]>, 612 pub bounds: Box<[TypeBound]>,
@@ -691,9 +616,9 @@ pub struct Trait {
691 616
692#[derive(Debug, Clone, Eq, PartialEq)] 617#[derive(Debug, Clone, Eq, PartialEq)]
693pub struct Impl { 618pub struct Impl {
694 pub generic_params: GenericParamsId, 619 pub generic_params: Interned<GenericParams>,
695 pub target_trait: Option<Idx<TypeRef>>, 620 pub target_trait: Option<Interned<TraitRef>>,
696 pub target_type: Idx<TypeRef>, 621 pub self_ty: Interned<TypeRef>,
697 pub is_negative: bool, 622 pub is_negative: bool,
698 pub items: Box<[AssocItem]>, 623 pub items: Box<[AssocItem]>,
699 pub ast_id: FileAstId<ast::Impl>, 624 pub ast_id: FileAstId<ast::Impl>,
@@ -705,8 +630,8 @@ pub struct TypeAlias {
705 pub visibility: RawVisibilityId, 630 pub visibility: RawVisibilityId,
706 /// Bounds on the type alias itself. Only valid in trait declarations, eg. `type Assoc: Copy;`. 631 /// Bounds on the type alias itself. Only valid in trait declarations, eg. `type Assoc: Copy;`.
707 pub bounds: Box<[TypeBound]>, 632 pub bounds: Box<[TypeBound]>,
708 pub generic_params: GenericParamsId, 633 pub generic_params: Interned<GenericParams>,
709 pub type_ref: Option<Idx<TypeRef>>, 634 pub type_ref: Option<Interned<TypeRef>>,
710 pub is_extern: bool, 635 pub is_extern: bool,
711 pub ast_id: FileAstId<ast::TypeAlias>, 636 pub ast_id: FileAstId<ast::TypeAlias>,
712} 637}
@@ -731,7 +656,7 @@ pub enum ModKind {
731#[derive(Debug, Clone, Eq, PartialEq)] 656#[derive(Debug, Clone, Eq, PartialEq)]
732pub struct MacroCall { 657pub struct MacroCall {
733 /// Path to the called macro. 658 /// Path to the called macro.
734 pub path: ModPath, 659 pub path: Interned<ModPath>,
735 pub ast_id: FileAstId<ast::MacroCall>, 660 pub ast_id: FileAstId<ast::MacroCall>,
736} 661}
737 662
@@ -896,6 +821,6 @@ pub enum Fields {
896#[derive(Debug, Clone, PartialEq, Eq)] 821#[derive(Debug, Clone, PartialEq, Eq)]
897pub struct Field { 822pub struct Field {
898 pub name: Name, 823 pub name: Name,
899 pub type_ref: Idx<TypeRef>, 824 pub type_ref: Interned<TypeRef>,
900 pub visibility: RawVisibilityId, 825 pub visibility: RawVisibilityId,
901} 826}