aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_def/src/item_tree
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2021-02-04 18:33:57 +0000
committerGitHub <[email protected]>2021-02-04 18:33:57 +0000
commit36191543a679d4e01c206d2e98a2d7ae170a25e2 (patch)
tree91431506bde2965c819030eea14433926b82310f /crates/hir_def/src/item_tree
parent663d404a4ee52cf96e0de793e45290be1a43dcb5 (diff)
parent003ee0086ae424ec43ad14cd90af9cd5809a93c8 (diff)
Merge #7557
7557: Intern `TypeRef`s in the containing `ItemTree` r=jonas-schievink a=jonas-schievink This reduces the memory used by `ItemTreeQuery` by ~20%. As it turns out, `TypeRef` is very heavy, and is used a lot in `ItemTree`: * Many types are frequently repeated throughout the same file. This is what this PR addresses by storing identical `TypeRef`s only once per `ItemTree`. * The vast majority of `TypeRef` consist of a plain path with only a single element. "Type anchors" like in `<Ty>::func` are used incredibly rarely, and even multi-segment paths are much rarer than single-segment paths. Co-authored-by: Jonas Schievink <[email protected]>
Diffstat (limited to 'crates/hir_def/src/item_tree')
-rw-r--r--crates/hir_def/src/item_tree/lower.rs18
1 files changed, 13 insertions, 5 deletions
diff --git a/crates/hir_def/src/item_tree/lower.rs b/crates/hir_def/src/item_tree/lower.rs
index de2177933..93cdca55d 100644
--- a/crates/hir_def/src/item_tree/lower.rs
+++ b/crates/hir_def/src/item_tree/lower.rs
@@ -364,6 +364,7 @@ impl Ctx {
364 params.push(type_ref); 364 params.push(type_ref);
365 } 365 }
366 } 366 }
367 let params = params.into_iter().map(|param| self.data().type_refs.intern(param)).collect();
367 368
368 let mut is_varargs = false; 369 let mut is_varargs = false;
369 if let Some(params) = func.param_list() { 370 if let Some(params) = func.param_list() {
@@ -385,6 +386,8 @@ impl Ctx {
385 ret_type 386 ret_type
386 }; 387 };
387 388
389 let ret_type = self.data().type_refs.intern(ret_type);
390
388 let has_body = func.body().is_some(); 391 let has_body = func.body().is_some();
389 392
390 let ast_id = self.source_ast_id_map.ast_id(func); 393 let ast_id = self.source_ast_id_map.ast_id(func);
@@ -396,7 +399,7 @@ impl Ctx {
396 has_body, 399 has_body,
397 is_unsafe: func.unsafe_token().is_some(), 400 is_unsafe: func.unsafe_token().is_some(),
398 is_extern: false, 401 is_extern: false,
399 params: params.into_boxed_slice(), 402 params,
400 is_varargs, 403 is_varargs,
401 ret_type, 404 ret_type,
402 ast_id, 405 ast_id,
@@ -657,6 +660,7 @@ impl Ctx {
657 generics.fill(&self.body_ctx, sm, node); 660 generics.fill(&self.body_ctx, sm, node);
658 // lower `impl Trait` in arguments 661 // lower `impl Trait` in arguments
659 for param in &*func.params { 662 for param in &*func.params {
663 let param = self.data().type_refs.lookup(*param);
660 generics.fill_implicit_impl_trait_args(param); 664 generics.fill_implicit_impl_trait_args(param);
661 } 665 }
662 } 666 }
@@ -709,11 +713,15 @@ impl Ctx {
709 self.data().vis.alloc(vis) 713 self.data().vis.alloc(vis)
710 } 714 }
711 715
712 fn lower_type_ref(&self, type_ref: &ast::Type) -> TypeRef { 716 fn lower_type_ref(&mut self, type_ref: &ast::Type) -> Idx<TypeRef> {
713 TypeRef::from_ast(&self.body_ctx, type_ref.clone()) 717 let tyref = TypeRef::from_ast(&self.body_ctx, type_ref.clone());
718 self.data().type_refs.intern(tyref)
714 } 719 }
715 fn lower_type_ref_opt(&self, type_ref: Option<ast::Type>) -> TypeRef { 720 fn lower_type_ref_opt(&mut self, type_ref: Option<ast::Type>) -> Idx<TypeRef> {
716 type_ref.map(|ty| self.lower_type_ref(&ty)).unwrap_or(TypeRef::Error) 721 match type_ref.map(|ty| self.lower_type_ref(&ty)) {
722 Some(it) => it,
723 None => self.data().type_refs.intern(TypeRef::Error),
724 }
717 } 725 }
718 726
719 /// Forces the visibility `vis` to be used for all items lowered during execution of `f`. 727 /// Forces the visibility `vis` to be used for all items lowered during execution of `f`.