diff options
author | Jonas Schievink <[email protected]> | 2020-06-24 14:36:18 +0100 |
---|---|---|
committer | Jonas Schievink <[email protected]> | 2020-06-24 15:54:20 +0100 |
commit | 43cad21623bc5de59598a565097be9c7d8642818 (patch) | |
tree | 5c467e4497824e0c67659311da7641ded7164a97 /crates/ra_hir_def/src/item_tree.rs | |
parent | 16fd4dabb754b017237127e70ef1e2b409c4f9b6 (diff) |
Don't allocate common visibilities
Diffstat (limited to 'crates/ra_hir_def/src/item_tree.rs')
-rw-r--r-- | crates/ra_hir_def/src/item_tree.rs | 87 |
1 files changed, 74 insertions, 13 deletions
diff --git a/crates/ra_hir_def/src/item_tree.rs b/crates/ra_hir_def/src/item_tree.rs index 40bb78b57..bbaa7c1f6 100644 --- a/crates/ra_hir_def/src/item_tree.rs +++ b/crates/ra_hir_def/src/item_tree.rs | |||
@@ -29,13 +29,60 @@ use crate::{ | |||
29 | attr::Attrs, | 29 | attr::Attrs, |
30 | db::DefDatabase, | 30 | db::DefDatabase, |
31 | generics::GenericParams, | 31 | generics::GenericParams, |
32 | path::{path, AssociatedTypeBinding, GenericArgs, ImportAlias, ModPath, Path}, | 32 | path::{path, AssociatedTypeBinding, GenericArgs, ImportAlias, ModPath, Path, PathKind}, |
33 | type_ref::{Mutability, TypeBound, TypeRef}, | 33 | type_ref::{Mutability, TypeBound, TypeRef}, |
34 | visibility::RawVisibility, | 34 | visibility::RawVisibility, |
35 | }; | 35 | }; |
36 | use smallvec::SmallVec; | 36 | use smallvec::SmallVec; |
37 | 37 | ||
38 | #[derive(Default, Debug, Eq, PartialEq)] | 38 | #[derive(Default, Debug, Eq, PartialEq)] |
39 | struct ItemVisibilities { | ||
40 | arena: Arena<RawVisibility>, | ||
41 | } | ||
42 | |||
43 | impl ItemVisibilities { | ||
44 | fn alloc(&mut self, vis: RawVisibility) -> RawVisibilityId { | ||
45 | match &vis { | ||
46 | RawVisibility::Public => RawVisibilityId::PUB, | ||
47 | RawVisibility::Module(path) if path.segments.is_empty() => match &path.kind { | ||
48 | PathKind::Super(0) => RawVisibilityId::PRIV, | ||
49 | PathKind::Crate => RawVisibilityId::PUB_CRATE, | ||
50 | _ => RawVisibilityId(self.arena.alloc(vis).into_raw().into()), | ||
51 | }, | ||
52 | _ => RawVisibilityId(self.arena.alloc(vis).into_raw().into()), | ||
53 | } | ||
54 | } | ||
55 | } | ||
56 | |||
57 | #[derive(Copy, Clone, Eq, PartialEq)] | ||
58 | pub struct RawVisibilityId(u32); | ||
59 | |||
60 | impl RawVisibilityId { | ||
61 | pub const PUB: Self = RawVisibilityId(u32::max_value()); | ||
62 | pub const PRIV: Self = RawVisibilityId(u32::max_value() - 1); | ||
63 | pub const PUB_CRATE: Self = RawVisibilityId(u32::max_value() - 2); | ||
64 | } | ||
65 | |||
66 | impl fmt::Debug for RawVisibilityId { | ||
67 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | ||
68 | let mut f = f.debug_tuple("RawVisibilityId"); | ||
69 | match *self { | ||
70 | Self::PUB => f.field(&"pub"), | ||
71 | Self::PRIV => f.field(&"pub(self)"), | ||
72 | Self::PUB_CRATE => f.field(&"pub(crate)"), | ||
73 | _ => f.field(&self.0), | ||
74 | }; | ||
75 | f.finish() | ||
76 | } | ||
77 | } | ||
78 | |||
79 | static VIS_PUB: RawVisibility = RawVisibility::Public; | ||
80 | static VIS_PRIV: RawVisibility = | ||
81 | RawVisibility::Module(ModPath { kind: PathKind::Super(0), segments: Vec::new() }); | ||
82 | static VIS_PUB_CRATE: RawVisibility = | ||
83 | RawVisibility::Module(ModPath { kind: PathKind::Crate, segments: Vec::new() }); | ||
84 | |||
85 | #[derive(Default, Debug, Eq, PartialEq)] | ||
39 | struct ItemTreeData { | 86 | struct ItemTreeData { |
40 | imports: Arena<Import>, | 87 | imports: Arena<Import>, |
41 | extern_crates: Arena<ExternCrate>, | 88 | extern_crates: Arena<ExternCrate>, |
@@ -53,6 +100,8 @@ struct ItemTreeData { | |||
53 | mods: Arena<Mod>, | 100 | mods: Arena<Mod>, |
54 | macro_calls: Arena<MacroCall>, | 101 | macro_calls: Arena<MacroCall>, |
55 | exprs: Arena<Expr>, | 102 | exprs: Arena<Expr>, |
103 | |||
104 | vis: ItemVisibilities, | ||
56 | } | 105 | } |
57 | 106 | ||
58 | #[derive(Debug, Eq, PartialEq, Hash)] | 107 | #[derive(Debug, Eq, PartialEq, Hash)] |
@@ -303,6 +352,18 @@ macro_rules! impl_index { | |||
303 | 352 | ||
304 | impl_index!(fields: Field, variants: Variant, exprs: Expr); | 353 | impl_index!(fields: Field, variants: Variant, exprs: Expr); |
305 | 354 | ||
355 | impl Index<RawVisibilityId> for ItemTree { | ||
356 | type Output = RawVisibility; | ||
357 | fn index(&self, index: RawVisibilityId) -> &Self::Output { | ||
358 | match index { | ||
359 | RawVisibilityId::PRIV => &VIS_PRIV, | ||
360 | RawVisibilityId::PUB => &VIS_PUB, | ||
361 | RawVisibilityId::PUB_CRATE => &VIS_PUB_CRATE, | ||
362 | _ => &self.data().vis.arena[Idx::from_raw(index.0.into())], | ||
363 | } | ||
364 | } | ||
365 | } | ||
366 | |||
306 | impl<N: ItemTreeNode> Index<FileItemTreeId<N>> for ItemTree { | 367 | impl<N: ItemTreeNode> Index<FileItemTreeId<N>> for ItemTree { |
307 | type Output = N; | 368 | type Output = N; |
308 | fn index(&self, id: FileItemTreeId<N>) -> &N { | 369 | fn index(&self, id: FileItemTreeId<N>) -> &N { |
@@ -315,7 +376,7 @@ impl<N: ItemTreeNode> Index<FileItemTreeId<N>> for ItemTree { | |||
315 | pub struct Import { | 376 | pub struct Import { |
316 | pub path: ModPath, | 377 | pub path: ModPath, |
317 | pub alias: Option<ImportAlias>, | 378 | pub alias: Option<ImportAlias>, |
318 | pub visibility: RawVisibility, | 379 | pub visibility: RawVisibilityId, |
319 | pub is_glob: bool, | 380 | pub is_glob: bool, |
320 | pub is_prelude: bool, | 381 | pub is_prelude: bool, |
321 | /// AST ID of the `use` or `extern crate` item this import was derived from. Note that many | 382 | /// AST ID of the `use` or `extern crate` item this import was derived from. Note that many |
@@ -327,7 +388,7 @@ pub struct Import { | |||
327 | pub struct ExternCrate { | 388 | pub struct ExternCrate { |
328 | pub path: ModPath, | 389 | pub path: ModPath, |
329 | pub alias: Option<ImportAlias>, | 390 | pub alias: Option<ImportAlias>, |
330 | pub visibility: RawVisibility, | 391 | pub visibility: RawVisibilityId, |
331 | /// Whether this is a `#[macro_use] extern crate ...`. | 392 | /// Whether this is a `#[macro_use] extern crate ...`. |
332 | pub is_macro_use: bool, | 393 | pub is_macro_use: bool, |
333 | pub ast_id: FileAstId<ast::ExternCrateItem>, | 394 | pub ast_id: FileAstId<ast::ExternCrateItem>, |
@@ -336,7 +397,7 @@ pub struct ExternCrate { | |||
336 | #[derive(Debug, Clone, Eq, PartialEq)] | 397 | #[derive(Debug, Clone, Eq, PartialEq)] |
337 | pub struct Function { | 398 | pub struct Function { |
338 | pub name: Name, | 399 | pub name: Name, |
339 | pub visibility: RawVisibility, | 400 | pub visibility: RawVisibilityId, |
340 | pub generic_params: GenericParams, | 401 | pub generic_params: GenericParams, |
341 | pub has_self_param: bool, | 402 | pub has_self_param: bool, |
342 | pub is_unsafe: bool, | 403 | pub is_unsafe: bool, |
@@ -348,7 +409,7 @@ pub struct Function { | |||
348 | #[derive(Debug, Clone, Eq, PartialEq)] | 409 | #[derive(Debug, Clone, Eq, PartialEq)] |
349 | pub struct Struct { | 410 | pub struct Struct { |
350 | pub name: Name, | 411 | pub name: Name, |
351 | pub visibility: RawVisibility, | 412 | pub visibility: RawVisibilityId, |
352 | pub generic_params: GenericParams, | 413 | pub generic_params: GenericParams, |
353 | pub fields: Fields, | 414 | pub fields: Fields, |
354 | pub ast_id: FileAstId<ast::StructDef>, | 415 | pub ast_id: FileAstId<ast::StructDef>, |
@@ -368,7 +429,7 @@ pub enum StructDefKind { | |||
368 | #[derive(Debug, Clone, Eq, PartialEq)] | 429 | #[derive(Debug, Clone, Eq, PartialEq)] |
369 | pub struct Union { | 430 | pub struct Union { |
370 | pub name: Name, | 431 | pub name: Name, |
371 | pub visibility: RawVisibility, | 432 | pub visibility: RawVisibilityId, |
372 | pub generic_params: GenericParams, | 433 | pub generic_params: GenericParams, |
373 | pub fields: Fields, | 434 | pub fields: Fields, |
374 | pub ast_id: FileAstId<ast::UnionDef>, | 435 | pub ast_id: FileAstId<ast::UnionDef>, |
@@ -377,7 +438,7 @@ pub struct Union { | |||
377 | #[derive(Debug, Clone, Eq, PartialEq)] | 438 | #[derive(Debug, Clone, Eq, PartialEq)] |
378 | pub struct Enum { | 439 | pub struct Enum { |
379 | pub name: Name, | 440 | pub name: Name, |
380 | pub visibility: RawVisibility, | 441 | pub visibility: RawVisibilityId, |
381 | pub generic_params: GenericParams, | 442 | pub generic_params: GenericParams, |
382 | pub variants: Range<Idx<Variant>>, | 443 | pub variants: Range<Idx<Variant>>, |
383 | pub ast_id: FileAstId<ast::EnumDef>, | 444 | pub ast_id: FileAstId<ast::EnumDef>, |
@@ -387,7 +448,7 @@ pub struct Enum { | |||
387 | pub struct Const { | 448 | pub struct Const { |
388 | /// const _: () = (); | 449 | /// const _: () = (); |
389 | pub name: Option<Name>, | 450 | pub name: Option<Name>, |
390 | pub visibility: RawVisibility, | 451 | pub visibility: RawVisibilityId, |
391 | pub type_ref: TypeRef, | 452 | pub type_ref: TypeRef, |
392 | pub ast_id: FileAstId<ast::ConstDef>, | 453 | pub ast_id: FileAstId<ast::ConstDef>, |
393 | } | 454 | } |
@@ -395,7 +456,7 @@ pub struct Const { | |||
395 | #[derive(Debug, Clone, Eq, PartialEq)] | 456 | #[derive(Debug, Clone, Eq, PartialEq)] |
396 | pub struct Static { | 457 | pub struct Static { |
397 | pub name: Name, | 458 | pub name: Name, |
398 | pub visibility: RawVisibility, | 459 | pub visibility: RawVisibilityId, |
399 | pub mutable: bool, | 460 | pub mutable: bool, |
400 | pub type_ref: TypeRef, | 461 | pub type_ref: TypeRef, |
401 | pub ast_id: FileAstId<ast::StaticDef>, | 462 | pub ast_id: FileAstId<ast::StaticDef>, |
@@ -404,7 +465,7 @@ pub struct Static { | |||
404 | #[derive(Debug, Clone, Eq, PartialEq)] | 465 | #[derive(Debug, Clone, Eq, PartialEq)] |
405 | pub struct Trait { | 466 | pub struct Trait { |
406 | pub name: Name, | 467 | pub name: Name, |
407 | pub visibility: RawVisibility, | 468 | pub visibility: RawVisibilityId, |
408 | pub generic_params: GenericParams, | 469 | pub generic_params: GenericParams, |
409 | pub auto: bool, | 470 | pub auto: bool, |
410 | pub items: Vec<AssocItem>, | 471 | pub items: Vec<AssocItem>, |
@@ -424,7 +485,7 @@ pub struct Impl { | |||
424 | #[derive(Debug, Clone, PartialEq, Eq)] | 485 | #[derive(Debug, Clone, PartialEq, Eq)] |
425 | pub struct TypeAlias { | 486 | pub struct TypeAlias { |
426 | pub name: Name, | 487 | pub name: Name, |
427 | pub visibility: RawVisibility, | 488 | pub visibility: RawVisibilityId, |
428 | /// Bounds on the type alias itself. Only valid in trait declarations, eg. `type Assoc: Copy;`. | 489 | /// Bounds on the type alias itself. Only valid in trait declarations, eg. `type Assoc: Copy;`. |
429 | pub bounds: Vec<TypeBound>, | 490 | pub bounds: Vec<TypeBound>, |
430 | pub generic_params: GenericParams, | 491 | pub generic_params: GenericParams, |
@@ -435,7 +496,7 @@ pub struct TypeAlias { | |||
435 | #[derive(Debug, Clone, Eq, PartialEq)] | 496 | #[derive(Debug, Clone, Eq, PartialEq)] |
436 | pub struct Mod { | 497 | pub struct Mod { |
437 | pub name: Name, | 498 | pub name: Name, |
438 | pub visibility: RawVisibility, | 499 | pub visibility: RawVisibilityId, |
439 | pub kind: ModKind, | 500 | pub kind: ModKind, |
440 | pub ast_id: FileAstId<ast::Module>, | 501 | pub ast_id: FileAstId<ast::Module>, |
441 | } | 502 | } |
@@ -549,5 +610,5 @@ pub enum Fields { | |||
549 | pub struct Field { | 610 | pub struct Field { |
550 | pub name: Name, | 611 | pub name: Name, |
551 | pub type_ref: TypeRef, | 612 | pub type_ref: TypeRef, |
552 | pub visibility: RawVisibility, | 613 | pub visibility: RawVisibilityId, |
553 | } | 614 | } |