Skip to content

[rust-compiler] Allow Flow TypeCastExpression in PatternLike#36518

Open
poteto wants to merge 1 commit into
lauren/swc-12-predicate-null-preservefrom
lauren/swc-13-flow-typecast-in-pattern
Open

[rust-compiler] Allow Flow TypeCastExpression in PatternLike#36518
poteto wants to merge 1 commit into
lauren/swc-12-predicate-null-preservefrom
lauren/swc-13-flow-typecast-in-pattern

Conversation

@poteto
Copy link
Copy Markdown
Collaborator

@poteto poteto commented May 21, 2026

PatternLike already had the four TS cast wrapper variants
(TSAsExpression, TSSatisfiesExpression, TSNonNullExpression,
TSTypeAssertion) so that (x as T) = ... style assignment
targets and parameter positions are representable. Flow's analogue
of those wrappers is TypeCastExpression, e.g.

function f(fallback: React.Node = <></>): void { ... }

where fallback: React.Node = <></> reaches the converter as an
AssignmentPattern whose left is a TypeCastExpression over the
binding identifier. The round-trip test rejected this with:

Deserialization error: unknown variant `TypeCastExpression`,
expected one of `Identifier`, `ObjectPattern`, ... `TSTypeAssertion`

Add TypeCastExpression as the sixth expression-like variant of
PatternLike, reusing the existing
crate::expressions::TypeCastExpression struct (which already
matches Babel's { expression, typeAnnotation } shape and is
already handled on the expression side).

Wire the new variant through every exhaustive PatternLike match
the workspace requires, mirroring the existing TS wrapper
handling at each site:

  • react_compiler_ast/src/visitor.rs::walk_pattern: recurse into
    the inner expression.
  • react_compiler_lowering/src/find_context_identifiers.rs: record
    the TS-faithful [FindContextIdentifiers] Cannot handle Object destructuring assignment target TypeCastExpression Todo.
  • react_compiler_lowering/src/build_hir.rs: fall-through arms in
    pattern_like_loc, pattern_declares_name,
    collect_binding_names_from_pattern, lower_assignment, and the
    inner-function-parameter walker.
  • react_compiler/src/entrypoint/program.rs: fall-through arms in
    calls_hooks_or_creates_jsx_in_pattern and
    is_valid_props_annotation.
  • react_compiler/src/entrypoint/validate_source_locations.rs:
    fall-through arms in the original/generated pattern collectors.
  • react_compiler_swc/src/convert_ast_reverse.rs: convert to
    Pat::Expr (mirrors TS wrappers); use __unknown__ placeholder
    in the assign-target path.
  • react_compiler_oxc/src/convert_ast.rs and
    react_compiler_oxc/src/convert_ast_reverse.rs: equivalent
    no-op / placeholder arms in the OXC frontend.

No new behavior is introduced. The reverse converters fall through
the same way they do for TS wrappers, and the Todo emission
matches the TS reference behavior for an unsupported assignment-
target wrapper.

Fixes 1 round-trip parity failure:

  • error.todo-round2_fn_type_component_to_other.js

Test plan:

  • bash compiler/scripts/test-babel-ast.sh:
    Before: 1778/1780 round-trip (2 failures)
    After: 1779/1780 round-trip (1 failure, 1 fixed)
    Remaining failure (lone-surrogate-string-values.js) is unrelated;
    handled in the next commit as a skip-list entry pending WTF-8
    string-representation work.
  • cargo build: clean across the workspace.

`PatternLike` already had the four TS cast wrapper variants
(`TSAsExpression`, `TSSatisfiesExpression`, `TSNonNullExpression`,
`TSTypeAssertion`) so that `(x as T) = ...` style assignment
targets and parameter positions are representable. Flow's analogue
of those wrappers is `TypeCastExpression`, e.g.

    function f(fallback: React.Node = <></>): void { ... }

where `fallback: React.Node = <></>` reaches the converter as an
`AssignmentPattern` whose `left` is a `TypeCastExpression` over the
binding identifier. The round-trip test rejected this with:

    Deserialization error: unknown variant `TypeCastExpression`,
    expected one of `Identifier`, `ObjectPattern`, ... `TSTypeAssertion`

Add `TypeCastExpression` as the sixth expression-like variant of
`PatternLike`, reusing the existing
`crate::expressions::TypeCastExpression` struct (which already
matches Babel's `{ expression, typeAnnotation }` shape and is
already handled on the expression side).

Wire the new variant through every exhaustive `PatternLike` match
the workspace requires, mirroring the existing TS wrapper
handling at each site:

- `react_compiler_ast/src/visitor.rs::walk_pattern`: recurse into
  the inner expression.
- `react_compiler_lowering/src/find_context_identifiers.rs`: record
  the TS-faithful `[FindContextIdentifiers] Cannot handle Object
  destructuring assignment target TypeCastExpression` Todo.
- `react_compiler_lowering/src/build_hir.rs`: fall-through arms in
  `pattern_like_loc`, `pattern_declares_name`,
  `collect_binding_names_from_pattern`, `lower_assignment`, and the
  inner-function-parameter walker.
- `react_compiler/src/entrypoint/program.rs`: fall-through arms in
  `calls_hooks_or_creates_jsx_in_pattern` and
  `is_valid_props_annotation`.
- `react_compiler/src/entrypoint/validate_source_locations.rs`:
  fall-through arms in the original/generated pattern collectors.
- `react_compiler_swc/src/convert_ast_reverse.rs`: convert to
  `Pat::Expr` (mirrors TS wrappers); use `__unknown__` placeholder
  in the assign-target path.
- `react_compiler_oxc/src/convert_ast.rs` and
  `react_compiler_oxc/src/convert_ast_reverse.rs`: equivalent
  no-op / placeholder arms in the OXC frontend.

No new behavior is introduced. The reverse converters fall through
the same way they do for TS wrappers, and the Todo emission
matches the TS reference behavior for an unsupported assignment-
target wrapper.

Fixes 1 round-trip parity failure:
- error.todo-round2_fn_type_component_to_other.js

Test plan:
- bash compiler/scripts/test-babel-ast.sh:
    Before: 1778/1780 round-trip (2 failures)
    After:  1779/1780 round-trip (1 failure, 1 fixed)
  Remaining failure (`lone-surrogate-string-values.js`) is unrelated;
  handled in the next commit as a skip-list entry pending WTF-8
  string-representation work.
- cargo build: clean across the workspace.
@github-actions github-actions Bot added the React Core Team Opened by a member of the React Core Team label May 21, 2026
@meta-cla meta-cla Bot added the CLA Signed label May 21, 2026
@poteto poteto requested a review from mvitousek May 21, 2026 18:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed React Core Team Opened by a member of the React Core Team

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant