aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexandru Macovei <[email protected]>2021-03-30 21:06:57 +0100
committerAlexandru Macovei <[email protected]>2021-04-06 14:01:31 +0100
commitfb1f544e2479addd5957688e297ea04ddf0cf249 (patch)
treecad7e5fce89b5b42d46ea5c9fe6f5bc12ed7c03e
parent4bc8a018302d53951ae855ba57d07095a16ef182 (diff)
Use Box'es to reduce size of hir_def::expr::Expr from 128 to 72 bytes (on 64bit systems)
Rationale: only a minority of variants used almost half the size. By keeping large members (especially in Option) behind a box the memory cost is only payed when the large variants are needed. This reduces the size Vec<Expr> needs to allocate.
-rw-r--r--crates/hir_def/src/body/lower.rs16
-rw-r--r--crates/hir_def/src/expr.rs8
-rw-r--r--crates/hir_ty/src/infer/expr.rs10
3 files changed, 22 insertions, 12 deletions
diff --git a/crates/hir_def/src/body/lower.rs b/crates/hir_def/src/body/lower.rs
index 63e89a1f4..73e7aee33 100644
--- a/crates/hir_def/src/body/lower.rs
+++ b/crates/hir_def/src/body/lower.rs
@@ -322,8 +322,10 @@ impl ExprCollector<'_> {
322 Vec::new() 322 Vec::new()
323 }; 323 };
324 let method_name = e.name_ref().map(|nr| nr.as_name()).unwrap_or_else(Name::missing); 324 let method_name = e.name_ref().map(|nr| nr.as_name()).unwrap_or_else(Name::missing);
325 let generic_args = 325 let generic_args = e
326 e.generic_arg_list().and_then(|it| GenericArgs::from_ast(&self.ctx(), it)); 326 .generic_arg_list()
327 .and_then(|it| GenericArgs::from_ast(&self.ctx(), it))
328 .map(Box::new);
327 self.alloc_expr( 329 self.alloc_expr(
328 Expr::MethodCall { receiver, method_name, args, generic_args }, 330 Expr::MethodCall { receiver, method_name, args, generic_args },
329 syntax_ptr, 331 syntax_ptr,
@@ -385,7 +387,7 @@ impl ExprCollector<'_> {
385 self.alloc_expr(Expr::Yield { expr }, syntax_ptr) 387 self.alloc_expr(Expr::Yield { expr }, syntax_ptr)
386 } 388 }
387 ast::Expr::RecordExpr(e) => { 389 ast::Expr::RecordExpr(e) => {
388 let path = e.path().and_then(|path| self.expander.parse_path(path)); 390 let path = e.path().and_then(|path| self.expander.parse_path(path)).map(Box::new);
389 let record_lit = if let Some(nfl) = e.record_expr_field_list() { 391 let record_lit = if let Some(nfl) = e.record_expr_field_list() {
390 let fields = nfl 392 let fields = nfl
391 .fields() 393 .fields()
@@ -430,7 +432,7 @@ impl ExprCollector<'_> {
430 } 432 }
431 ast::Expr::CastExpr(e) => { 433 ast::Expr::CastExpr(e) => {
432 let expr = self.collect_expr_opt(e.expr()); 434 let expr = self.collect_expr_opt(e.expr());
433 let type_ref = TypeRef::from_ast_opt(&self.ctx(), e.ty()); 435 let type_ref = Box::new(TypeRef::from_ast_opt(&self.ctx(), e.ty()));
434 self.alloc_expr(Expr::Cast { expr, type_ref }, syntax_ptr) 436 self.alloc_expr(Expr::Cast { expr, type_ref }, syntax_ptr)
435 } 437 }
436 ast::Expr::RefExpr(e) => { 438 ast::Expr::RefExpr(e) => {
@@ -469,8 +471,10 @@ impl ExprCollector<'_> {
469 arg_types.push(type_ref); 471 arg_types.push(type_ref);
470 } 472 }
471 } 473 }
472 let ret_type = 474 let ret_type = e
473 e.ret_type().and_then(|r| r.ty()).map(|it| TypeRef::from_ast(&self.ctx(), it)); 475 .ret_type()
476 .and_then(|r| r.ty())
477 .map(|it| Box::new(TypeRef::from_ast(&self.ctx(), it)));
474 let body = self.collect_expr_opt(e.body()); 478 let body = self.collect_expr_opt(e.body());
475 self.alloc_expr(Expr::Lambda { args, arg_types, ret_type, body }, syntax_ptr) 479 self.alloc_expr(Expr::Lambda { args, arg_types, ret_type, body }, syntax_ptr)
476 } 480 }
diff --git a/crates/hir_def/src/expr.rs b/crates/hir_def/src/expr.rs
index 6c7376fad..ba00b9609 100644
--- a/crates/hir_def/src/expr.rs
+++ b/crates/hir_def/src/expr.rs
@@ -86,7 +86,7 @@ pub enum Expr {
86 receiver: ExprId, 86 receiver: ExprId,
87 method_name: Name, 87 method_name: Name,
88 args: Vec<ExprId>, 88 args: Vec<ExprId>,
89 generic_args: Option<GenericArgs>, 89 generic_args: Option<Box<GenericArgs>>,
90 }, 90 },
91 Match { 91 Match {
92 expr: ExprId, 92 expr: ExprId,
@@ -106,7 +106,7 @@ pub enum Expr {
106 expr: Option<ExprId>, 106 expr: Option<ExprId>,
107 }, 107 },
108 RecordLit { 108 RecordLit {
109 path: Option<Path>, 109 path: Option<Box<Path>>,
110 fields: Vec<RecordLitField>, 110 fields: Vec<RecordLitField>,
111 spread: Option<ExprId>, 111 spread: Option<ExprId>,
112 }, 112 },
@@ -131,7 +131,7 @@ pub enum Expr {
131 }, 131 },
132 Cast { 132 Cast {
133 expr: ExprId, 133 expr: ExprId,
134 type_ref: TypeRef, 134 type_ref: Box<TypeRef>,
135 }, 135 },
136 Ref { 136 Ref {
137 expr: ExprId, 137 expr: ExprId,
@@ -162,7 +162,7 @@ pub enum Expr {
162 Lambda { 162 Lambda {
163 args: Vec<PatId>, 163 args: Vec<PatId>,
164 arg_types: Vec<Option<TypeRef>>, 164 arg_types: Vec<Option<TypeRef>>,
165 ret_type: Option<TypeRef>, 165 ret_type: Option<Box<TypeRef>>,
166 body: ExprId, 166 body: ExprId,
167 }, 167 },
168 Tuple { 168 Tuple {
diff --git a/crates/hir_ty/src/infer/expr.rs b/crates/hir_ty/src/infer/expr.rs
index ff564106b..2fcc7c549 100644
--- a/crates/hir_ty/src/infer/expr.rs
+++ b/crates/hir_ty/src/infer/expr.rs
@@ -317,7 +317,13 @@ impl<'a> InferenceContext<'a> {
317 self.normalize_associated_types_in(ret_ty) 317 self.normalize_associated_types_in(ret_ty)
318 } 318 }
319 Expr::MethodCall { receiver, args, method_name, generic_args } => self 319 Expr::MethodCall { receiver, args, method_name, generic_args } => self
320 .infer_method_call(tgt_expr, *receiver, &args, &method_name, generic_args.as_ref()), 320 .infer_method_call(
321 tgt_expr,
322 *receiver,
323 &args,
324 &method_name,
325 generic_args.as_deref(),
326 ),
321 Expr::Match { expr, arms } => { 327 Expr::Match { expr, arms } => {
322 let input_ty = self.infer_expr(*expr, &Expectation::none()); 328 let input_ty = self.infer_expr(*expr, &Expectation::none());
323 329
@@ -398,7 +404,7 @@ impl<'a> InferenceContext<'a> {
398 TyKind::Never.intern(&Interner) 404 TyKind::Never.intern(&Interner)
399 } 405 }
400 Expr::RecordLit { path, fields, spread } => { 406 Expr::RecordLit { path, fields, spread } => {
401 let (ty, def_id) = self.resolve_variant(path.as_ref()); 407 let (ty, def_id) = self.resolve_variant(path.as_deref());
402 if let Some(variant) = def_id { 408 if let Some(variant) = def_id {
403 self.write_variant_resolution(tgt_expr.into(), variant); 409 self.write_variant_resolution(tgt_expr.into(), variant);
404 } 410 }