diff --git a/crates/oxc_transformer/src/common/arrow_function_converter.rs b/crates/oxc_transformer/src/common/arrow_function_converter.rs index dc8006e6f5bfa..40326e4ff7af9 100644 --- a/crates/oxc_transformer/src/common/arrow_function_converter.rs +++ b/crates/oxc_transformer/src/common/arrow_function_converter.rs @@ -419,7 +419,7 @@ impl<'a> Traverse<'a> for ArrowFunctionConverter<'a> { // prop = (() => { return async () => {} })(); // } // ``` - Some(wrap_arrow_function_iife(expr, ctx)) + Some(wrap_arrow_function_iife(ctx.ast.move_expression(expr), ctx)) } else { return; } diff --git a/crates/oxc_transformer/src/es2020/optional_chaining.rs b/crates/oxc_transformer/src/es2020/optional_chaining.rs index 8222b98dda37e..d673efd2ede1f 100644 --- a/crates/oxc_transformer/src/es2020/optional_chaining.rs +++ b/crates/oxc_transformer/src/es2020/optional_chaining.rs @@ -283,7 +283,7 @@ impl<'a> OptionalChaining<'a, '_> { // To insert the temp binding in the correct scope, we wrap the expression with // an arrow function. During the chain expression transformation, the temp binding // will be inserted into the arrow function's body. - wrap_arrow_function_iife(expr, ctx) + wrap_arrow_function_iife(ctx.ast.move_expression(expr), ctx) } else { self.transform_chain_expression_impl(false, expr, ctx) } @@ -297,7 +297,7 @@ impl<'a> OptionalChaining<'a, '_> { ) { *expr = if self.is_inside_function_parameter { // Same as the above `transform_chain_expression` explanation - wrap_arrow_function_iife(expr, ctx) + wrap_arrow_function_iife(ctx.ast.move_expression(expr), ctx) } else { // Unfortunately no way to get compiler to see that this branch is provably unreachable. // We don't want to inline this function, to keep `enter_expression` as small as possible. diff --git a/crates/oxc_transformer/src/utils/ast_builder.rs b/crates/oxc_transformer/src/utils/ast_builder.rs index 8ffbd796c8581..079ae29e7000e 100644 --- a/crates/oxc_transformer/src/utils/ast_builder.rs +++ b/crates/oxc_transformer/src/utils/ast_builder.rs @@ -37,20 +37,20 @@ pub(crate) fn create_call_call<'a>( ctx.ast.expression_call(span, callee, NONE, arguments, false) } -/// Wrap the expression with an arrow function iife. +/// Wrap an `Expression` in an arrow function IIFE (immediately invoked function expression) +/// with a body block. /// /// `expr` -> `(() => { return expr; })()` pub(crate) fn wrap_arrow_function_iife<'a>( - expr: &mut Expression<'a>, + expr: Expression<'a>, ctx: &mut TraverseCtx<'a>, ) -> Expression<'a> { let scope_id = - ctx.insert_scope_below_expression(expr, ScopeFlags::Arrow | ScopeFlags::Function); + ctx.insert_scope_below_expression(&expr, ScopeFlags::Arrow | ScopeFlags::Function); let kind = FormalParameterKind::ArrowFormalParameters; let params = ctx.ast.formal_parameters(SPAN, kind, ctx.ast.vec(), NONE); - let statements = - ctx.ast.vec1(ctx.ast.statement_return(SPAN, Some(ctx.ast.move_expression(expr)))); + let statements = ctx.ast.vec1(ctx.ast.statement_return(SPAN, Some(expr))); let body = ctx.ast.function_body(SPAN, ctx.ast.vec(), statements); let arrow = ctx.ast.alloc_arrow_function_expression_with_scope_id( SPAN, false, false, NONE, params, NONE, body, scope_id,