[rust-compiler] Bail out on nested TypeScript this parameters (#37232)

## Summary

Propagate errors returned while lowering block statements instead of
discarding them and continuing with partially built HIR.

The original issue was triggered by the SWC path, where a TypeScript
`this` pseudo-parameter remains in the AST but is omitted from
`ScopeInfo`. Lowering rejects the AST parameter, but the function-body
block wrapper previously swallowed that error and returned a partial
function.

```ts
function Component() {
  useEffect(() => {
    const get = (): Val => {
      window.value = {
        count: 0,
        method(this: Val) {},
      };
      return window.value;
    };
    get().count++;
  }, []);
}
```

This could emit a partial transform with the assignment removed:

```js
function Component() {
  useEffect(() => {
    const get = () => {
      return window.value;
    };
    get().count++;
  }, []);
}
```

## How did you test this change?

Added a [source-level reproduction against the SWC
adapter](https://github.com/wbinnssmith/swc/blob/114e9c55b2/crates/swc_ecma_react_compiler/src/tests/integration.rs#L1563-L1591)
using the same case above.

- With the current lowering crate, the test fails because the adapter
emits a partial program.
- With this change patched into the lowering dependency, the test passes
because compilation bails out.
- `cargo test --manifest-path compiler/Cargo.toml -p
react_compiler_lowering`
This commit is contained in:
Will Binns-Smith
2026-08-24 15:23:00 -07:00
committed by GitHub
parent 3d050805e8
commit 35e64cf2bc
@@ -2589,8 +2589,12 @@ fn lower_block_statement(
block: &react_compiler_ast::statements::BlockStatement,
parent_scope: Option<react_compiler_ast::scope::ScopeId>,
) -> Result<(), CompilerError> {
let _ = lower_block_statement_inner(builder, block, None, parent_scope);
Ok(())
Ok(lower_block_statement_inner(
builder,
block,
None,
parent_scope,
)?)
}
fn lower_block_statement_with_scope(
@@ -2598,8 +2602,12 @@ fn lower_block_statement_with_scope(
block: &react_compiler_ast::statements::BlockStatement,
scope_override: react_compiler_ast::scope::ScopeId,
) -> Result<(), CompilerError> {
let _ = lower_block_statement_inner(builder, block, Some(scope_override), None);
Ok(())
Ok(lower_block_statement_inner(
builder,
block,
Some(scope_override),
None,
)?)
}
fn lower_block_statement_inner(