Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-def/src/expr_store/scope.rs')
| -rw-r--r-- | crates/hir-def/src/expr_store/scope.rs | 70 |
1 files changed, 41 insertions, 29 deletions
diff --git a/crates/hir-def/src/expr_store/scope.rs b/crates/hir-def/src/expr_store/scope.rs index c881a961b1..3ce0ed44da 100644 --- a/crates/hir-def/src/expr_store/scope.rs +++ b/crates/hir-def/src/expr_store/scope.rs @@ -46,13 +46,18 @@ impl ScopeEntry { #[derive(Debug, PartialEq, Eq)] pub struct ScopeData { parent: Option<ScopeId>, - block: Option<BlockId>, - label: Option<(LabelId, Name)>, - // FIXME: We can compress this with an enum for this and `label`/`block` if memory usage matters. - macro_def: Option<Box<MacroDefId>>, + kind: ScopeKind, entries: IdxRange<ScopeEntry>, } +#[derive(Debug, PartialEq, Eq)] +enum ScopeKind { + None, + Block { id: BlockId, label: Option<LabelId> }, + Label(LabelId), + MacroDef(Box<MacroDefId>), +} + #[salsa::tracked] impl ExprScopes { #[salsa::tracked(returns(ref))] @@ -100,18 +105,28 @@ impl ExprScopes { /// If `scope` refers to a block expression scope, returns the corresponding `BlockId`. pub fn block(&self, scope: ScopeId) -> Option<BlockId> { - self.scopes[scope].block + match self.scopes[scope].kind { + ScopeKind::Block { id, label: _ } => Some(id), + ScopeKind::None | ScopeKind::Label(_) | ScopeKind::MacroDef(_) => None, + } } /// If `scope` refers to a macro def scope, returns the corresponding `MacroId`. #[allow(clippy::borrowed_box)] // If we return `&MacroDefId` we need to move it, this way we just clone the `Box`. pub fn macro_def(&self, scope: ScopeId) -> Option<&Box<MacroDefId>> { - self.scopes[scope].macro_def.as_ref() + match &self.scopes[scope].kind { + ScopeKind::MacroDef(macro_def) => Some(macro_def), + ScopeKind::None | ScopeKind::Block { id: _, label: _ } | ScopeKind::Label(_) => None, + } } /// If `scope` refers to a labeled expression scope, returns the corresponding `Label`. - pub fn label(&self, scope: ScopeId) -> Option<(LabelId, Name)> { - self.scopes[scope].label.clone() + pub fn label(&self, scope: ScopeId) -> Option<LabelId> { + match &self.scopes[scope].kind { + &ScopeKind::Block { id: _, label } => label, + &ScopeKind::Label(label) => Some(label), + ScopeKind::None | ScopeKind::MacroDef(_) => None, + } } /// Returns the scopes in ascending order. @@ -174,9 +189,7 @@ impl ExprScopes { fn root_scope(&mut self) -> ScopeId { self.scopes.alloc(ScopeData { parent: None, - block: None, - label: None, - macro_def: None, + kind: ScopeKind::None, entries: empty_entries(self.scope_entries.len()), }) } @@ -184,19 +197,19 @@ impl ExprScopes { fn new_scope(&mut self, parent: ScopeId) -> ScopeId { self.scopes.alloc(ScopeData { parent: Some(parent), - block: None, - label: None, - macro_def: None, + kind: ScopeKind::None, entries: empty_entries(self.scope_entries.len()), }) } - fn new_labeled_scope(&mut self, parent: ScopeId, label: Option<(LabelId, Name)>) -> ScopeId { + fn new_labeled_scope(&mut self, parent: ScopeId, label: Option<LabelId>) -> ScopeId { + let kind = match label { + Some(label) => ScopeKind::Label(label), + None => ScopeKind::None, + }; self.scopes.alloc(ScopeData { parent: Some(parent), - block: None, - label, - macro_def: None, + kind, entries: empty_entries(self.scope_entries.len()), }) } @@ -205,13 +218,16 @@ impl ExprScopes { &mut self, parent: ScopeId, block: Option<BlockId>, - label: Option<(LabelId, Name)>, + label: Option<LabelId>, ) -> ScopeId { + let kind = match (block, label) { + (Some(id), label) => ScopeKind::Block { id, label }, + (None, Some(label)) => ScopeKind::Label(label), + (None, None) => ScopeKind::None, + }; self.scopes.alloc(ScopeData { parent: Some(parent), - block, - label, - macro_def: None, + kind, entries: empty_entries(self.scope_entries.len()), }) } @@ -219,9 +235,7 @@ impl ExprScopes { fn new_macro_def_scope(&mut self, parent: ScopeId, macro_id: Box<MacroDefId>) -> ScopeId { self.scopes.alloc(ScopeData { parent: Some(parent), - block: None, - label: None, - macro_def: Some(macro_id), + kind: ScopeKind::MacroDef(macro_id), entries: empty_entries(self.scope_entries.len()), }) } @@ -303,8 +317,6 @@ fn compute_expr_scopes( scope: &mut ScopeId, const_scope: &mut ScopeId, ) { - let make_label = |label: Option<LabelId>| label.map(|label| (label, store[label].name.clone())); - let compute_expr_scopes = |scopes: &mut ExprScopes, expr: ExprId, scope: &mut ScopeId, const_scope: &mut ScopeId| { compute_expr_scopes(expr, store, scopes, scope, const_scope) @@ -316,7 +328,7 @@ fn compute_expr_scopes( scopes: &mut ExprScopes, scope: &mut ScopeId, const_scope: &mut ScopeId| { - let mut scope = scopes.new_block_scope(*scope, id, make_label(label)); + let mut scope = scopes.new_block_scope(*scope, id, label); let mut const_scope = if id.is_some() { scopes.new_block_scope(*const_scope, id, None) } else { @@ -347,7 +359,7 @@ fn compute_expr_scopes( handle_block(*id, statements, *tail, None, scopes, scope, const_scope); } Expr::Loop { body: body_expr, label, source: _ } => { - let mut scope = scopes.new_labeled_scope(*scope, make_label(*label)); + let mut scope = scopes.new_labeled_scope(*scope, *label); compute_expr_scopes(scopes, *body_expr, &mut scope, const_scope); } Expr::Closure { args, body: body_expr, .. } => { |