aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_def/src/item_tree.rs
diff options
context:
space:
mode:
authorJonas Schievink <[email protected]>2020-06-24 14:54:35 +0100
committerJonas Schievink <[email protected]>2020-06-24 15:54:21 +0100
commitabdba92334f800d236c65e543377f75327f7307a (patch)
tree61fbd8e6dd3269dcd746767bcac8ba169d6eebfc /crates/ra_hir_def/src/item_tree.rs
parent43cad21623bc5de59598a565097be9c7d8642818 (diff)
Don't allocate empty generics
Diffstat (limited to 'crates/ra_hir_def/src/item_tree.rs')
-rw-r--r--crates/ra_hir_def/src/item_tree.rs51
1 files changed, 44 insertions, 7 deletions
diff --git a/crates/ra_hir_def/src/item_tree.rs b/crates/ra_hir_def/src/item_tree.rs
index bbaa7c1f6..9e1fd904f 100644
--- a/crates/ra_hir_def/src/item_tree.rs
+++ b/crates/ra_hir_def/src/item_tree.rs
@@ -76,12 +76,37 @@ impl fmt::Debug for RawVisibilityId {
76 } 76 }
77} 77}
78 78
79#[derive(Default, Debug, Eq, PartialEq)]
80struct GenericParamsStorage {
81 arena: Arena<GenericParams>,
82}
83
84impl GenericParamsStorage {
85 fn alloc(&mut self, params: GenericParams) -> GenericParamsId {
86 if params.types.is_empty() && params.where_predicates.is_empty() {
87 return GenericParamsId::EMPTY;
88 }
89
90 GenericParamsId(self.arena.alloc(params).into_raw().into())
91 }
92}
93
94#[derive(Debug, Copy, Clone, Eq, PartialEq)]
95pub struct GenericParamsId(u32);
96
97impl GenericParamsId {
98 pub const EMPTY: Self = GenericParamsId(u32::max_value());
99}
100
79static VIS_PUB: RawVisibility = RawVisibility::Public; 101static VIS_PUB: RawVisibility = RawVisibility::Public;
80static VIS_PRIV: RawVisibility = 102static VIS_PRIV: RawVisibility =
81 RawVisibility::Module(ModPath { kind: PathKind::Super(0), segments: Vec::new() }); 103 RawVisibility::Module(ModPath { kind: PathKind::Super(0), segments: Vec::new() });
82static VIS_PUB_CRATE: RawVisibility = 104static VIS_PUB_CRATE: RawVisibility =
83 RawVisibility::Module(ModPath { kind: PathKind::Crate, segments: Vec::new() }); 105 RawVisibility::Module(ModPath { kind: PathKind::Crate, segments: Vec::new() });
84 106
107static EMPTY_GENERICS: GenericParams =
108 GenericParams { types: Arena::new(), where_predicates: Vec::new() };
109
85#[derive(Default, Debug, Eq, PartialEq)] 110#[derive(Default, Debug, Eq, PartialEq)]
86struct ItemTreeData { 111struct ItemTreeData {
87 imports: Arena<Import>, 112 imports: Arena<Import>,
@@ -102,6 +127,7 @@ struct ItemTreeData {
102 exprs: Arena<Expr>, 127 exprs: Arena<Expr>,
103 128
104 vis: ItemVisibilities, 129 vis: ItemVisibilities,
130 generics: GenericParamsStorage,
105} 131}
106 132
107#[derive(Debug, Eq, PartialEq, Hash)] 133#[derive(Debug, Eq, PartialEq, Hash)]
@@ -364,6 +390,17 @@ impl Index<RawVisibilityId> for ItemTree {
364 } 390 }
365} 391}
366 392
393impl Index<GenericParamsId> for ItemTree {
394 type Output = GenericParams;
395
396 fn index(&self, index: GenericParamsId) -> &Self::Output {
397 match index {
398 GenericParamsId::EMPTY => &EMPTY_GENERICS,
399 _ => &self.data().generics.arena[Idx::from_raw(index.0.into())],
400 }
401 }
402}
403
367impl<N: ItemTreeNode> Index<FileItemTreeId<N>> for ItemTree { 404impl<N: ItemTreeNode> Index<FileItemTreeId<N>> for ItemTree {
368 type Output = N; 405 type Output = N;
369 fn index(&self, id: FileItemTreeId<N>) -> &N { 406 fn index(&self, id: FileItemTreeId<N>) -> &N {
@@ -398,7 +435,7 @@ pub struct ExternCrate {
398pub struct Function { 435pub struct Function {
399 pub name: Name, 436 pub name: Name,
400 pub visibility: RawVisibilityId, 437 pub visibility: RawVisibilityId,
401 pub generic_params: GenericParams, 438 pub generic_params: GenericParamsId,
402 pub has_self_param: bool, 439 pub has_self_param: bool,
403 pub is_unsafe: bool, 440 pub is_unsafe: bool,
404 pub params: Vec<TypeRef>, 441 pub params: Vec<TypeRef>,
@@ -410,7 +447,7 @@ pub struct Function {
410pub struct Struct { 447pub struct Struct {
411 pub name: Name, 448 pub name: Name,
412 pub visibility: RawVisibilityId, 449 pub visibility: RawVisibilityId,
413 pub generic_params: GenericParams, 450 pub generic_params: GenericParamsId,
414 pub fields: Fields, 451 pub fields: Fields,
415 pub ast_id: FileAstId<ast::StructDef>, 452 pub ast_id: FileAstId<ast::StructDef>,
416 pub kind: StructDefKind, 453 pub kind: StructDefKind,
@@ -430,7 +467,7 @@ pub enum StructDefKind {
430pub struct Union { 467pub struct Union {
431 pub name: Name, 468 pub name: Name,
432 pub visibility: RawVisibilityId, 469 pub visibility: RawVisibilityId,
433 pub generic_params: GenericParams, 470 pub generic_params: GenericParamsId,
434 pub fields: Fields, 471 pub fields: Fields,
435 pub ast_id: FileAstId<ast::UnionDef>, 472 pub ast_id: FileAstId<ast::UnionDef>,
436} 473}
@@ -439,7 +476,7 @@ pub struct Union {
439pub struct Enum { 476pub struct Enum {
440 pub name: Name, 477 pub name: Name,
441 pub visibility: RawVisibilityId, 478 pub visibility: RawVisibilityId,
442 pub generic_params: GenericParams, 479 pub generic_params: GenericParamsId,
443 pub variants: Range<Idx<Variant>>, 480 pub variants: Range<Idx<Variant>>,
444 pub ast_id: FileAstId<ast::EnumDef>, 481 pub ast_id: FileAstId<ast::EnumDef>,
445} 482}
@@ -466,7 +503,7 @@ pub struct Static {
466pub struct Trait { 503pub struct Trait {
467 pub name: Name, 504 pub name: Name,
468 pub visibility: RawVisibilityId, 505 pub visibility: RawVisibilityId,
469 pub generic_params: GenericParams, 506 pub generic_params: GenericParamsId,
470 pub auto: bool, 507 pub auto: bool,
471 pub items: Vec<AssocItem>, 508 pub items: Vec<AssocItem>,
472 pub ast_id: FileAstId<ast::TraitDef>, 509 pub ast_id: FileAstId<ast::TraitDef>,
@@ -474,7 +511,7 @@ pub struct Trait {
474 511
475#[derive(Debug, Clone, Eq, PartialEq)] 512#[derive(Debug, Clone, Eq, PartialEq)]
476pub struct Impl { 513pub struct Impl {
477 pub generic_params: GenericParams, 514 pub generic_params: GenericParamsId,
478 pub target_trait: Option<TypeRef>, 515 pub target_trait: Option<TypeRef>,
479 pub target_type: TypeRef, 516 pub target_type: TypeRef,
480 pub is_negative: bool, 517 pub is_negative: bool,
@@ -488,7 +525,7 @@ pub struct TypeAlias {
488 pub visibility: RawVisibilityId, 525 pub visibility: RawVisibilityId,
489 /// Bounds on the type alias itself. Only valid in trait declarations, eg. `type Assoc: Copy;`. 526 /// Bounds on the type alias itself. Only valid in trait declarations, eg. `type Assoc: Copy;`.
490 pub bounds: Vec<TypeBound>, 527 pub bounds: Vec<TypeBound>,
491 pub generic_params: GenericParams, 528 pub generic_params: GenericParamsId,
492 pub type_ref: Option<TypeRef>, 529 pub type_ref: Option<TypeRef>,
493 pub ast_id: FileAstId<ast::TypeAliasDef>, 530 pub ast_id: FileAstId<ast::TypeAliasDef>,
494} 531}