diff --git a/compiler/forget/Cargo.lock b/compiler/forget/Cargo.lock index dc07fa3e7a..1da54c9970 100644 --- a/compiler/forget/Cargo.lock +++ b/compiler/forget/Cargo.lock @@ -450,7 +450,6 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" name = "forget_build_hir" version = "0.1.0" dependencies = [ - "bumpalo", "forget_diagnostics", "forget_estree", "forget_hir", @@ -472,7 +471,6 @@ dependencies = [ name = "forget_estree" version = "0.1.0" dependencies = [ - "bumpalo", "forget_estree_codegen", "insta", "serde", @@ -505,7 +503,6 @@ dependencies = [ name = "forget_fixtures" version = "0.1.0" dependencies = [ - "bumpalo", "forget_build_hir", "forget_estree", "forget_estree_swc", @@ -520,7 +517,6 @@ dependencies = [ name = "forget_hir" version = "0.1.0" dependencies = [ - "bumpalo", "forget_diagnostics", "forget_estree", "forget_utils", @@ -533,7 +529,6 @@ dependencies = [ name = "forget_optimization" version = "0.1.0" dependencies = [ - "bumpalo", "forget_build_hir", "forget_diagnostics", "forget_estree", @@ -549,7 +544,6 @@ dependencies = [ name = "forget_ssa" version = "0.1.0" dependencies = [ - "bumpalo", "forget_diagnostics", "forget_hir", "forget_utils", @@ -562,7 +556,6 @@ dependencies = [ name = "forget_utils" version = "0.1.0" dependencies = [ - "bumpalo", "stacker", ] diff --git a/compiler/forget/Cargo.toml b/compiler/forget/Cargo.toml index c9eeb5422f..712c4670f9 100644 --- a/compiler/forget/Cargo.toml +++ b/compiler/forget/Cargo.toml @@ -26,7 +26,6 @@ forget_swc_demo = { path = "crates/forget_swc_demo" } forget_utils = { path = "crates/forget_utils" } # dependencies -bumpalo = { version = "3.13.0", features = ["boxed", "collections"] } indexmap = { version = "2.0.0", features = ["serde"] } insta = { version = "1.30.0", features = ["glob"] } miette = { version = "5.9.0" } diff --git a/compiler/forget/crates/forget_build_hir/Cargo.toml b/compiler/forget/crates/forget_build_hir/Cargo.toml index b2d71acd04..2a3ffcbd52 100644 --- a/compiler/forget/crates/forget_build_hir/Cargo.toml +++ b/compiler/forget/crates/forget_build_hir/Cargo.toml @@ -16,6 +16,5 @@ repository.workspace = true forget_hir = { workspace = true } forget_estree = { workspace = true} indexmap = { workspace = true } -bumpalo = { workspace = true } forget_diagnostics = { workspace = true } thiserror = { workspace = true } diff --git a/compiler/forget/crates/forget_build_hir/src/build.rs b/compiler/forget/crates/forget_build_hir/src/build.rs index e072d044ec..ce0f2282fb 100644 --- a/compiler/forget/crates/forget_build_hir/src/build.rs +++ b/compiler/forget/crates/forget_build_hir/src/build.rs @@ -1,6 +1,5 @@ use std::collections::HashSet; -use bumpalo::collections::{CollectIn, String}; use forget_diagnostics::Diagnostic; use forget_estree::{ AssignmentTarget, BinaryExpression, BlockStatement, Expression, ExpressionOrSpread, @@ -23,10 +22,7 @@ use crate::error::BuildHIRError; /// /// Failures generally include nonsensical input (`delete 1`) or syntax /// that is not yet supported. -pub fn build<'a>( - env: &'a Environment<'a>, - fun: Function, -) -> Result>, Diagnostic> { +pub fn build(env: &Environment, fun: Function) -> Result, Diagnostic> { let mut builder = Builder::new(env); match fun.body { @@ -44,7 +40,7 @@ pub fn build<'a>( } } - let mut params = env.vec_with_capacity(fun.params.len()); + let mut params = Vec::with_capacity(fun.params.len()); for param in fun.params { match param { Pattern::Identifier(param) => { @@ -83,21 +79,19 @@ pub fn build<'a>( let body = builder.build()?; Ok(Box::new(forget_hir::Function { - id: fun - .id - .map(|id| String::from_str_in(&id.name, &env.allocator)), + id: fun.id.map(|id| id.name), body, params, // TODO: populate context! - context: env.vec_new(), + context: Default::default(), is_async: fun.is_async, is_generator: fun.is_generator, })) } -fn lower_block_statement<'a>( - env: &'a Environment<'a>, - builder: &mut Builder<'a>, +fn lower_block_statement( + env: &Environment, + builder: &mut Builder, stmt: BlockStatement, ) -> Result<(), Diagnostic> { for stmt in stmt.body { @@ -108,11 +102,11 @@ fn lower_block_statement<'a>( /// Convert a statement to HIR. This will often result in multiple instructions and blocks /// being created as statements often describe control flow. -fn lower_statement<'a>( - env: &'a Environment<'a>, - builder: &mut Builder<'a>, +fn lower_statement( + env: &Environment, + builder: &mut Builder, stmt: Statement, - label: Option>, + label: Option, ) -> Result<(), Diagnostic> { match stmt { Statement::BlockStatement(stmt) => { @@ -350,9 +344,9 @@ fn lower_statement<'a>( /// InstructionValue is returned, this function is recursive and may cause multiple instructions /// to be emitted, possibly across multiple basic blocks (in the case of expressions with control /// flow semenatics such as logical, conditional, and optional expressions). -fn lower_expression<'a>( - env: &'a Environment<'a>, - builder: &mut Builder<'a>, +fn lower_expression( + env: &Environment, + builder: &mut Builder, expr: Expression, ) -> Result { let value = match expr { @@ -367,16 +361,16 @@ fn lower_expression<'a>( }; InstructionValue::LoadLocal(LoadLocal { place }) } - Binding::Module(..) | Binding::Global => InstructionValue::LoadGlobal(LoadGlobal { - name: String::from_str_in(&expr.name, &env.allocator), - }), + Binding::Module(..) | Binding::Global => { + InstructionValue::LoadGlobal(LoadGlobal { name: expr.name }) + } } } Expression::Literal(expr) => InstructionValue::Primitive(forget_hir::Primitive { value: lower_primitive(env, builder, *expr), }), Expression::ArrayExpression(expr) => { - let mut elements = env.vec_with_capacity(expr.elements.len()); + let mut elements = Vec::with_capacity(expr.elements.len()); for expr in expr.elements { let element = match expr { Some(forget_estree::ExpressionOrSpread::SpreadElement(expr)) => { @@ -477,12 +471,12 @@ fn lower_expression<'a>( Ok(builder.push(value)) } -fn lower_arguments<'a>( - env: &'a Environment<'a>, - builder: &mut Builder<'a>, +fn lower_arguments( + env: &Environment, + builder: &mut Builder, args: Vec, -) -> Result, Diagnostic> { - let mut arguments = env.vec_with_capacity(args.len()); +) -> Result, Diagnostic> { + let mut arguments = Vec::with_capacity(args.len()); for arg in args { let element = match arg { forget_estree::ExpressionOrSpread::SpreadElement(arg) => { @@ -501,15 +495,15 @@ fn lower_arguments<'a>( Ok(arguments) } -fn lower_function<'a>( - env: &'a Environment<'a>, - builder: &mut Builder<'a>, +fn lower_function( + env: &Environment, + builder: &mut Builder, function: forget_estree::Function, -) -> Result, Diagnostic> { +) -> Result { println!("get_context_identifiers() ..."); let context_identifiers = get_context_identifiers(env, &function); println!("ok"); - let mut context = env.vec_new(); + let mut context = Vec::new(); let mut seen = HashSet::new(); for identifier in context_identifiers { match builder.resolve_identifier(identifier)? { @@ -529,17 +523,17 @@ fn lower_function<'a>( fun.context = context; Ok(forget_hir::FunctionExpression { // TODO: collect dependencies! - dependencies: env.vec_new(), + dependencies: Default::default(), lowered_function: fun, }) } -fn lower_jsx_element<'a>( - env: &'a Environment<'a>, - builder: &mut Builder<'a>, +fn lower_jsx_element( + env: &Environment, + builder: &mut Builder, expr: forget_estree::JSXElement, -) -> Result, Diagnostic> { - let props: Result>, Diagnostic> = expr +) -> Result { + let props: Result, Diagnostic> = expr .opening_element .attributes .into_iter() @@ -567,25 +561,25 @@ fn lower_jsx_element<'a>( // }) } -fn lower_jsx_attribute<'a>( - env: &'a Environment<'a>, - builder: &mut Builder<'a>, +fn lower_jsx_attribute( + env: &Environment, + builder: &mut Builder, attr: forget_estree::JSXAttributeOrSpread, -) -> Result, Diagnostic> { +) -> Result { todo!("lower jsx attribute") } -fn lower_jsx_child<'a>( - env: &'a Environment<'a>, - builder: &mut Builder<'a>, +fn lower_jsx_child( + env: &Environment, + builder: &mut Builder, child: forget_estree::JSXChildItem, ) -> Result { todo!("lower jsx child") } -fn lower_assignment<'a>( - env: &'a Environment<'a>, - builder: &mut Builder<'a>, +fn lower_assignment( + env: &Environment, + builder: &mut Builder, kind: InstructionKind, lvalue: AssignmentTarget, value: InstrIx, @@ -608,12 +602,12 @@ fn lower_assignment<'a>( }) } -fn lower_identifier_for_assignment<'a>( - _env: &'a Environment<'a>, - builder: &mut Builder<'a>, +fn lower_identifier_for_assignment( + _env: &Environment, + builder: &mut Builder, _kind: InstructionKind, identifier: forget_estree::Identifier, -) -> Result, Diagnostic> { +) -> Result { let binding = builder.resolve_identifier(&identifier)?; match binding { Binding::Module(..) | Binding::Global => Err(Diagnostic::invalid_react( @@ -632,16 +626,12 @@ fn lower_identifier_for_assignment<'a>( } /// Converts an ESTree literal into a HIR primitive -fn lower_primitive<'a>( - env: &'a Environment<'a>, - _builder: &mut Builder<'a>, - literal: Literal, -) -> PrimitiveValue<'a> { +fn lower_primitive(_env: &Environment, _builder: &mut Builder, literal: Literal) -> PrimitiveValue { match literal.value { JsValue::Bool(bool) => PrimitiveValue::Boolean(bool), JsValue::Null => PrimitiveValue::Null, JsValue::Number(value) => PrimitiveValue::Number(f64::from(value).into()), - JsValue::String(s) => PrimitiveValue::String(String::from_str_in(&s, &env.allocator)), + JsValue::String(s) => PrimitiveValue::String(s), _ => todo!("Lower literal {literal:#?}"), } } diff --git a/compiler/forget/crates/forget_build_hir/src/builder.rs b/compiler/forget/crates/forget_build_hir/src/builder.rs index ee0151097c..cd78735e0f 100644 --- a/compiler/forget/crates/forget_build_hir/src/builder.rs +++ b/compiler/forget/crates/forget_build_hir/src/builder.rs @@ -1,7 +1,6 @@ use std::cell::RefCell; use std::rc::Rc; -use bumpalo::collections::{String, Vec}; use forget_diagnostics::Diagnostic; use forget_hir::{ initialize_hir, BasicBlock, BlockId, BlockKind, Blocks, Environment, GotoKind, Identifier, @@ -20,59 +19,59 @@ use crate::BuildHIRError; /// generally involves driving calls to enter/exit blocks, resolve /// labels and variables, and then calling `build()` when the HIR /// is complete. -pub(crate) struct Builder<'a> { +pub(crate) struct Builder<'e> { #[allow(dead_code)] - environment: &'a Environment<'a>, + environment: &'e Environment, - completed: Blocks<'a>, + completed: Blocks, - instructions: Vec<'a, Instruction<'a>>, + instructions: Vec, entry: BlockId, - wip: WipBlock<'a>, + wip: WipBlock, id_gen: InstructionIdGenerator, - scopes: Vec<'a, ControlFlowScope<'a>>, + scopes: Vec, } -pub(crate) struct WipBlock<'a> { +pub(crate) struct WipBlock { pub id: BlockId, pub kind: BlockKind, - pub instructions: Vec<'a, InstrIx>, + pub instructions: Vec, } -pub(crate) enum Binding<'a> { - Local(Identifier<'a>), - Module(Identifier<'a>), +pub(crate) enum Binding { + Local(Identifier), + Module(Identifier), Global, } #[derive(Clone, PartialEq, Eq, Debug)] -enum ControlFlowScope<'a> { - Loop(LoopScope<'a>), +enum ControlFlowScope { + Loop(LoopScope), - // Switch(SwitchScope<'a>), + // Switch(SwitchScope), #[allow(dead_code)] - Label(LabelScope<'a>), + Label(LabelScope), } #[derive(Clone, PartialEq, Eq, Debug)] -pub(crate) struct LoopScope<'a> { - pub label: Option>, +pub(crate) struct LoopScope { + pub label: Option, pub continue_block: BlockId, pub break_block: BlockId, } #[derive(Clone, PartialEq, Eq, Debug)] -pub(crate) struct LabelScope<'a> { - pub label: String<'a>, +pub(crate) struct LabelScope { + pub label: String, pub block: BlockId, } -impl<'a> ControlFlowScope<'a> { - fn label(&self) -> Option<&String<'a>> { +impl ControlFlowScope { + fn label(&self) -> Option<&String> { match self { Self::Loop(scope) => scope.label.as_ref(), Self::Label(scope) => Some(&scope.label), @@ -87,22 +86,22 @@ impl<'a> ControlFlowScope<'a> { } } -impl<'a> Builder<'a> { - pub(crate) fn new(environment: &'a Environment<'a>) -> Self { +impl<'e> Builder<'e> { + pub(crate) fn new(environment: &'e Environment) -> Self { let entry = environment.next_block_id(); let current = WipBlock { id: entry, kind: BlockKind::Block, - instructions: environment.vec_new(), + instructions: Default::default(), }; Self { environment, completed: Default::default(), - instructions: environment.vec_new(), + instructions: Default::default(), entry, wip: current, id_gen: InstructionIdGenerator::new(), - scopes: environment.vec_new(), + scopes: Default::default(), } } @@ -111,7 +110,7 @@ impl<'a> Builder<'a> { /// /// TODO: refine the type, only invariants should be possible here, /// not other types of errors - pub(crate) fn build(self) -> Result, Diagnostic> { + pub(crate) fn build(self) -> Result { let mut hir = HIR { entry: self.entry, blocks: self.completed, @@ -123,7 +122,7 @@ impl<'a> Builder<'a> { } /// Adds a new instruction to the end of the work in progress block - pub(crate) fn push(&mut self, value: InstructionValue<'a>) -> InstrIx { + pub(crate) fn push(&mut self, value: InstructionValue) -> InstrIx { let instr = Instruction { id: self.id_gen.next(), value, @@ -136,19 +135,19 @@ impl<'a> Builder<'a> { /// Terminates the work in progress block with the given terminal, and starts a new /// work in progress block with the given kind - pub(crate) fn terminate(&mut self, terminal: TerminalValue<'a>, next_kind: BlockKind) { + pub(crate) fn terminate(&mut self, terminal: TerminalValue, next_kind: BlockKind) { let next_wip = WipBlock { id: self.environment.next_block_id(), kind: next_kind, - instructions: self.environment.vec_new(), + instructions: Default::default(), }; self.terminate_with_fallthrough(terminal, next_wip) } pub(crate) fn terminate_with_fallthrough( &mut self, - terminal: TerminalValue<'a>, - fallthrough: WipBlock<'a>, + terminal: TerminalValue, + fallthrough: WipBlock, ) { let prev_wip = std::mem::replace(&mut self.wip, fallthrough); self.completed.insert(Box::new(BasicBlock { @@ -160,21 +159,21 @@ impl<'a> Builder<'a> { value: terminal, }, predecessors: Default::default(), - phis: self.environment.vec_new(), + phis: Default::default(), })); } - pub(crate) fn reserve(&mut self, kind: BlockKind) -> WipBlock<'a> { + pub(crate) fn reserve(&mut self, kind: BlockKind) -> WipBlock { WipBlock { id: self.environment.next_block_id(), kind, - instructions: self.environment.vec_new(), + instructions: Default::default(), } } pub(crate) fn enter(&mut self, kind: BlockKind, f: F) -> Result where - F: FnOnce(&mut Self) -> Result, Diagnostic>, + F: FnOnce(&mut Self) -> Result, { let wip = self.reserve(kind); let id = wip.id; @@ -182,9 +181,9 @@ impl<'a> Builder<'a> { Ok(id) } - fn enter_reserved(&mut self, wip: WipBlock<'a>, f: F) -> Result<(), Diagnostic> + fn enter_reserved(&mut self, wip: WipBlock, f: F) -> Result<(), Diagnostic> where - F: FnOnce(&mut Self) -> Result, Diagnostic>, + F: FnOnce(&mut Self) -> Result, { let current = std::mem::replace(&mut self.wip, wip); @@ -210,18 +209,18 @@ impl<'a> Builder<'a> { value: terminal, }, predecessors: Default::default(), - phis: self.environment.vec_new(), + phis: Default::default(), })); result } pub(crate) fn enter_loop( &mut self, - scope: LoopScope<'a>, + scope: LoopScope, f: F, - ) -> Result, Diagnostic> + ) -> Result where - F: FnOnce(&mut Self) -> Result, Diagnostic>, + F: FnOnce(&mut Self) -> Result, { self.scopes.push(ControlFlowScope::Loop(scope.clone())); let terminal = f(self); @@ -235,7 +234,7 @@ impl<'a> Builder<'a> { /// we synthesize a temporary identifier to store the possibly-missing value /// into, and emit a later StoreLocal for the original identifier #[allow(dead_code)] - pub(crate) fn make_temporary(&self) -> forget_hir::Identifier<'a> { + pub(crate) fn make_temporary(&self) -> forget_hir::Identifier { forget_hir::Identifier { id: self.environment.next_identifier_id(), name: None, @@ -318,7 +317,7 @@ impl<'a> Builder<'a> { pub(crate) fn resolve_identifier( &mut self, identifier: &forget_estree::Identifier, - ) -> Result, Diagnostic> { + ) -> Result { match &identifier.binding { Some(binding) => Ok(match binding { forget_estree::Binding::Global => Binding::Global, diff --git a/compiler/forget/crates/forget_build_hir/src/context.rs b/compiler/forget/crates/forget_build_hir/src/context.rs index e185f3f178..7623cc4553 100644 --- a/compiler/forget/crates/forget_build_hir/src/context.rs +++ b/compiler/forget/crates/forget_build_hir/src/context.rs @@ -3,8 +3,8 @@ use std::collections::HashSet; use forget_estree::{Binding, BindingId, Function, Identifier, Visitor}; use forget_hir::Environment; -pub(crate) fn get_context_identifiers<'a, 'ast>( - _env: &'a Environment<'a>, +pub(crate) fn get_context_identifiers<'ast>( + _env: &Environment, function: &'ast Function, ) -> Vec<&'ast Identifier> { let mut visitor = ContextVisitor::new(); diff --git a/compiler/forget/crates/forget_estree/Cargo.toml b/compiler/forget/crates/forget_estree/Cargo.toml index 47adaf48f6..31525551ef 100644 --- a/compiler/forget/crates/forget_estree/Cargo.toml +++ b/compiler/forget/crates/forget_estree/Cargo.toml @@ -13,7 +13,6 @@ repository.workspace = true # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -bumpalo = { workspace = true } insta = { workspace = true } serde = { workspace = true } serde_json = { workspace = true } diff --git a/compiler/forget/crates/forget_estree/src/snapshots/forget_estree__tests__fixtures@test.json.snap b/compiler/forget/crates/forget_estree/src/snapshots/forget_estree__tests__fixtures@test.json.snap index 67ced0dac8..4b87ee2f85 100644 --- a/compiler/forget/crates/forget_estree/src/snapshots/forget_estree__tests__fixtures@test.json.snap +++ b/compiler/forget/crates/forget_estree/src/snapshots/forget_estree__tests__fixtures@test.json.snap @@ -395,10 +395,7 @@ Output: "type": "JSXMemberExpression", "object": { "type": "JSXIdentifier", - "type": "Identifier", "name": "Foo", - "loc": null, - "range": null, "loc": { "source": null, "start": { @@ -417,10 +414,7 @@ Output: }, "property": { "type": "JSXIdentifier", - "type": "Identifier", "name": "Bar", - "loc": null, - "range": null, "loc": { "source": null, "start": { @@ -458,10 +452,7 @@ Output: "type": "JSXAttribute", "name": { "type": "JSXIdentifier", - "type": "Identifier", "name": "a", - "loc": null, - "range": null, "loc": { "source": null, "start": { @@ -561,10 +552,7 @@ Output: "type": "JSXMemberExpression", "object": { "type": "JSXIdentifier", - "type": "Identifier", "name": "Foo", - "loc": null, - "range": null, "loc": { "source": null, "start": { @@ -583,10 +571,7 @@ Output: }, "property": { "type": "JSXIdentifier", - "type": "Identifier", "name": "Bar", - "loc": null, - "range": null, "loc": { "source": null, "start": { diff --git a/compiler/forget/crates/forget_fixtures/Cargo.toml b/compiler/forget/crates/forget_fixtures/Cargo.toml index 9906d14216..4bab804f10 100644 --- a/compiler/forget/crates/forget_fixtures/Cargo.toml +++ b/compiler/forget/crates/forget_fixtures/Cargo.toml @@ -20,5 +20,4 @@ forget_hir = { workspace = true } forget_optimization = { workspace = true } forget_ssa = { workspace = true } forget_build_hir = { workspace = true } -bumpalo = { workspace = true } miette = { workspace = true, features = ["backtrace", "fancy"] } diff --git a/compiler/forget/crates/forget_fixtures/tests/fixtures/jsx.js b/compiler/forget/crates/forget_fixtures/tests/fixtures/jsx.js deleted file mode 100644 index b1071a9beb..0000000000 --- a/compiler/forget/crates/forget_fixtures/tests/fixtures/jsx.js +++ /dev/null @@ -1,9 +0,0 @@ -function Component(props) { - return ( - - Hello - {props.foo} -
{props.bar}
-
- ); -} diff --git a/compiler/forget/crates/forget_fixtures/tests/fixtures_test.rs b/compiler/forget/crates/forget_fixtures/tests/fixtures_test.rs index 8f9f99505f..92bbb1952b 100644 --- a/compiler/forget/crates/forget_fixtures/tests/fixtures_test.rs +++ b/compiler/forget/crates/forget_fixtures/tests/fixtures_test.rs @@ -1,7 +1,6 @@ use std::env; use std::fmt::Write; -use bumpalo::Bump; use forget_build_hir::build; use forget_estree::{ModuleItem, Statement}; use forget_estree_swc::parse; @@ -24,14 +23,12 @@ fn fixtures() { for (ix, item) in ast.body.into_iter().enumerate() { if let ModuleItem::Statement(stmt) = item { if let Statement::FunctionDeclaration(fun) = stmt { - let allocator = Bump::new(); - let environment = allocator.alloc(Environment::new( - &allocator, + let environment = Environment::new( Features { validate_frozen_lambdas: true, }, Registry, - )); + ); if ix != 0 { output.push_str("\n\n"); } diff --git a/compiler/forget/crates/forget_hir/Cargo.toml b/compiler/forget/crates/forget_hir/Cargo.toml index 6b994c18ce..6bf0437cda 100644 --- a/compiler/forget/crates/forget_hir/Cargo.toml +++ b/compiler/forget/crates/forget_hir/Cargo.toml @@ -13,7 +13,6 @@ repository.workspace = true # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -bumpalo = { workspace = true } forget_estree = { workspace = true } indexmap = { workspace = true } serde = { workspace = true } diff --git a/compiler/forget/crates/forget_hir/src/basic_block.rs b/compiler/forget/crates/forget_hir/src/basic_block.rs index ba51c42b60..2bf2b67d20 100644 --- a/compiler/forget/crates/forget_hir/src/basic_block.rs +++ b/compiler/forget/crates/forget_hir/src/basic_block.rs @@ -12,7 +12,7 @@ use crate::{Identifier, InstrIx, Terminal}; /// /// [1] Assuming no exceptions are thrown. #[derive(Debug)] -pub struct BasicBlock<'a> { +pub struct BasicBlock { /// The identifier for the block pub id: BlockId, @@ -23,21 +23,21 @@ pub struct BasicBlock<'a> { pub kind: BlockKind, /// The ordered instructions in this block - pub instructions: bumpalo::collections::Vec<'a, InstrIx>, + pub instructions: Vec, /// The terminal instruction for the block - pub terminal: Terminal<'a>, + pub terminal: Terminal, /// The immediate predecessors of this block pub predecessors: IndexSet, - pub phis: bumpalo::collections::Vec<'a, Phi<'a>>, + pub phis: Vec, } #[derive(Debug)] -pub struct Phi<'a> { - pub identifier: Identifier<'a>, - pub operands: IndexMap>, +pub struct Phi { + pub identifier: Identifier, + pub operands: IndexMap, } #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] diff --git a/compiler/forget/crates/forget_hir/src/environment.rs b/compiler/forget/crates/forget_hir/src/environment.rs index bac1ce67b3..ec7f85fe38 100644 --- a/compiler/forget/crates/forget_hir/src/environment.rs +++ b/compiler/forget/crates/forget_hir/src/environment.rs @@ -2,9 +2,6 @@ use std::cell::{Cell, RefCell}; use std::collections::HashMap; use std::rc::Rc; -use bumpalo::boxed::Box; -use bumpalo::collections::Vec; -use bumpalo::Bump; use forget_estree::BindingId; use crate::{ @@ -15,7 +12,7 @@ use crate::{ /// compiled. Environments may not be reused between React functions, but *are* /// shared between each React function and all its nested function expressions. #[derive(Debug)] -pub struct Environment<'a> { +pub struct Environment { /// The set of enabled compiler features pub features: Features, @@ -24,10 +21,6 @@ pub struct Environment<'a> { #[allow(dead_code)] registry: Registry, - /// Arena allocator so that data for compilation can be efficiently allocated - /// and the memory reclaimed when compilation completes. - pub allocator: &'a Bump, - /// The next available block index next_block_id: Cell, @@ -36,13 +29,12 @@ pub struct Environment<'a> { next_type_var_id: Cell, - bindings: Rc, BindingId), Identifier<'a>>>>, + bindings: Rc>>, } -impl<'a> Environment<'a> { - pub fn new(allocator: &'a Bump, features: Features, registry: Registry) -> Self { +impl Environment { + pub fn new(features: Features, registry: Registry) -> Self { Self { - allocator, features, registry, next_block_id: Cell::new(BlockId(0)), @@ -52,23 +44,6 @@ impl<'a> Environment<'a> { } } - /// Allocate a value into the environment's memory arena - pub fn alloc(&self, value: T) -> &'a mut T { - self.allocator.alloc(value) - } - - pub fn box_new(&self, value: T) -> Box<'a, T> { - Box::new_in(value, &self.allocator) - } - - pub fn vec_new(&self) -> Vec<'a, T> { - Vec::new_in(&self.allocator) - } - - pub fn vec_with_capacity(&self, capacity: usize) -> Vec<'a, T> { - Vec::with_capacity_in(capacity, &self.allocator) - } - /// Get the next available block id pub fn next_block_id(&self) -> BlockId { let id = self.next_block_id.get(); @@ -90,8 +65,8 @@ impl<'a> Environment<'a> { id } - pub fn resolve_binding_identifier(&self, name: &str, binding_id: BindingId) -> Identifier<'a> { - let key_name = bumpalo::collections::String::from_str_in(name, &self.allocator); + pub fn resolve_binding_identifier(&self, name: &str, binding_id: BindingId) -> Identifier { + let key_name = name.to_string(); let mut bindings = self.bindings.borrow_mut(); if let Some(identifier) = bindings.get(&(key_name.clone(), binding_id)) { identifier.clone() diff --git a/compiler/forget/crates/forget_hir/src/function.rs b/compiler/forget/crates/forget_hir/src/function.rs index ccaf6501de..a5f0e72672 100644 --- a/compiler/forget/crates/forget_hir/src/function.rs +++ b/compiler/forget/crates/forget_hir/src/function.rs @@ -1,4 +1,3 @@ -use bumpalo::collections::{String, Vec}; use forget_diagnostics::Diagnostic; use indexmap::IndexMap; @@ -6,11 +5,11 @@ use crate::{BasicBlock, BlockId, FunctionExpression, IdentifierOperand, InstrIx, /// Represents either a React function or a function expression #[derive(Debug)] -pub struct Function<'a> { - pub id: Option>, - pub body: HIR<'a>, - pub params: Vec<'a, IdentifierOperand<'a>>, - pub context: Vec<'a, IdentifierOperand<'a>>, +pub struct Function { + pub id: Option, + pub body: HIR, + pub params: Vec, + pub context: Vec, pub is_async: bool, pub is_generator: bool, } @@ -20,20 +19,20 @@ pub struct Function<'a> { /// so that compiler passes can complete forward data flow analysis in a /// single pass over the CFG in the case where there are no loops. #[derive(Debug)] -pub struct HIR<'a> { +pub struct HIR { /// The id of the first block pub entry: BlockId, /// Blocks are stored in a map for easy retrieval by their id, /// but the blocks are in reverse postorder - pub blocks: Blocks<'a>, + pub blocks: Blocks, /// All instructions for the block. This may contain unused items, - pub instructions: Vec<'a, Instruction<'a>>, + pub instructions: Vec, } -impl<'a> HIR<'a> { - pub fn inline(&mut self, other: FunctionExpression<'a>) -> () { +impl HIR { + pub fn inline(&mut self, other: FunctionExpression) -> () { let offset = self.instructions.len(); for mut instr in other.lowered_function.body.instructions.into_iter() { instr.each_operand(|operand| { @@ -54,11 +53,11 @@ impl<'a> HIR<'a> { } #[derive(Default, Debug)] -pub struct Blocks<'a> { - data: IndexMap>>>, +pub struct Blocks { + data: IndexMap>>, } -impl<'a> Blocks<'a> { +impl Blocks { pub fn new() -> Self { Self { data: Default::default(), @@ -75,7 +74,7 @@ impl<'a> Blocks<'a> { self.data.len() } - pub fn insert(&mut self, block: Box>) -> Option>>> { + pub fn insert(&mut self, block: Box) -> Option>> { self.data.insert(block.id, Some(block)) } @@ -83,7 +82,7 @@ impl<'a> Blocks<'a> { self.data.keys().cloned().collect() } - pub fn remove(&mut self, id: BlockId) -> Box> { + pub fn remove(&mut self, id: BlockId) -> Box { self.data.remove(&id).unwrap().unwrap() } @@ -91,38 +90,38 @@ impl<'a> Blocks<'a> { self.data.extend(other.data); } - pub fn into_iter(self) -> BlocksIntoIter<'a> { + pub fn into_iter(self) -> BlocksIntoIter { BlocksIntoIter::new(self.data.into_iter()) } - pub fn block(&self, id: BlockId) -> &BasicBlock<'a> { + pub fn block(&self, id: BlockId) -> &BasicBlock { self.data.get(&id).unwrap().as_ref().unwrap() } - pub fn block_mut(&mut self, id: BlockId) -> &mut BasicBlock<'a> { + pub fn block_mut(&mut self, id: BlockId) -> &mut BasicBlock { self.data.get_mut(&id).unwrap().as_mut().unwrap() } - pub fn iter(&self) -> BlocksIter<'_, 'a> { + pub fn iter(&self) -> BlocksIter<'_> { BlocksIter::new(self.data.iter()) } - pub fn iter_mut(&mut self) -> BlocksIterMut<'_, 'a> { + pub fn iter_mut(&mut self) -> BlocksIterMut<'_> { BlocksIterMut::new(self.data.iter_mut()) } } -pub struct BlocksIntoIter<'a> { - iter: indexmap::map::IntoIter>>>, +pub struct BlocksIntoIter { + iter: indexmap::map::IntoIter>>, } -impl<'a> BlocksIntoIter<'a> { - fn new(iter: indexmap::map::IntoIter>>>) -> Self { +impl BlocksIntoIter { + fn new(iter: indexmap::map::IntoIter>>) -> Self { Self { iter } } } -impl<'a> Iterator for BlocksIntoIter<'a> { - type Item = Box>; +impl Iterator for BlocksIntoIter { + type Item = Box; fn size_hint(&self) -> (usize, Option) { self.iter.size_hint() @@ -139,18 +138,18 @@ impl<'a> Iterator for BlocksIntoIter<'a> { } } -pub struct BlocksIter<'b, 'a> { - iter: indexmap::map::Iter<'b, BlockId, Option>>>, +pub struct BlocksIter<'b> { + iter: indexmap::map::Iter<'b, BlockId, Option>>, } -impl<'b, 'a> BlocksIter<'b, 'a> { - fn new(iter: indexmap::map::Iter<'b, BlockId, Option>>>) -> Self { +impl<'b> BlocksIter<'b> { + fn new(iter: indexmap::map::Iter<'b, BlockId, Option>>) -> Self { Self { iter } } } -impl<'b, 'a> Iterator for BlocksIter<'b, 'a> { - type Item = &'b BasicBlock<'a>; +impl<'b> Iterator for BlocksIter<'b> { + type Item = &'b BasicBlock; fn size_hint(&self) -> (usize, Option) { self.iter.size_hint() @@ -164,18 +163,18 @@ impl<'b, 'a> Iterator for BlocksIter<'b, 'a> { } } -pub struct BlocksIterMut<'b, 'a> { - iter: indexmap::map::IterMut<'b, BlockId, Option>>>, +pub struct BlocksIterMut<'b> { + iter: indexmap::map::IterMut<'b, BlockId, Option>>, } -impl<'b, 'a> BlocksIterMut<'b, 'a> { - fn new(iter: indexmap::map::IterMut<'b, BlockId, Option>>>) -> Self { +impl<'b> BlocksIterMut<'b> { + fn new(iter: indexmap::map::IterMut<'b, BlockId, Option>>) -> Self { Self { iter } } } -impl<'b, 'a> Iterator for BlocksIterMut<'b, 'a> { - type Item = &'b mut BasicBlock<'a>; +impl<'b> Iterator for BlocksIterMut<'b> { + type Item = &'b mut BasicBlock; fn size_hint(&self) -> (usize, Option) { self.iter.size_hint() @@ -189,14 +188,14 @@ impl<'b, 'a> Iterator for BlocksIterMut<'b, 'a> { } } -pub struct BlockRewriter<'blocks, 'a> { - blocks: &'blocks mut Blocks<'a>, +pub struct BlockRewriter<'blocks> { + blocks: &'blocks mut Blocks, current: BlockId, - new_blocks: std::vec::Vec>>, + new_blocks: std::vec::Vec>, } -impl<'blocks, 'a> BlockRewriter<'blocks, 'a> { - pub fn new(blocks: &'blocks mut Blocks<'a>, entry: BlockId) -> Self { +impl<'blocks> BlockRewriter<'blocks> { + pub fn new(blocks: &'blocks mut Blocks, entry: BlockId) -> Self { Self { blocks, current: entry, @@ -206,7 +205,7 @@ impl<'blocks, 'a> BlockRewriter<'blocks, 'a> { pub fn each_block(&mut self, mut f: F) -> () where - F: FnMut(Box>, &mut Self) -> BlockRewriterAction<'a>, + F: FnMut(Box, &mut Self) -> BlockRewriterAction, { let mut keys = self.blocks.block_ids(); loop { @@ -236,7 +235,7 @@ impl<'blocks, 'a> BlockRewriter<'blocks, 'a> { pub fn try_each_block(&mut self, mut f: F) -> Result<(), Diagnostic> where - F: FnMut(Box>, &mut Self) -> Result, Diagnostic>, + F: FnMut(Box, &mut Self) -> Result, { let mut keys = self.blocks.block_ids(); loop { @@ -270,22 +269,22 @@ impl<'blocks, 'a> BlockRewriter<'blocks, 'a> { self.blocks.data.contains_key(&block_id) } - pub fn block(&self, block_id: BlockId) -> &BasicBlock<'a> { + pub fn block(&self, block_id: BlockId) -> &BasicBlock { assert_ne!(block_id, self.current); self.blocks.block(block_id) } - pub fn block_mut(&mut self, block_id: BlockId) -> &mut BasicBlock<'a> { + pub fn block_mut(&mut self, block_id: BlockId) -> &mut BasicBlock { assert_ne!(block_id, self.current); self.blocks.block_mut(block_id) } - pub fn add_block(&mut self, block: Box>) { + pub fn add_block(&mut self, block: Box) { self.new_blocks.push(block); } } -pub enum BlockRewriterAction<'a> { - Keep(Box>), +pub enum BlockRewriterAction { + Keep(Box), Remove, } diff --git a/compiler/forget/crates/forget_hir/src/initialize.rs b/compiler/forget/crates/forget_hir/src/initialize.rs index c1dd73ee1f..41bc4f0f9c 100644 --- a/compiler/forget/crates/forget_hir/src/initialize.rs +++ b/compiler/forget/crates/forget_hir/src/initialize.rs @@ -11,7 +11,7 @@ use crate::{ /// Runs a variety of passes to put the HIR in canonical form. This should be called /// after initial HIR construction and after any transformations that change the /// shape of the control-flow graph. -pub fn initialize_hir<'a>(hir: &mut HIR<'a>) -> Result<(), Diagnostic> { +pub fn initialize_hir(hir: &mut HIR) -> Result<(), Diagnostic> { prune_tombstones(hir); reverse_postorder_blocks(hir); remove_unreachable_for_updates(hir); @@ -22,7 +22,7 @@ pub fn initialize_hir<'a>(hir: &mut HIR<'a>) -> Result<(), Diagnostic> { Ok(()) } -pub fn prune_tombstones<'a>(hir: &mut HIR<'a>) { +pub fn prune_tombstones(hir: &mut HIR) { for block in hir.blocks.iter_mut() { block.instructions.retain(|ix| { let instr = &hir.instructions[usize::from(*ix)]; @@ -34,12 +34,12 @@ pub fn prune_tombstones<'a>(hir: &mut HIR<'a>) { /// Modifies the HIR to put the blocks in reverse postorder, with predecessors before /// successors (except for the case of loops) -pub fn reverse_postorder_blocks<'a>(hir: &mut HIR<'a>) { +pub fn reverse_postorder_blocks(hir: &mut HIR) { let mut visited = HashSet::::with_capacity(hir.blocks.len()); let mut postorder = std::vec::Vec::::with_capacity(hir.blocks.len()); - fn visit<'a>( + fn visit( block_id: BlockId, - hir: &HIR<'a>, + hir: &HIR, visited: &mut HashSet, postorder: &mut std::vec::Vec, ) { @@ -89,7 +89,7 @@ pub fn reverse_postorder_blocks<'a>(hir: &mut HIR<'a>) { } /// Prunes ForTerminal.update values (sets to None) if they are unreachable -pub fn remove_unreachable_for_updates<'a>(hir: &mut HIR<'a>) { +pub fn remove_unreachable_for_updates(hir: &mut HIR) { BlockRewriter::new(&mut hir.blocks, hir.entry).each_block(|mut block, rewriter| { if let TerminalValue::For(terminal) = &mut block.terminal.value { if let Some(update) = terminal.update { @@ -104,7 +104,7 @@ pub fn remove_unreachable_for_updates<'a>(hir: &mut HIR<'a>) { /// Prunes unreachable fallthrough values, setting them to None if the referenced /// block was not otherwise reachable. -pub fn remove_unreachable_fallthroughs<'a>(hir: &mut HIR<'a>) { +pub fn remove_unreachable_fallthroughs(hir: &mut HIR) { BlockRewriter::new(&mut hir.blocks, hir.entry).each_block(|mut block, rewriter| { block .terminal @@ -121,7 +121,7 @@ pub fn remove_unreachable_fallthroughs<'a>(hir: &mut HIR<'a>) { } /// Rewrites DoWhile statements into Gotos if the test block is not reachable -pub fn remove_unreachable_do_while_statements<'a>(hir: &mut HIR<'a>) { +pub fn remove_unreachable_do_while_statements(hir: &mut HIR) { BlockRewriter::new(&mut hir.blocks, hir.entry).each_block(|mut block, rewriter| { if let TerminalValue::DoWhile(terminal) = &mut block.terminal.value { if !rewriter.contains(terminal.test) { @@ -137,7 +137,7 @@ pub fn remove_unreachable_do_while_statements<'a>(hir: &mut HIR<'a>) { /// Updates the instruction ids for all instructions and blocks /// Relies on the blocks being in reverse postorder to ensure that id ordering is correct -pub fn mark_instruction_ids<'a>(hir: &mut HIR<'a>) -> Result<(), Diagnostic> { +pub fn mark_instruction_ids(hir: &mut HIR) -> Result<(), Diagnostic> { let mut id_gen = InstructionIdGenerator::new(); let mut visited = HashSet::<(usize, usize)>::new(); for (ii, block) in hir.blocks.iter_mut().enumerate() { @@ -161,15 +161,15 @@ pub struct BlockVisitedTwice { } /// Updates the predecessors of each block -pub fn mark_predecessors<'a>(hir: &mut HIR<'a>) { +pub fn mark_predecessors(hir: &mut HIR) { for block in hir.blocks.iter_mut() { block.predecessors.clear(); } let mut visited = HashSet::::with_capacity(hir.blocks.len()); - fn visit<'a>( + fn visit( block_id: BlockId, prev_id: Option, - hir: &mut HIR<'a>, + hir: &mut HIR, visited: &mut HashSet, ) { let block = hir.blocks.block_mut(block_id); diff --git a/compiler/forget/crates/forget_hir/src/inline_use_memo.rs b/compiler/forget/crates/forget_hir/src/inline_use_memo.rs index 4f50afb8ab..65db1e1df4 100644 --- a/compiler/forget/crates/forget_hir/src/inline_use_memo.rs +++ b/compiler/forget/crates/forget_hir/src/inline_use_memo.rs @@ -2,7 +2,6 @@ use std::cell::RefCell; use std::collections::HashSet; use std::rc::Rc; -use bumpalo::collections::String; use forget_diagnostics::Diagnostic; use crate::{ @@ -63,10 +62,7 @@ use crate::{ /// [13] StoreLocal 'x', #6 /// ``` /// -pub fn inline_use_memo<'a>( - env: &Environment<'a>, - fun: &mut Function<'a>, -) -> Result<(), Diagnostic> { +pub fn inline_use_memo(env: &Environment, fun: &mut Function) -> Result<(), Diagnostic> { let mut use_memo_globals: HashSet = Default::default(); let mut functions: HashSet = Default::default(); @@ -108,7 +104,7 @@ pub fn inline_use_memo<'a>( let temporary = Identifier { id: temporary_id, // NOTE: for memoization to work correctly this variable has to be named - name: Some(String::from_str_in("t", &env.allocator)), + name: Some("t".to_string()), data: Rc::new(RefCell::new(IdentifierData { mutable_range: MutableRange::new(), scope: None, @@ -232,7 +228,7 @@ pub fn inline_use_memo<'a>( id: continuation_block_id, instructions: continuation_instructions, kind: block.kind, - phis: env.vec_new(), + phis: Default::default(), predecessors: Default::default(), terminal, }); diff --git a/compiler/forget/crates/forget_hir/src/instruction.rs b/compiler/forget/crates/forget_hir/src/instruction.rs index 8f77bd3602..c24d5fea92 100644 --- a/compiler/forget/crates/forget_hir/src/instruction.rs +++ b/compiler/forget/crates/forget_hir/src/instruction.rs @@ -2,21 +2,20 @@ use std::cell::RefCell; use std::fmt::Display; use std::rc::Rc; -use bumpalo::collections::{String, Vec}; use forget_estree::BinaryOperator; use crate::{Function, IdentifierId, InstrIx, InstructionId, ScopeId, Type}; #[derive(Debug)] -pub struct Instruction<'a> { +pub struct Instruction { pub id: InstructionId, - pub value: InstructionValue<'a>, + pub value: InstructionValue, } -impl<'a> Instruction<'a> { +impl Instruction { pub fn each_identifier_store(&mut self, mut f: F) -> () where - F: FnMut(&mut LValue<'a>) -> (), + F: FnMut(&mut LValue) -> (), { match &mut self.value { InstructionValue::DeclareContext(instr) => { @@ -43,7 +42,7 @@ impl<'a> Instruction<'a> { pub fn try_each_identifier_store(&mut self, mut f: F) -> Result<(), E> where - F: FnMut(&mut LValue<'a>) -> Result<(), E>, + F: FnMut(&mut LValue) -> Result<(), E>, { match &mut self.value { InstructionValue::DeclareContext(instr) => { @@ -71,7 +70,7 @@ impl<'a> Instruction<'a> { pub fn each_identifier_load(&mut self, mut f: F) -> () where - F: FnMut(&mut IdentifierOperand<'a>) -> (), + F: FnMut(&mut IdentifierOperand) -> (), { match &mut self.value { InstructionValue::LoadLocal(instr) => f(&mut instr.place), @@ -151,46 +150,46 @@ impl<'a> Instruction<'a> { } #[derive(Debug)] -pub enum InstructionValue<'a> { - Array(Array<'a>), - // Await(Await<'a>), +pub enum InstructionValue { + Array(Array), + // Await(Await), Binary(Binary), - Call(Call<'a>), - // ComputedDelete(ComputedDelete<'a>), - // ComputedLoad(ComputedLoad<'a>), - // ComputedStore(ComputedStore<'a>), - // Debugger(Debugger<'a>), - DeclareContext(DeclareContext<'a>), - DeclareLocal(DeclareLocal<'a>), - // Destructure(Destructure<'a>), - Function(FunctionExpression<'a>), - JSXElement(JSXElement<'a>), - // JsxFragment(JsxFragment<'a>), - // JsxText(JsxText<'a>), + Call(Call), + // ComputedDelete(ComputedDelete), + // ComputedLoad(ComputedLoad), + // ComputedStore(ComputedStore), + // Debugger(Debugger), + DeclareContext(DeclareContext), + DeclareLocal(DeclareLocal), + // Destructure(Destructure), + Function(FunctionExpression), + JSXElement(JSXElement), + // JsxFragment(JsxFragment), + // JsxText(JsxText), LoadContext(LoadContext), - LoadGlobal(LoadGlobal<'a>), - LoadLocal(LoadLocal<'a>), - // MethodCall(MethodCall<'a>), - // New(New<'a>), - // NextIterable(NextIterable<'a>), - // Object(Object<'a>), - Primitive(Primitive<'a>), - // PropertyDelete(PropertyDelete<'a>), - // PropertyLoad(PropertyLoad<'a>), - // PropertyStore(PropertyStore<'a>), - // RegExp(RegExp<'a>), - // StoreContext(StoreContext<'a>), - StoreLocal(StoreLocal<'a>), - // TaggedTemplate(TaggedTemplate<'a>), - // Template(Template<'a>), - // TypeCast(TypeCast<'a>), - // Unary(Unary<'a>), + LoadGlobal(LoadGlobal), + LoadLocal(LoadLocal), + // MethodCall(MethodCall), + // New(New), + // NextIterable(NextIterable), + // Object(Object), + Primitive(Primitive), + // PropertyDelete(PropertyDelete), + // PropertyLoad(PropertyLoad), + // PropertyStore(PropertyStore), + // RegExp(RegExp), + // StoreContext(StoreContext), + StoreLocal(StoreLocal), + // TaggedTemplate(TaggedTemplate), + // Template(Template), + // TypeCast(TypeCast), + // Unary(Unary), Tombstone, } #[derive(Debug)] -pub struct Array<'a> { - pub elements: Vec<'a, Option>, +pub struct Array { + pub elements: Vec>, } #[derive(Debug)] @@ -207,32 +206,32 @@ pub struct Binary { } #[derive(Debug)] -pub struct Call<'a> { +pub struct Call { pub callee: Operand, - pub arguments: Vec<'a, PlaceOrSpread>, + pub arguments: Vec, } #[derive(Debug)] -pub struct FunctionExpression<'a> { - pub dependencies: Vec<'a, Operand>, - pub lowered_function: Box>, +pub struct FunctionExpression { + pub dependencies: Vec, + pub lowered_function: Box, } #[derive(Debug, Clone, PartialEq, Eq)] -pub struct Primitive<'a> { - pub value: PrimitiveValue<'a>, +pub struct Primitive { + pub value: PrimitiveValue, } #[derive(Debug, Clone, PartialEq, Eq)] -pub enum PrimitiveValue<'a> { +pub enum PrimitiveValue { Boolean(bool), Null, Number(Number), - String(String<'a>), + String(String), Undefined, } -impl<'a> PrimitiveValue<'a> { +impl PrimitiveValue { pub fn is_truthy(&self) -> bool { match &self { PrimitiveValue::Boolean(value) => *value, @@ -370,8 +369,8 @@ impl std::ops::Div for Number { } #[derive(Debug)] -pub struct LoadLocal<'a> { - pub place: IdentifierOperand<'a>, +pub struct LoadLocal { + pub place: IdentifierOperand, } #[derive(Debug)] @@ -380,37 +379,37 @@ pub struct LoadContext { } #[derive(Debug, PartialEq, Eq, Clone)] -pub struct LoadGlobal<'a> { - pub name: String<'a>, +pub struct LoadGlobal { + pub name: String, } #[derive(Debug)] -pub struct DeclareLocal<'a> { - pub lvalue: LValue<'a>, +pub struct DeclareLocal { + pub lvalue: LValue, } #[derive(Debug)] -pub struct DeclareContext<'a> { - pub lvalue: LValue<'a>, // note: kind must be InstructionKind::Let +pub struct DeclareContext { + pub lvalue: LValue, // note: kind must be InstructionKind::Let } #[derive(Debug)] -pub struct StoreLocal<'a> { - pub lvalue: LValue<'a>, +pub struct StoreLocal { + pub lvalue: LValue, pub value: Operand, } #[derive(Debug)] -pub struct JSXElement<'a> { +pub struct JSXElement { pub tag: Operand, - pub props: Vec<'a, JSXAttribute<'a>>, - pub children: Option>, + pub props: Vec, + pub children: Option>, } #[derive(Debug)] -pub enum JSXAttribute<'a> { +pub enum JSXAttribute { Spread { argument: Operand }, - Attribute { name: String<'a>, value: Operand }, + Attribute { name: String, value: Operand }, } #[derive(Clone, Debug)] @@ -420,14 +419,14 @@ pub struct Operand { } #[derive(Clone, Debug)] -pub struct IdentifierOperand<'a> { - pub identifier: Identifier<'a>, +pub struct IdentifierOperand { + pub identifier: Identifier, pub effect: Option, } #[derive(Debug)] -pub struct LValue<'a> { - pub identifier: IdentifierOperand<'a>, +pub struct LValue { + pub identifier: IdentifierOperand, pub kind: InstructionKind, } @@ -503,10 +502,10 @@ impl Display for Effect { } #[derive(Clone, Debug)] -pub struct Identifier<'a> { +pub struct Identifier { /// Uniquely identifiers this identifier pub id: IdentifierId, - pub name: Option>, + pub name: Option, pub data: Rc>, } diff --git a/compiler/forget/crates/forget_hir/src/merge_consecutive_blocks.rs b/compiler/forget/crates/forget_hir/src/merge_consecutive_blocks.rs index a250595863..1bbab540c1 100644 --- a/compiler/forget/crates/forget_hir/src/merge_consecutive_blocks.rs +++ b/compiler/forget/crates/forget_hir/src/merge_consecutive_blocks.rs @@ -17,10 +17,7 @@ use crate::{ /// Note that this pass leaves value/loop blocks alone because they cannot /// be merged without breaking the structure of the high-level terminals /// that reference them. -pub fn merge_consecutive_blocks<'a>( - env: &Environment<'a>, - fun: &mut Function<'a>, -) -> Result<(), Diagnostic> { +pub fn merge_consecutive_blocks(env: &Environment, fun: &mut Function) -> Result<(), Diagnostic> { let mut merged = MergedBlocks::default(); let blocks = &mut fun.body.blocks; let instructions = &mut fun.body.instructions; diff --git a/compiler/forget/crates/forget_hir/src/print.rs b/compiler/forget/crates/forget_hir/src/print.rs index 88ecc06355..9e3c8bc706 100644 --- a/compiler/forget/crates/forget_hir/src/print.rs +++ b/compiler/forget/crates/forget_hir/src/print.rs @@ -12,11 +12,11 @@ use crate::{ /// handle things like indentation and maybe wrapping long lines. The /// `pretty` crate seems to have a lot of usage but the type signatures /// are pretty tedious, we can make something much simpler. -pub trait Print<'a> { - fn print(&self, hir: &HIR<'a>, out: &mut impl Write) -> Result; +pub trait Print { + fn print(&self, hir: &HIR, out: &mut impl Write) -> Result; } -impl<'a> Function<'a> { +impl Function { pub fn debug(&self) { let mut out = String::new(); self.print(&self.body, &mut out).unwrap(); @@ -24,8 +24,8 @@ impl<'a> Function<'a> { } } -impl<'a> Print<'a> for Function<'a> { - fn print(&self, hir: &HIR<'a>, out: &mut impl Write) -> Result { +impl Print for Function { + fn print(&self, hir: &HIR, out: &mut impl Write) -> Result { ensure_sufficient_stack(|| { writeln!( out, @@ -51,8 +51,8 @@ impl<'a> Print<'a> for Function<'a> { } } -impl<'a> Print<'a> for BasicBlock<'a> { - fn print(&self, hir: &HIR<'a>, out: &mut impl Write) -> Result { +impl Print for BasicBlock { + fn print(&self, hir: &HIR, out: &mut impl Write) -> Result { writeln!(out, "{} ({})", self.id, self.kind)?; if !self.predecessors.is_empty() { write!(out, " predecessors: ")?; @@ -83,8 +83,8 @@ impl<'a> Print<'a> for BasicBlock<'a> { } } -impl<'a> Print<'a> for Phi<'a> { - fn print(&self, hir: &HIR<'a>, out: &mut impl Write) -> Result { +impl Print for Phi { + fn print(&self, hir: &HIR, out: &mut impl Write) -> Result { write!(out, " ")?; self.identifier.print(hir, out)?; write!(out, ": phi(")?; @@ -100,8 +100,8 @@ impl<'a> Print<'a> for Phi<'a> { } } -impl<'a> Print<'a> for Instruction<'a> { - fn print(&self, hir: &HIR<'a>, out: &mut impl Write) -> Result { +impl Print for Instruction { + fn print(&self, hir: &HIR, out: &mut impl Write) -> Result { write!(out, " {} ", self.id)?; self.value.print(hir, out)?; writeln!(out, "")?; @@ -109,8 +109,8 @@ impl<'a> Print<'a> for Instruction<'a> { } } -impl<'a> Print<'a> for InstructionValue<'a> { - fn print(&self, hir: &HIR<'a>, out: &mut impl Write) -> Result { +impl Print for InstructionValue { + fn print(&self, hir: &HIR, out: &mut impl Write) -> Result { match self { InstructionValue::Array(value) => { write!(out, "Array [")?; @@ -211,8 +211,8 @@ impl<'a> Print<'a> for InstructionValue<'a> { } } -impl<'a> Print<'a> for PlaceOrSpread { - fn print(&self, hir: &HIR<'a>, out: &mut impl Write) -> Result { +impl Print for PlaceOrSpread { + fn print(&self, hir: &HIR, out: &mut impl Write) -> Result { match self { PlaceOrSpread::Place(place) => place.print(hir, out), PlaceOrSpread::Spread(place) => { @@ -224,8 +224,8 @@ impl<'a> Print<'a> for PlaceOrSpread { } } -impl<'a> Print<'a> for Operand { - fn print(&self, _hir: &HIR<'a>, out: &mut impl Write) -> Result { +impl Print for Operand { + fn print(&self, _hir: &HIR, out: &mut impl Write) -> Result { write!( out, "{} {}", @@ -238,15 +238,15 @@ impl<'a> Print<'a> for Operand { } } -impl<'a> Print<'a> for LValue<'a> { - fn print(&self, hir: &HIR<'a>, out: &mut impl Write) -> Result { +impl Print for LValue { + fn print(&self, hir: &HIR, out: &mut impl Write) -> Result { write!(out, "{} ", self.kind)?; self.identifier.print(hir, out) } } -impl<'a> Print<'a> for IdentifierOperand<'a> { - fn print(&self, hir: &HIR<'a>, out: &mut impl Write) -> Result { +impl Print for IdentifierOperand { + fn print(&self, hir: &HIR, out: &mut impl Write) -> Result { write!( out, "{} ", @@ -259,8 +259,8 @@ impl<'a> Print<'a> for IdentifierOperand<'a> { } } -impl<'a> Print<'a> for Identifier<'a> { - fn print(&self, _hir: &HIR<'a>, out: &mut impl Write) -> Result { +impl Print for Identifier { + fn print(&self, _hir: &HIR, out: &mut impl Write) -> Result { write!( out, "{}{}", @@ -273,8 +273,8 @@ impl<'a> Print<'a> for Identifier<'a> { } } -impl<'a> Print<'a> for Terminal<'a> { - fn print(&self, hir: &HIR<'a>, out: &mut impl Write) -> Result { +impl Print for Terminal { + fn print(&self, hir: &HIR, out: &mut impl Write) -> Result { write!(out, " {} ", self.id)?; self.value.print(hir, out)?; writeln!(out, "")?; @@ -282,8 +282,8 @@ impl<'a> Print<'a> for Terminal<'a> { } } -impl<'a> Print<'a> for TerminalValue<'a> { - fn print(&self, hir: &HIR<'a>, out: &mut impl Write) -> Result { +impl Print for TerminalValue { + fn print(&self, hir: &HIR, out: &mut impl Write) -> Result { match self { TerminalValue::Return(terminal) => { write!(out, "Return ")?; diff --git a/compiler/forget/crates/forget_hir/src/terminal.rs b/compiler/forget/crates/forget_hir/src/terminal.rs index 44adbb36ff..604bd0bec5 100644 --- a/compiler/forget/crates/forget_hir/src/terminal.rs +++ b/compiler/forget/crates/forget_hir/src/terminal.rs @@ -4,13 +4,13 @@ use crate::{BlockId, InstructionId}; /// Terminals represent statements or expressions that affect control flow, /// such as for-of, if-else, return, logical (??), ternaries (?:), etc. #[derive(Debug)] -pub struct Terminal<'a> { +pub struct Terminal { pub id: InstructionId, - pub value: TerminalValue<'a>, + pub value: TerminalValue, } #[derive(Debug)] -pub enum TerminalValue<'a> { +pub enum TerminalValue { Branch(BranchTerminal), DoWhile(DoWhileTerminal), // ForOf(ForOfTerminal), @@ -25,11 +25,11 @@ pub enum TerminalValue<'a> { // Switch(SwitchTerminal), // Ternary(TernaryTerminal), // Throw(ThrowTerminal), - Unsupported(UnsupportedTerminal<'a>), + Unsupported(UnsupportedTerminal), // While(WhileTerminal), } -impl<'a> TerminalValue<'a> { +impl TerminalValue { pub fn map_optional_fallthroughs(&mut self, f: F) -> () where F: Fn(BlockId) -> Option, @@ -103,9 +103,7 @@ impl<'a> TerminalValue<'a> { } #[derive(Debug)] -pub struct UnsupportedTerminal<'a> { - phantom: std::marker::PhantomData<&'a ()>, -} +pub struct UnsupportedTerminal {} #[derive(Debug)] pub struct BranchTerminal { diff --git a/compiler/forget/crates/forget_optimization/Cargo.toml b/compiler/forget/crates/forget_optimization/Cargo.toml index 6382d43acc..433a0e4f34 100644 --- a/compiler/forget/crates/forget_optimization/Cargo.toml +++ b/compiler/forget/crates/forget_optimization/Cargo.toml @@ -19,7 +19,6 @@ forget_ssa = { workspace = true } forget_build_hir = { workspace = true } forget_utils = { workspace = true } forget_diagnostics = { workspace = true } -bumpalo = { workspace = true } indexmap = { workspace = true } miette = { workspace = true } thiserror = { workspace = true } \ No newline at end of file diff --git a/compiler/forget/crates/forget_optimization/src/constant_propagation.rs b/compiler/forget/crates/forget_optimization/src/constant_propagation.rs index 87d869ab8e..6c8bd61c6e 100644 --- a/compiler/forget/crates/forget_optimization/src/constant_propagation.rs +++ b/compiler/forget/crates/forget_optimization/src/constant_propagation.rs @@ -9,18 +9,15 @@ use forget_hir::{ }; use forget_ssa::eliminate_redundant_phis; -pub fn constant_propagation<'a>( - env: &Environment<'a>, - fun: &mut Function<'a>, -) -> Result<(), Diagnostic> { +pub fn constant_propagation(env: &Environment, fun: &mut Function) -> Result<(), Diagnostic> { let mut constants = Constants::new(); constant_propagation_impl(env, fun, &mut constants) } -fn constant_propagation_impl<'a>( - env: &Environment<'a>, - fun: &mut Function<'a>, - constants: &mut Constants<'a>, +fn constant_propagation_impl( + env: &Environment, + fun: &mut Function, + constants: &mut Constants, ) -> Result<(), Diagnostic> { loop { let have_terminals_changed = apply_constant_propagation(env, fun, constants)?; @@ -55,16 +52,16 @@ fn constant_propagation_impl<'a>( Ok(()) } -fn apply_constant_propagation<'a>( - env: &Environment<'a>, - fun: &mut Function<'a>, - constants: &mut Constants<'a>, +fn apply_constant_propagation( + env: &Environment, + fun: &mut Function, + constants: &mut Constants, ) -> Result { let mut has_changes = false; for block in fun.body.blocks.iter_mut() { for phi in block.phis.iter() { - let mut value: Option> = None; + let mut value: Option = None; for (_, operand) in &phi.operands { if let Some(operand_value) = constants.get(&operand.id) { match &mut value { @@ -128,10 +125,7 @@ fn apply_constant_propagation<'a>( Ok(has_changes) } -fn read_primitive_instruction<'a>( - instrs: &[Instruction<'a>], - operand: &Operand, -) -> Option> { +fn read_primitive_instruction(instrs: &[Instruction], operand: &Operand) -> Option { let instr = &instrs[usize::from(operand.ix)].value; if let InstructionValue::Primitive(primitive) = instr { Some(primitive.clone()) @@ -140,11 +134,11 @@ fn read_primitive_instruction<'a>( } } -fn evaluate_instruction<'a>( - env: &Environment<'a>, - instrs: &[Instruction<'a>], - mut instr: &mut InstructionValue<'a>, - constants: &mut Constants<'a>, +fn evaluate_instruction( + env: &Environment, + instrs: &[Instruction], + mut instr: &mut InstructionValue, + constants: &mut Constants, ) -> Result<(), Diagnostic> { let read_constant = |operand: &Operand| { let instr = &instrs[usize::from(operand.ix)].value; @@ -189,7 +183,7 @@ fn evaluate_instruction<'a>( // the function (using its context variables list) // - Track the last such filtered Constants instance we visited the function // with. Only visit again if the Constants have changed. - let mut inner_constants: Constants<'a> = value + let mut inner_constants: Constants = value .lowered_function .context .iter() @@ -207,12 +201,12 @@ fn evaluate_instruction<'a>( Ok(()) } -fn apply_binary_operator<'a>( - _env: &Environment<'a>, - left: Primitive<'a>, +fn apply_binary_operator( + _env: &Environment, + left: Primitive, operator: BinaryOperator, - right: Primitive<'a>, -) -> Option> { + right: Primitive, +) -> Option { match (left.value, right.value) { (PrimitiveValue::Number(left), PrimitiveValue::Number(right)) => match operator { BinaryOperator::Add => Some(Primitive { @@ -271,16 +265,16 @@ fn apply_binary_operator<'a>( } } -type Constants<'a> = HashMap>; +type Constants = HashMap; #[derive(Debug, Clone, PartialEq, Eq)] -enum Constant<'a> { - Global(LoadGlobal<'a>), - Primitive(Primitive<'a>), +enum Constant { + Global(LoadGlobal), + Primitive(Primitive), } -impl<'a> From<&Constant<'a>> for InstructionValue<'a> { - fn from(value: &Constant<'a>) -> Self { +impl From<&Constant> for InstructionValue { + fn from(value: &Constant) -> Self { match value { Constant::Global(value) => InstructionValue::LoadGlobal(value.clone()), Constant::Primitive(value) => InstructionValue::Primitive(value.clone()), @@ -288,8 +282,8 @@ impl<'a> From<&Constant<'a>> for InstructionValue<'a> { } } -impl<'a> From> for InstructionValue<'a> { - fn from(value: Constant<'a>) -> Self { +impl From for InstructionValue { + fn from(value: Constant) -> Self { match value { Constant::Global(value) => InstructionValue::LoadGlobal(value), Constant::Primitive(value) => InstructionValue::Primitive(value), diff --git a/compiler/forget/crates/forget_ssa/Cargo.toml b/compiler/forget/crates/forget_ssa/Cargo.toml index e4eb2eab0d..da87d91826 100644 --- a/compiler/forget/crates/forget_ssa/Cargo.toml +++ b/compiler/forget/crates/forget_ssa/Cargo.toml @@ -16,7 +16,6 @@ repository.workspace = true forget_hir = { workspace = true } forget_utils = { workspace = true } forget_diagnostics = { workspace = true } -bumpalo = { workspace = true } indexmap = { workspace = true } miette = { workspace = true } thiserror = { workspace = true } \ No newline at end of file diff --git a/compiler/forget/crates/forget_ssa/src/eliminate_redundant_phis.rs b/compiler/forget/crates/forget_ssa/src/eliminate_redundant_phis.rs index 9e83eb564b..d882089ced 100644 --- a/compiler/forget/crates/forget_ssa/src/eliminate_redundant_phis.rs +++ b/compiler/forget/crates/forget_ssa/src/eliminate_redundant_phis.rs @@ -1,7 +1,6 @@ use std::collections::{HashMap, HashSet}; use forget_hir::{BlockId, Environment, Function, Identifier, IdentifierId, InstructionValue}; -use forget_utils::RetainMut; /// Pass to eliminate redundant phi nodes: /// all operands are the same identifier, ie `x2 = phi(x1, x1, x1)`. @@ -15,8 +14,8 @@ use forget_utils::RetainMut; /// phi is encountered we add a mapping (eg x2 -> x1) to a rewrite table. Subsequent instructions, terminals, /// and phis rewrite all their identifiers based on this table. The algorithm loops over the CFG repeatedly /// until there are no new rewrites: for a CFG without back-edges it completes in a single pass. -type Rewrites<'a> = HashMap>; -pub fn eliminate_redundant_phis<'a>(env: &Environment, fun: &mut Function<'a>) { +type Rewrites = HashMap; +pub fn eliminate_redundant_phis(env: &Environment, fun: &mut Function) { let hir = &mut fun.body; let mut rewrites = Rewrites::new(); @@ -97,7 +96,7 @@ pub fn eliminate_redundant_phis<'a>(env: &Environment, fun: &mut Function<'a>) { } } -fn rewrite<'a>(rewrites: &Rewrites<'a>, identifier: &mut Identifier<'a>) { +fn rewrite(rewrites: &Rewrites, identifier: &mut Identifier) { if let Some(rewrite) = rewrites.get(&identifier.id) { *identifier = rewrite.clone() } diff --git a/compiler/forget/crates/forget_ssa/src/enter.rs b/compiler/forget/crates/forget_ssa/src/enter.rs index 3e3189438e..df8c8cf167 100644 --- a/compiler/forget/crates/forget_ssa/src/enter.rs +++ b/compiler/forget/crates/forget_ssa/src/enter.rs @@ -1,7 +1,6 @@ use std::cell::RefCell; use std::rc::Rc; -use bumpalo::collections::Vec; use forget_diagnostics::{invariant, Diagnostic}; use forget_hir::{ BasicBlock, BlockId, Blocks, Environment, Function, Identifier, IdentifierData, IdentifierId, @@ -9,15 +8,15 @@ use forget_hir::{ }; use indexmap::{IndexMap, IndexSet}; -pub fn enter_ssa<'a>(env: &Environment<'a>, fun: &mut Function<'a>) -> Result<(), Diagnostic> { +pub fn enter_ssa(env: &Environment, fun: &mut Function) -> Result<(), Diagnostic> { assert!(fun.context.is_empty()); enter_ssa_impl(env, fun, None) } -pub fn enter_ssa_impl<'a>( - env: &Environment<'a>, - fun: &mut Function<'a>, - context_defs: Option>>, +pub fn enter_ssa_impl( + env: &Environment, + fun: &mut Function, + context_defs: Option>, ) -> Result<(), Diagnostic> { let blocks = &fun.body.blocks; let instructions = &mut fun.body.instructions; @@ -40,10 +39,10 @@ pub fn enter_ssa_impl<'a>( Ok(()) } -fn visit_instructions<'a, 'e, 'f>( - env: &Environment<'a>, - builder: &mut Builder<'a, 'e, 'f>, - instructions: &mut Vec<'a, Instruction<'a>>, +fn visit_instructions<'e, 'f>( + env: &Environment, + builder: &mut Builder<'e, 'f>, + instructions: &mut Vec, ) -> Result<(), Diagnostic> { builder.each_block(|block, builder| { for instr_ix in &block.instructions { @@ -75,11 +74,11 @@ fn visit_instructions<'a, 'e, 'f>( } #[derive(Debug)] -struct Builder<'a, 'e, 'f> { - env: &'e Environment<'a>, - blocks: &'f Blocks<'a>, +struct Builder<'e, 'f> { + env: &'e Environment, + blocks: &'f Blocks, - states: IndexMap>, + states: IndexMap, current: BlockId, unsealed_predecessors: IndexMap, unknown: IndexSet, @@ -87,34 +86,34 @@ struct Builder<'a, 'e, 'f> { } #[derive(Debug)] -struct BlockState<'a> { - defs: IndexMap>, - incomplete_phis: Vec<'a, IncompletePhi<'a>>, - phis: Vec<'a, Phi<'a>>, +struct BlockState { + defs: IndexMap, + incomplete_phis: Vec, + phis: Vec, } -impl<'a> BlockState<'a> { - fn new(env: &Environment<'a>) -> Self { +impl BlockState { + fn new() -> Self { Self { defs: Default::default(), - incomplete_phis: env.vec_new(), - phis: env.vec_new(), + incomplete_phis: Default::default(), + phis: Default::default(), } } } #[derive(Debug)] -struct IncompletePhi<'a> { - old_id: Identifier<'a>, - new_id: Identifier<'a>, +struct IncompletePhi { + old_id: Identifier, + new_id: Identifier, } -impl<'a, 'e, 'f> Builder<'a, 'e, 'f> { - fn new(env: &'e Environment<'a>, entry: BlockId, blocks: &'f Blocks<'a>) -> Self { +impl<'e, 'f> Builder<'e, 'f> { + fn new(env: &'e Environment, entry: BlockId, blocks: &'f Blocks) -> Self { let states = blocks .block_ids() .into_iter() - .map(|block_id| (block_id, BlockState::new(env))) + .map(|block_id| (block_id, BlockState::new())) .collect(); Self { env, @@ -127,12 +126,12 @@ impl<'a, 'e, 'f> Builder<'a, 'e, 'f> { } } - fn initialize_context(&mut self, defs: IndexMap>) { + fn initialize_context(&mut self, defs: IndexMap) { let state = self.states.get_mut(&self.current).unwrap(); state.defs = defs; } - fn complete(self) -> IndexMap> { + fn complete(self) -> IndexMap { self.states } @@ -140,7 +139,7 @@ impl<'a, 'e, 'f> Builder<'a, 'e, 'f> { self.env.next_identifier_id() } - fn visit_store(&mut self, lvalue: &mut LValue<'a>) -> Result<(), Diagnostic> { + fn visit_store(&mut self, lvalue: &mut LValue) -> Result<(), Diagnostic> { let old_identifier = &lvalue.identifier.identifier; // TODO: use Result (?) invariant(!self.unknown.contains(&old_identifier.id), || { @@ -163,7 +162,7 @@ impl<'a, 'e, 'f> Builder<'a, 'e, 'f> { Ok(()) } - fn visit_param(&mut self, param: &mut IdentifierOperand<'a>) -> () { + fn visit_param(&mut self, param: &mut IdentifierOperand) -> () { let old_identifier = ¶m.identifier; let new_identifier = self.make_identifier(old_identifier); let state = self.states.get_mut(&self.current).unwrap(); @@ -171,12 +170,12 @@ impl<'a, 'e, 'f> Builder<'a, 'e, 'f> { param.identifier = new_identifier; } - fn visit_load(&mut self, local: &mut IdentifierOperand<'a>) -> () { + fn visit_load(&mut self, local: &mut IdentifierOperand) -> () { let new_identifier = self.get_id_at(self.current, &local.identifier); local.identifier = new_identifier; } - fn get_id_at(&mut self, block_id: BlockId, old_identifier: &Identifier<'a>) -> Identifier<'a> { + fn get_id_at(&mut self, block_id: BlockId, old_identifier: &Identifier) -> Identifier { // Check if we've already resolved this identifier in this block let state = self.states.get(&block_id).unwrap(); if let Some(identifier) = state.defs.get(&old_identifier.id) { @@ -219,9 +218,9 @@ impl<'a, 'e, 'f> Builder<'a, 'e, 'f> { fn add_phi( &mut self, block_id: BlockId, - old_identifier: &Identifier<'a>, - new_identifier: Identifier<'a>, - ) -> Identifier<'a> { + old_identifier: &Identifier, + new_identifier: Identifier, + ) -> Identifier { let mut phi = Phi { identifier: new_identifier.clone(), operands: Default::default(), @@ -237,7 +236,7 @@ impl<'a, 'e, 'f> Builder<'a, 'e, 'f> { new_identifier } - fn make_identifier(&self, old_identifier: &Identifier<'a>) -> Identifier<'a> { + fn make_identifier(&self, old_identifier: &Identifier) -> Identifier { let old_data = old_identifier.data.borrow(); Identifier { id: self.next_ssa_id(), @@ -252,7 +251,7 @@ impl<'a, 'e, 'f> Builder<'a, 'e, 'f> { fn fix_incomplete_phis(&mut self, block_id: BlockId) -> () { let state = self.states.get_mut(&block_id).unwrap(); - let incomplete_phis = std::mem::replace(&mut state.incomplete_phis, self.env.vec_new()); + let incomplete_phis = std::mem::take(&mut state.incomplete_phis); for phi in incomplete_phis { self.add_phi(block_id, &phi.old_id, phi.new_id); } @@ -260,7 +259,7 @@ impl<'a, 'e, 'f> Builder<'a, 'e, 'f> { fn each_block(&mut self, mut f: F) -> Result<(), Diagnostic> where - F: FnMut(&BasicBlock<'a>, &mut Self) -> Result<(), Diagnostic>, + F: FnMut(&BasicBlock, &mut Self) -> Result<(), Diagnostic>, { let mut visited = IndexSet::new(); let block_ids = self.blocks.block_ids(); diff --git a/compiler/forget/crates/forget_ssa/src/leave.rs b/compiler/forget/crates/forget_ssa/src/leave.rs index 599591e047..ef968348a0 100644 --- a/compiler/forget/crates/forget_ssa/src/leave.rs +++ b/compiler/forget/crates/forget_ssa/src/leave.rs @@ -1,5 +1,5 @@ use forget_hir::{Environment, HIR}; -pub fn leave_ssa<'a>(_env: &'a Environment, _hir: &mut HIR<'a>) { +pub fn leave_ssa(_env: &Environment, _hir: &mut HIR) { todo!("leave_ssa()"); } diff --git a/compiler/forget/crates/forget_utils/Cargo.toml b/compiler/forget/crates/forget_utils/Cargo.toml index 748695e2e0..61d4d55904 100644 --- a/compiler/forget/crates/forget_utils/Cargo.toml +++ b/compiler/forget/crates/forget_utils/Cargo.toml @@ -13,5 +13,4 @@ repository.workspace = true # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -bumpalo = { workspace = true } stacker = { workspace = true } diff --git a/compiler/forget/crates/forget_utils/src/lib.rs b/compiler/forget/crates/forget_utils/src/lib.rs index ce8ab25562..a410ea2f58 100644 --- a/compiler/forget/crates/forget_utils/src/lib.rs +++ b/compiler/forget/crates/forget_utils/src/lib.rs @@ -1,5 +1,3 @@ mod ensure_sufficient_stack; -mod retain_mut; pub use ensure_sufficient_stack::*; -pub use retain_mut::*; diff --git a/compiler/forget/crates/forget_utils/src/retain_mut.rs b/compiler/forget/crates/forget_utils/src/retain_mut.rs deleted file mode 100644 index 174e1c3a3a..0000000000 --- a/compiler/forget/crates/forget_utils/src/retain_mut.rs +++ /dev/null @@ -1,113 +0,0 @@ -use bumpalo::collections::Vec; - -pub trait RetainMut { - fn retain_mut(&mut self, f: F) -> () - where - F: FnMut(&mut T) -> bool; -} - -impl<'a, T> RetainMut for Vec<'a, T> { - fn retain_mut(&mut self, mut f: F) -> () - where - F: FnMut(&mut T) -> bool, - { - // NOTE: implementation adapted from retain_mut crate - // which is in turn adapted from Rust stdlib - // https://docs.rs/retain_mut/latest/src/retain_mut/lib.rs.html#68-69 - - let original_len = self.len(); - // Avoid double drop if the drop guard is not executed, - // since we may make some holes during the process. - unsafe { self.set_len(0) }; - - // Vec: [Kept, Kept, Hole, Hole, Hole, Hole, Unchecked, Unchecked] - // |<- processed len ->| ^- next to check - // |<- deleted cnt ->| - // |<- original_len ->| - // Kept: Elements which predicate returns true on. - // Hole: Moved or dropped element slot. - // Unchecked: Unchecked valid elements. - // - // This drop guard will be invoked when predicate or `drop` of element panicked. - // It shifts unchecked elements to cover holes and `set_len` to the correct length. - // In cases when predicate and `drop` never panick, it will be optimized out. - struct BackshiftOnDrop<'a, 'b, T> { - v: &'b mut Vec<'a, T>, - processed_len: usize, - deleted_cnt: usize, - original_len: usize, - } - - impl Drop for BackshiftOnDrop<'_, '_, T> { - fn drop(&mut self) { - if self.deleted_cnt > 0 { - // SAFETY: Trailing unchecked items must be valid since we never touch them. - unsafe { - std::ptr::copy( - self.v.as_ptr().add(self.processed_len), - self.v - .as_mut_ptr() - .add(self.processed_len - self.deleted_cnt), - self.original_len - self.processed_len, - ); - } - } - // SAFETY: After filling holes, all items are in contiguous memory. - unsafe { - self.v.set_len(self.original_len - self.deleted_cnt); - } - } - } - - let mut g = BackshiftOnDrop { - v: self, - processed_len: 0, - deleted_cnt: 0, - original_len, - }; - - fn process_loop( - original_len: usize, - f: &mut F, - g: &mut BackshiftOnDrop<'_, '_, T>, - ) where - F: FnMut(&mut T) -> bool, - { - while g.processed_len != original_len { - // SAFETY: Unchecked element must be valid. - let cur = unsafe { &mut *g.v.as_mut_ptr().add(g.processed_len) }; - if !f(cur) { - // Advance early to avoid double drop if `drop_in_place` panicked. - g.processed_len += 1; - g.deleted_cnt += 1; - // SAFETY: We never touch this element again after dropped. - unsafe { std::ptr::drop_in_place(cur) }; - // We already advanced the counter. - if DELETED { - continue; - } else { - break; - } - } - if DELETED { - // SAFETY: `deleted_cnt` > 0, so the hole slot must not overlap with current element. - // We use copy for move, and never touch this element again. - unsafe { - let hole_slot = g.v.as_mut_ptr().add(g.processed_len - g.deleted_cnt); - std::ptr::copy_nonoverlapping(cur, hole_slot, 1); - } - } - g.processed_len += 1; - } - } - - // Stage 1: Nothing was deleted. - process_loop::(original_len, &mut f, &mut g); - - // Stage 2: Some elements were deleted. - process_loop::(original_len, &mut f, &mut g); - - // All item are processed. This can be optimized to `set_len` by LLVM. - drop(g); - } -}