Refactor AST nodes to use Rc

This commit refactors various AST node types to use `Rc` (Reference
Counting) instead of `Box`. This change is primarily driven by the need
for shared ownership and more efficient handling of potentially
recursive or shared data structures within the AST.

The main benefits of this change include:

- **Reduced cloning:** `Rc` allows multiple parts of the AST to refer to
  the same node without needing to clone the entire node. This is
  particularly beneficial for optimization passes where nodes might be
  visited multiple times.
- **Enabling sharing:** It makes it easier to represent scenarios where
  a single AST node might be a child of multiple parent nodes.
- **Performance improvements:** By avoiding unnecessary deep copies of
  AST nodes, this change can lead to performance gains, especially
  during complex compilation phases.
This commit is contained in:
Michael Schimmel
2026-03-03 16:07:42 +01:00
parent 78c36cf08d
commit 7c38dee243
12 changed files with 439 additions and 336 deletions
+22 -22
View File
@@ -215,14 +215,14 @@ impl Binder {
let then_br = self.bind(then_br, diag);
let mut else_br_bound = None;
if let Some(e) = else_br {
else_br_bound = Some(Box::new(self.bind(e, diag)));
else_br_bound = Some(Rc::new(self.bind(e, diag)));
}
self.make_node(
node.identity.clone(),
BoundKind::If {
cond: Box::new(cond),
then_br: Box::new(then_br),
cond: Rc::new(cond),
then_br: Rc::new(then_br),
else_br: else_br_bound,
},
)
@@ -246,7 +246,7 @@ impl Binder {
name: name.clone(),
addr,
kind: crate::ast::compiler::bound_nodes::DeclarationKind::Variable,
value: Box::new(val_node),
value: Rc::new(val_node),
captured_by: Vec::new(), // Will be filled by post-pass
},
)
@@ -263,8 +263,8 @@ impl Binder {
self.make_node(
node.identity.clone(),
BoundKind::Destructure {
pattern: Box::new(target_node),
value: Box::new(val_node),
pattern: Rc::new(target_node),
value: Rc::new(val_node),
},
)
}
@@ -279,7 +279,7 @@ impl Binder {
node.identity.clone(),
BoundKind::Set {
addr,
value: Box::new(val_node),
value: Rc::new(val_node),
},
)
} else {
@@ -290,8 +290,8 @@ impl Binder {
self.make_node(
node.identity.clone(),
BoundKind::Destructure {
pattern: Box::new(target_node),
value: Box::new(val_node),
pattern: Rc::new(target_node),
value: Rc::new(val_node),
},
)
}
@@ -300,9 +300,9 @@ impl Binder {
UntypedKind::Pipe { inputs, lambda } => {
let mut bound_inputs = Vec::with_capacity(inputs.len());
for input in inputs {
bound_inputs.push(self.bind(input, diag));
bound_inputs.push(Rc::new(self.bind(input, diag)));
}
let bound_lambda = Box::new(self.bind(lambda.as_ref(), diag));
let bound_lambda = Rc::new(self.bind(lambda.as_ref(), diag));
self.make_node(
node.identity.clone(),
BoundKind::Pipe {
@@ -365,8 +365,8 @@ impl Binder {
self.make_node(
node.identity.clone(),
BoundKind::Call {
callee: Box::new(callee),
args: Box::new(args),
callee: Rc::new(callee),
args: Rc::new(args),
},
)
}
@@ -383,7 +383,7 @@ impl Binder {
self.make_node(
node.identity.clone(),
BoundKind::Again {
args: Box::new(args),
args: Rc::new(args),
},
)
}
@@ -391,7 +391,7 @@ impl Binder {
UntypedKind::Block { exprs } => {
let mut bound_exprs = Vec::new();
for expr in exprs {
bound_exprs.push(self.bind(expr, diag));
bound_exprs.push(Rc::new(self.bind(expr, diag)));
}
self.make_node(
node.identity.clone(),
@@ -402,7 +402,7 @@ impl Binder {
UntypedKind::Tuple { elements } => {
let mut bound_elems = Vec::new();
for e in elements {
bound_elems.push(self.bind(e, diag));
bound_elems.push(Rc::new(self.bind(e, diag)));
}
self.make_node(
node.identity.clone(),
@@ -433,7 +433,7 @@ impl Binder {
Some(key_node.identity.clone()),
);
}
bound_values.push(val_node);
bound_values.push(Rc::new(val_node));
}
let layout = crate::ast::types::RecordLayout::get_or_create(layout_fields);
@@ -453,7 +453,7 @@ impl Binder {
node.identity.clone(),
BoundKind::Expansion {
original_call: Rc::from(call.as_ref().clone()),
bound_expanded: Box::new(bound_expanded),
bound_expanded: Rc::new(bound_expanded),
},
)
}
@@ -551,7 +551,7 @@ impl Binder {
name: sym.clone(),
addr,
kind,
value: Box::new(self.make_node(node.identity.clone(), BoundKind::Nop)),
value: Rc::new(self.make_node(node.identity.clone(), BoundKind::Nop)),
captured_by: Vec::new(), // Filled by post-pass
},
)
@@ -562,7 +562,7 @@ impl Binder {
UntypedKind::Tuple { elements } => {
let mut bound_elems = Vec::new();
for e in elements {
bound_elems.push(self.bind_pattern(e, kind, diag));
bound_elems.push(Rc::new(self.bind_pattern(e, kind, diag)));
}
self.make_node(
node.identity.clone(),
@@ -593,7 +593,7 @@ impl Binder {
node.identity.clone(),
BoundKind::Set {
addr,
value: Box::new(self.make_node(node.identity.clone(), BoundKind::Nop)),
value: Rc::new(self.make_node(node.identity.clone(), BoundKind::Nop)),
},
)
} else {
@@ -603,7 +603,7 @@ impl Binder {
UntypedKind::Tuple { elements } => {
let mut bound_elems = Vec::new();
for e in elements {
bound_elems.push(self.bind_assign_pattern(e, diag));
bound_elems.push(Rc::new(self.bind_assign_pattern(e, diag)));
}
self.make_node(
node.identity.clone(),