From 6012e961a784dec321296385b38551ce73822e8d Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Sat, 25 Jan 2025 14:27:47 +0100 Subject: [PATCH 1/5] Combine `pat_hyigene` and `expr_hygiene` --- crates/hir-def/src/body.rs | 20 ++++++++------------ crates/hir-def/src/body/lower.rs | 6 +++--- crates/hir-def/src/hir.rs | 2 ++ 3 files changed, 13 insertions(+), 15 deletions(-) diff --git a/crates/hir-def/src/body.rs b/crates/hir-def/src/body.rs index de4392493063..139e1ba896ce 100644 --- a/crates/hir-def/src/body.rs +++ b/crates/hir-def/src/body.rs @@ -3,6 +3,7 @@ mod lower; mod pretty; pub mod scope; + #[cfg(test)] mod tests; @@ -92,11 +93,9 @@ pub struct Body { binding_hygiene: FxHashMap, /// A map from an variable usages to their hygiene ID. /// - /// Expressions that can be recorded here are single segment path, although not all single segments path refer + /// Expressions (and destructuing patterns) that can be recorded here are single segment path, although not all single segments path refer /// to variables and have hygiene (some refer to items, we don't know at this stage). - expr_hygiene: FxHashMap, - /// A map from a destructuring assignment possible variable usages to their hygiene ID. - pat_hygiene: FxHashMap, + ident_hygiene: FxHashMap, } pub type ExprPtr = AstPtr; @@ -317,8 +316,7 @@ impl Body { bindings, binding_owners, binding_hygiene, - expr_hygiene, - pat_hygiene, + ident_hygiene, types, } = self; block_scopes.shrink_to_fit(); @@ -328,8 +326,7 @@ impl Body { bindings.shrink_to_fit(); binding_owners.shrink_to_fit(); binding_hygiene.shrink_to_fit(); - expr_hygiene.shrink_to_fit(); - pat_hygiene.shrink_to_fit(); + ident_hygiene.shrink_to_fit(); types.shrink_to_fit(); } @@ -658,11 +655,11 @@ impl Body { } pub fn expr_path_hygiene(&self, expr: ExprId) -> HygieneId { - self.expr_hygiene.get(&expr).copied().unwrap_or(HygieneId::ROOT) + self.ident_hygiene.get(&expr.into()).copied().unwrap_or(HygieneId::ROOT) } pub fn pat_path_hygiene(&self, pat: PatId) -> HygieneId { - self.pat_hygiene.get(&pat).copied().unwrap_or(HygieneId::ROOT) + self.ident_hygiene.get(&pat.into()).copied().unwrap_or(HygieneId::ROOT) } pub fn expr_or_pat_path_hygiene(&self, id: ExprOrPatId) -> HygieneId { @@ -686,8 +683,7 @@ impl Default for Body { binding_owners: Default::default(), self_param: Default::default(), binding_hygiene: Default::default(), - expr_hygiene: Default::default(), - pat_hygiene: Default::default(), + ident_hygiene: Default::default(), types: Default::default(), } } diff --git a/crates/hir-def/src/body/lower.rs b/crates/hir-def/src/body/lower.rs index 16c7b5ca00a0..583c6ac5e8c7 100644 --- a/crates/hir-def/src/body/lower.rs +++ b/crates/hir-def/src/body/lower.rs @@ -480,7 +480,7 @@ impl ExprCollector<'_> { .unwrap_or((Expr::Missing, HygieneId::ROOT)); let expr_id = self.alloc_expr(path, syntax_ptr); if !hygiene.is_root() { - self.body.expr_hygiene.insert(expr_id, hygiene); + self.body.ident_hygiene.insert(expr_id.into(), hygiene); } expr_id } @@ -835,7 +835,7 @@ impl ExprCollector<'_> { .unwrap_or((Pat::Missing, HygieneId::ROOT)); let pat_id = self.alloc_pat_from_expr(path, syntax_ptr); if !hygiene.is_root() { - self.body.pat_hygiene.insert(pat_id, hygiene); + self.body.ident_hygiene.insert(pat_id.into(), hygiene); } pat_id } @@ -2023,7 +2023,7 @@ impl ExprCollector<'_> { ); } if !hygiene.is_root() { - self.body.expr_hygiene.insert(expr_id, hygiene); + self.body.ident_hygiene.insert(expr_id.into(), hygiene); } expr_id }, diff --git a/crates/hir-def/src/hir.rs b/crates/hir-def/src/hir.rs index 859634694302..9392e8d12d40 100644 --- a/crates/hir-def/src/hir.rs +++ b/crates/hir-def/src/hir.rs @@ -44,6 +44,8 @@ pub(crate) fn dummy_expr_id() -> ExprId { pub type PatId = Idx; +// FIXME: Encode this as a single u32, we won't ever reach all 32 bits especially given these counts +// are local to the body. #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] pub enum ExprOrPatId { ExprId(ExprId), From 724455bf5a6bfd5d7201215ec64263d79262aef4 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Sat, 25 Jan 2025 14:43:22 +0100 Subject: [PATCH 2/5] BodyCollector --- crates/hir-def/src/body.rs | 112 +++++++++++++++++-------------- crates/hir-def/src/body/lower.rs | 49 ++++++++------ crates/hir-def/src/hir.rs | 7 +- 3 files changed, 91 insertions(+), 77 deletions(-) diff --git a/crates/hir-def/src/body.rs b/crates/hir-def/src/body.rs index 139e1ba896ce..334177751e4c 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, + block_scopes: Box<[BlockId]>, /// A map from binding to its hygiene ID. /// @@ -98,6 +98,64 @@ pub struct Body { ident_hygiene: FxHashMap, } +/// The body of an item (function, const etc.). +#[derive(Debug, Eq, PartialEq, Default)] +pub struct BodyCollector { + pub exprs: Arena, + pub pats: Arena, + pub bindings: Arena, + pub labels: Arena