diff options
Diffstat (limited to 'crates/hir_def/src/item_tree.rs')
-rw-r--r-- | crates/hir_def/src/item_tree.rs | 159 |
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}; | |||
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 { |
@@ -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 | |||
244 | static VIS_PUB_CRATE: RawVisibility = RawVisibility::Module(ModPath::from_kind(PathKind::Crate)); | 238 | static 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)] |
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 { | 241 | struct 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 | ||
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 { | 480 | impl<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)] |
568 | pub struct Import { | 489 | pub 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 { | |||
592 | pub struct Function { | 513 | pub 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)] |
608 | pub enum Param { | 525 | pub 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)] |
614 | pub struct FunctionQualifier { | 531 | pub(crate) struct FnFlags { |
615 | pub is_default: bool, | 532 | pub(crate) bits: u8, |
616 | pub is_const: bool, | 533 | } |
617 | pub is_async: bool, | 534 | impl 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)] |
623 | pub struct Struct { | 548 | pub 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 { | |||
643 | pub struct Union { | 568 | pub 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 { | |||
652 | pub struct Enum { | 577 | pub 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 { | |||
681 | pub struct Trait { | 606 | pub 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)] |
693 | pub struct Impl { | 618 | pub 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)] |
732 | pub struct MacroCall { | 657 | pub 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)] |
897 | pub struct Field { | 822 | pub 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 | } |