Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-def/src/body.rs')
| -rw-r--r-- | crates/hir-def/src/body.rs | 112 |
1 files changed, 62 insertions, 50 deletions
diff --git a/crates/hir-def/src/body.rs b/crates/hir-def/src/body.rs index 139e1ba896..334177751e 100644 --- a/crates/hir-def/src/body.rs +++ b/crates/hir-def/src/body.rs @@ -25,8 +25,8 @@ use crate::{ db::DefDatabase, expander::Expander, hir::{ - dummy_expr_id, Array, AsmOperand, Binding, BindingId, Expr, ExprId, ExprOrPatId, Label, - LabelId, Pat, PatId, RecordFieldPat, Statement, + Array, AsmOperand, Binding, BindingId, Expr, ExprId, ExprOrPatId, Label, LabelId, Pat, + PatId, RecordFieldPat, Statement, }, item_tree::AttrOwner, nameres::DefMap, @@ -81,7 +81,7 @@ pub struct Body { pub body_expr: ExprId, pub types: TypesMap, /// Block expressions in this body that may contain inner items. - block_scopes: Vec<BlockId>, + block_scopes: Box<[BlockId]>, /// A map from binding to its hygiene ID. /// @@ -98,6 +98,64 @@ pub struct Body { ident_hygiene: FxHashMap<ExprOrPatId, HygieneId>, } +/// The body of an item (function, const etc.). +#[derive(Debug, Eq, PartialEq, Default)] +pub struct BodyCollector { + pub exprs: Arena<Expr>, + pub pats: Arena<Pat>, + pub bindings: Arena<Binding>, + pub labels: Arena<Label>, + pub binding_owners: FxHashMap<BindingId, ExprId>, + pub types: TypesMap, + block_scopes: Vec<BlockId>, + binding_hygiene: FxHashMap<BindingId, HygieneId>, + ident_hygiene: FxHashMap<ExprOrPatId, HygieneId>, +} + +impl BodyCollector { + fn finish( + self, + body_expr: ExprId, + self_param: Option<BindingId>, + params: Box<[PatId]>, + ) -> Body { + let Self { + block_scopes, + mut exprs, + mut labels, + mut pats, + mut bindings, + mut binding_owners, + mut binding_hygiene, + mut ident_hygiene, + mut types, + } = self; + exprs.shrink_to_fit(); + labels.shrink_to_fit(); + pats.shrink_to_fit(); + bindings.shrink_to_fit(); + binding_owners.shrink_to_fit(); + binding_hygiene.shrink_to_fit(); + ident_hygiene.shrink_to_fit(); + types.shrink_to_fit(); + + Body { + exprs, + pats, + bindings, + labels, + binding_owners, + params, + self_param, + body_expr, + types, + block_scopes: block_scopes.into_boxed_slice(), + binding_hygiene, + ident_hygiene, + } + } +} + pub type ExprPtr = AstPtr<ast::Expr>; pub type ExprSource = InFile<ExprPtr>; @@ -242,9 +300,8 @@ impl Body { }; let module = def.module(db); let expander = Expander::new(db, file_id, module); - let (mut body, mut source_map) = + let (body, mut source_map) = Body::new(db, def, expander, params, body, module.krate, is_async_fn); - body.shrink_to_fit(); source_map.shrink_to_fit(); (Arc::new(body), Arc::new(source_map)) @@ -304,32 +361,6 @@ impl Body { lower::lower(db, owner, expander, params, body, krate, is_async_fn) } - fn shrink_to_fit(&mut self) { - let Self { - body_expr: _, - params: _, - self_param: _, - block_scopes, - exprs, - labels, - pats, - bindings, - binding_owners, - binding_hygiene, - ident_hygiene, - types, - } = self; - block_scopes.shrink_to_fit(); - exprs.shrink_to_fit(); - labels.shrink_to_fit(); - pats.shrink_to_fit(); - bindings.shrink_to_fit(); - binding_owners.shrink_to_fit(); - binding_hygiene.shrink_to_fit(); - ident_hygiene.shrink_to_fit(); - types.shrink_to_fit(); - } - pub fn walk_bindings_in_pat(&self, pat_id: PatId, mut f: impl FnMut(BindingId)) { self.walk_pats(pat_id, &mut |pat| { if let Pat::Bind { id, .. } = &self[pat] { @@ -670,25 +701,6 @@ impl Body { } } -impl Default for Body { - fn default() -> Self { - Self { - body_expr: dummy_expr_id(), - exprs: Default::default(), - pats: Default::default(), - bindings: Default::default(), - labels: Default::default(), - params: Default::default(), - block_scopes: Default::default(), - binding_owners: Default::default(), - self_param: Default::default(), - binding_hygiene: Default::default(), - ident_hygiene: Default::default(), - types: Default::default(), - } - } -} - impl Index<ExprId> for Body { type Output = Expr; |