diff options
Diffstat (limited to 'crates/hir_def/src/item_tree.rs')
-rw-r--r-- | crates/hir_def/src/item_tree.rs | 154 |
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}; | |||
24 | use profile::Count; | 24 | use profile::Count; |
25 | use rustc_hash::FxHashMap; | 25 | use rustc_hash::FxHashMap; |
26 | use smallvec::SmallVec; | 26 | use smallvec::SmallVec; |
27 | use syntax::{ast, match_ast, SmolStr, SyntaxKind}; | 27 | use syntax::{ast, match_ast, SyntaxKind}; |
28 | 28 | ||
29 | use crate::{ | 29 | use 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)] | ||
61 | pub struct GenericParamsId(u32); | ||
62 | |||
63 | impl 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)] |
69 | pub struct ItemTree { | 63 | pub 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 | |||
244 | static VIS_PUB_CRATE: RawVisibility = RawVisibility::Module(ModPath::from_kind(PathKind::Crate)); | 233 | static 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)] |
247 | struct GenericParamsStorage { | ||
248 | arena: Arena<GenericParams>, | ||
249 | } | ||
250 | |||
251 | impl 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 | |||
265 | static 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)] | ||
274 | struct TypeRefStorage { | ||
275 | arena: Arena<Arc<TypeRef>>, | ||
276 | map: FxHashMap<Arc<TypeRef>, Idx<Arc<TypeRef>>>, | ||
277 | } | ||
278 | |||
279 | impl 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)] | ||
299 | struct ItemTreeData { | 236 | struct 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 | ||
540 | impl 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 | |||
551 | impl 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 | |||
559 | impl<N: ItemTreeNode> Index<FileItemTreeId<N>> for ItemTree { | 475 | impl<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)] |
568 | pub struct Import { | 484 | pub 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 { | |||
592 | pub struct Function { | 508 | pub 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)] |
608 | pub enum Param { | 520 | pub 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)] |
614 | pub struct FunctionQualifier { | 526 | pub(crate) struct FnFlags { |
615 | pub is_default: bool, | 527 | pub(crate) bits: u8, |
616 | pub is_const: bool, | 528 | } |
617 | pub is_async: bool, | 529 | impl 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)] |
623 | pub struct Struct { | 543 | pub 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 { | |||
643 | pub struct Union { | 563 | pub 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 { | |||
652 | pub struct Enum { | 572 | pub 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 { | |||
681 | pub struct Trait { | 601 | pub 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)] |
693 | pub struct Impl { | 613 | pub 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)] |
732 | pub struct MacroCall { | 652 | pub 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)] |
897 | pub struct Field { | 817 | pub 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 | } |