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.rs70
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, .. } => {