mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-10-01 14:21:44 +00:00
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.
This commit is contained in:
parent
4bc8a01830
commit
fb1f544e24
3 changed files with 22 additions and 12 deletions
|
@ -322,8 +322,10 @@ impl ExprCollector<'_> {
|
||||||
Vec::new()
|
Vec::new()
|
||||||
};
|
};
|
||||||
let method_name = e.name_ref().map(|nr| nr.as_name()).unwrap_or_else(Name::missing);
|
let method_name = e.name_ref().map(|nr| nr.as_name()).unwrap_or_else(Name::missing);
|
||||||
let generic_args =
|
let generic_args = e
|
||||||
e.generic_arg_list().and_then(|it| GenericArgs::from_ast(&self.ctx(), it));
|
.generic_arg_list()
|
||||||
|
.and_then(|it| GenericArgs::from_ast(&self.ctx(), it))
|
||||||
|
.map(Box::new);
|
||||||
self.alloc_expr(
|
self.alloc_expr(
|
||||||
Expr::MethodCall { receiver, method_name, args, generic_args },
|
Expr::MethodCall { receiver, method_name, args, generic_args },
|
||||||
syntax_ptr,
|
syntax_ptr,
|
||||||
|
@ -385,7 +387,7 @@ impl ExprCollector<'_> {
|
||||||
self.alloc_expr(Expr::Yield { expr }, syntax_ptr)
|
self.alloc_expr(Expr::Yield { expr }, syntax_ptr)
|
||||||
}
|
}
|
||||||
ast::Expr::RecordExpr(e) => {
|
ast::Expr::RecordExpr(e) => {
|
||||||
let path = e.path().and_then(|path| self.expander.parse_path(path));
|
let path = e.path().and_then(|path| self.expander.parse_path(path)).map(Box::new);
|
||||||
let record_lit = if let Some(nfl) = e.record_expr_field_list() {
|
let record_lit = if let Some(nfl) = e.record_expr_field_list() {
|
||||||
let fields = nfl
|
let fields = nfl
|
||||||
.fields()
|
.fields()
|
||||||
|
@ -430,7 +432,7 @@ impl ExprCollector<'_> {
|
||||||
}
|
}
|
||||||
ast::Expr::CastExpr(e) => {
|
ast::Expr::CastExpr(e) => {
|
||||||
let expr = self.collect_expr_opt(e.expr());
|
let expr = self.collect_expr_opt(e.expr());
|
||||||
let type_ref = TypeRef::from_ast_opt(&self.ctx(), e.ty());
|
let type_ref = Box::new(TypeRef::from_ast_opt(&self.ctx(), e.ty()));
|
||||||
self.alloc_expr(Expr::Cast { expr, type_ref }, syntax_ptr)
|
self.alloc_expr(Expr::Cast { expr, type_ref }, syntax_ptr)
|
||||||
}
|
}
|
||||||
ast::Expr::RefExpr(e) => {
|
ast::Expr::RefExpr(e) => {
|
||||||
|
@ -469,8 +471,10 @@ impl ExprCollector<'_> {
|
||||||
arg_types.push(type_ref);
|
arg_types.push(type_ref);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let ret_type =
|
let ret_type = e
|
||||||
e.ret_type().and_then(|r| r.ty()).map(|it| TypeRef::from_ast(&self.ctx(), it));
|
.ret_type()
|
||||||
|
.and_then(|r| r.ty())
|
||||||
|
.map(|it| Box::new(TypeRef::from_ast(&self.ctx(), it)));
|
||||||
let body = self.collect_expr_opt(e.body());
|
let body = self.collect_expr_opt(e.body());
|
||||||
self.alloc_expr(Expr::Lambda { args, arg_types, ret_type, body }, syntax_ptr)
|
self.alloc_expr(Expr::Lambda { args, arg_types, ret_type, body }, syntax_ptr)
|
||||||
}
|
}
|
||||||
|
|
|
@ -86,7 +86,7 @@ pub enum Expr {
|
||||||
receiver: ExprId,
|
receiver: ExprId,
|
||||||
method_name: Name,
|
method_name: Name,
|
||||||
args: Vec<ExprId>,
|
args: Vec<ExprId>,
|
||||||
generic_args: Option<GenericArgs>,
|
generic_args: Option<Box<GenericArgs>>,
|
||||||
},
|
},
|
||||||
Match {
|
Match {
|
||||||
expr: ExprId,
|
expr: ExprId,
|
||||||
|
@ -106,7 +106,7 @@ pub enum Expr {
|
||||||
expr: Option<ExprId>,
|
expr: Option<ExprId>,
|
||||||
},
|
},
|
||||||
RecordLit {
|
RecordLit {
|
||||||
path: Option<Path>,
|
path: Option<Box<Path>>,
|
||||||
fields: Vec<RecordLitField>,
|
fields: Vec<RecordLitField>,
|
||||||
spread: Option<ExprId>,
|
spread: Option<ExprId>,
|
||||||
},
|
},
|
||||||
|
@ -131,7 +131,7 @@ pub enum Expr {
|
||||||
},
|
},
|
||||||
Cast {
|
Cast {
|
||||||
expr: ExprId,
|
expr: ExprId,
|
||||||
type_ref: TypeRef,
|
type_ref: Box<TypeRef>,
|
||||||
},
|
},
|
||||||
Ref {
|
Ref {
|
||||||
expr: ExprId,
|
expr: ExprId,
|
||||||
|
@ -162,7 +162,7 @@ pub enum Expr {
|
||||||
Lambda {
|
Lambda {
|
||||||
args: Vec<PatId>,
|
args: Vec<PatId>,
|
||||||
arg_types: Vec<Option<TypeRef>>,
|
arg_types: Vec<Option<TypeRef>>,
|
||||||
ret_type: Option<TypeRef>,
|
ret_type: Option<Box<TypeRef>>,
|
||||||
body: ExprId,
|
body: ExprId,
|
||||||
},
|
},
|
||||||
Tuple {
|
Tuple {
|
||||||
|
|
|
@ -317,7 +317,13 @@ impl<'a> InferenceContext<'a> {
|
||||||
self.normalize_associated_types_in(ret_ty)
|
self.normalize_associated_types_in(ret_ty)
|
||||||
}
|
}
|
||||||
Expr::MethodCall { receiver, args, method_name, generic_args } => self
|
Expr::MethodCall { receiver, args, method_name, generic_args } => self
|
||||||
.infer_method_call(tgt_expr, *receiver, &args, &method_name, generic_args.as_ref()),
|
.infer_method_call(
|
||||||
|
tgt_expr,
|
||||||
|
*receiver,
|
||||||
|
&args,
|
||||||
|
&method_name,
|
||||||
|
generic_args.as_deref(),
|
||||||
|
),
|
||||||
Expr::Match { expr, arms } => {
|
Expr::Match { expr, arms } => {
|
||||||
let input_ty = self.infer_expr(*expr, &Expectation::none());
|
let input_ty = self.infer_expr(*expr, &Expectation::none());
|
||||||
|
|
||||||
|
@ -398,7 +404,7 @@ impl<'a> InferenceContext<'a> {
|
||||||
TyKind::Never.intern(&Interner)
|
TyKind::Never.intern(&Interner)
|
||||||
}
|
}
|
||||||
Expr::RecordLit { path, fields, spread } => {
|
Expr::RecordLit { path, fields, spread } => {
|
||||||
let (ty, def_id) = self.resolve_variant(path.as_ref());
|
let (ty, def_id) = self.resolve_variant(path.as_deref());
|
||||||
if let Some(variant) = def_id {
|
if let Some(variant) = def_id {
|
||||||
self.write_variant_resolution(tgt_expr.into(), variant);
|
self.write_variant_resolution(tgt_expr.into(), variant);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue