Refactor TypeContext locals to HashMap

Change the `slots` field in `TypeContext` from a `Vec` to a `HashMap`.
This allows for sparse local variable storage and avoids the need to
pre-allocate for all slots, which is more efficient when not all locals
are used.
This commit is contained in:
Michael Schimmel
2026-03-13 16:37:00 +01:00
parent ba36e2157e
commit 5a6cae1866
+6 -7
View File
@@ -1,13 +1,14 @@
use crate::ast::compiler::bound_nodes::{Address, BoundKind, Node, TypedNode}; use crate::ast::compiler::bound_nodes::{Address, BoundKind, Node, TypedNode};
use crate::ast::diagnostics::Diagnostics; use crate::ast::diagnostics::Diagnostics;
use crate::ast::types::StaticType; use crate::ast::types::StaticType;
use std::collections::HashMap;
use std::rc::Rc; use std::rc::Rc;
/// Manages the types of locals and upvalues during a single type-checking pass. /// Manages the types of locals and upvalues during a single type-checking pass.
struct TypeContext<'a> { struct TypeContext<'a> {
_parent: Option<&'a TypeContext<'a>>, _parent: Option<&'a TypeContext<'a>>,
/// Maps slot index -> Inferred Type /// Maps slot index -> Inferred Type
slots: Vec<StaticType>, slots: HashMap<u32, StaticType>,
/// Types of captured variables (passed from outer scope) /// Types of captured variables (passed from outer scope)
upvalue_types: Vec<StaticType>, upvalue_types: Vec<StaticType>,
/// Access to root types for unified resolution /// Access to root types for unified resolution
@@ -18,14 +19,14 @@ struct TypeContext<'a> {
impl<'a> TypeContext<'a> { impl<'a> TypeContext<'a> {
fn new( fn new(
slot_count: u32, _slot_count: u32,
upvalue_types: Vec<StaticType>, upvalue_types: Vec<StaticType>,
root_types: &'a std::cell::RefCell<Vec<StaticType>>, root_types: &'a std::cell::RefCell<Vec<StaticType>>,
parent: Option<&'a TypeContext<'a>>, parent: Option<&'a TypeContext<'a>>,
) -> Self { ) -> Self {
Self { Self {
_parent: parent, _parent: parent,
slots: vec![StaticType::Any; slot_count as usize], slots: HashMap::new(),
upvalue_types, upvalue_types,
root_types, root_types,
current_params_ty: None, current_params_ty: None,
@@ -36,7 +37,7 @@ impl<'a> TypeContext<'a> {
match addr { match addr {
Address::Local(slot) => self Address::Local(slot) => self
.slots .slots
.get(slot.0 as usize) .get(&slot.0)
.cloned() .cloned()
.unwrap_or(StaticType::Any), .unwrap_or(StaticType::Any),
Address::Global(idx) => self Address::Global(idx) => self
@@ -56,9 +57,7 @@ impl<'a> TypeContext<'a> {
fn set_type(&mut self, addr: Address, ty: StaticType) { fn set_type(&mut self, addr: Address, ty: StaticType) {
match addr { match addr {
Address::Local(slot) => { Address::Local(slot) => {
if let Some(entry) = self.slots.get_mut(slot.0 as usize) { self.slots.insert(slot.0, ty);
*entry = ty;
}
} }
Address::Global(idx) => { Address::Global(idx) => {
let mut rt = self.root_types.borrow_mut(); let mut rt = self.root_types.borrow_mut();