main
md 122 lines 6.32 KB
Rendered Raw
1 # Rust Port Gap Analysis
2
3 Comprehensive comparison of the TypeScript and Rust compiler implementations.
4 Generated 2026-03-30 from systematic review of all major subsystems.
5
6 Current test status: Pass 1717/1717, Code 1716/1717, Snap 1717/1718.
7
8 ---
9
10 ## Critical Gaps (incorrect compilation possible)
11
12 ### 3. Hardcoded `useMemoCache` identifier name
13 - **TS**: `ReactiveScopes/CodegenReactiveFunction.ts:166-178`
14 ```typescript
15 const useMemoCacheIdentifier = fn.env.programContext.addMemoCacheImport().name;
16 ```
17 - **Rust**: `react_compiler_reactive_scopes/src/codegen_reactive_function.rs:179`
18 ```rust
19 callee: Box::new(Expression::Identifier(make_identifier("useMemoCache"))),
20 ```
21 - The TS dynamically resolves the `useMemoCache` import to `_c` (from `react/compiler-runtime` import specifier `c`). The Rust hardcodes `"useMemoCache"`. The BabelPlugin.ts wrapper handles the rename to `_c` during AST application, so this works in practice, but it means the codegen output has an incorrect intermediate identifier.
22
23
24 ---
25
26 ## Moderate Gaps (feature gaps or edge cases)
27
28 ### 6. Missing `optimizeForSSR` pass
29 - **TS**: `Entrypoint/Pipeline.ts:223-226`
30 - **Rust**: MISSING entirely
31 - Inlines useState/useReducer, removes effects, strips event handlers from JSX, removes refs. Without it, SSR-mode compilation produces unoptimized output.
32
33 ### 7. Missing `enableForest` codegen path
34 - **TS**: `ReactiveScopes/CodegenReactiveFunction.ts:1527-1536`
35 - **Rust**: MISSING
36 - Skips hook guard wrapping and emits `typeArguments` on call expressions. Missing in Rust means forest mode has incorrect hook wrapping and dropped type arguments.
37
38 ### 8. Function name inference from AssignmentExpression and Property
39 - **TS**: `Entrypoint/Program.ts:1226-1268` — three cases: `parent.isAssignmentExpression()`, `parent.isProperty()`, `parent.isAssignmentPattern()`
40 - **Rust**: `program.rs:1483-1488` — only handles `VariableDeclarator`
41 - Functions in `Foo = () => {}`, `{useFoo: () => {}}`, or `{useFoo = () => {}} = {}` positions are nameless in Rust, preventing component/hook detection via name heuristics.
42
43 ### 9. Missing validations in outlined function pipeline
44 - **TS**: Outlined functions go through full `compileFn` → all validations
45 - **Rust**: `run_pipeline_passes` skips: `validateContextVariableLValues`, `validateUseMemo`, `validateNoDerivedComputationsInEffects/_exp`, `validateNoSetStateInEffects`, `validateNoJSXInTryStatement`, `validateNoCapitalizedCalls`, `validateStaticComponents`
46 - Also missing: `has_errors()` check at end, `memo_cache_import` registration
47
48 ### 10. Reanimated flag injection missing
49 - **TS**: `Babel/BabelPlugin.ts:48-53` — `injectReanimatedFlag(opts)` sets `enableCustomTypeDefinitionForReanimated = true`
50 - **Rust**: Detects reanimated but doesn't inject the flag into environment config
51 - Custom type definitions for reanimated shared values won't activate.
52
53 ### 11. Dev-mode `enableResetCacheOnSourceFileChanges` injection missing
54 - **TS**: `Babel/BabelPlugin.ts:54-65` — auto-enables in dev mode
55 - **Rust**: MISSING
56 - Fast refresh cache-reset code won't generate in dev mode unless explicitly configured.
57
58 ### 12. Outlined functions not re-queued for compilation
59 - **TS**: `Entrypoint/Program.ts:476-501` — outlined functions with a React function type are pushed back into the compilation queue
60 - **Rust**: `program.rs:2244-2262` — only does AST insertion
61 - Outlined functions don't receive full compilation treatment (memoization).
62
63 ### 13. Missing `addNewReference` in RenameVariables
64 - **TS**: `ReactiveScopes/RenameVariables.ts:163` — `this.#programContext.addNewReference(name)`
65 - **Rust**: MISSING
66 - Newly created variable names aren't registered with the program context, risking import binding conflicts.
67
68 ### 14. `known_incompatible` not checked for legacy signatures without aliasing config
69 - **TS**: `Inference/InferMutationAliasingEffects.ts:2351-2370`
70 - **Rust**: `infer_mutation_aliasing_effects.rs:2099-2100` — TODO comment, only checked in the `Apply` path with aliasing configs
71 - If any legacy signatures (without aliasing configs) have `known_incompatible` set, Rust silently continues.
72
73 ---
74
75 ## Minor Gaps (cosmetic, defensive, or unlikely to trigger)
76
77 ### 15. Missing `assertValidMutableRanges` pass
78 - **TS**: `Pipeline.ts:246-249` — gated behind `config.assertValidMutableRanges` (defaults false)
79 - **Rust**: Config flag exists but pass never called
80 - Debugging-only validation, no production impact.
81
82 ### 16. Missing `ValidateNoDerivedComputationsInEffects_exp` experimental variant
83 - **TS**: 842-line experimental validation pass
84 - **Rust**: MISSING — only the non-experimental version is ported
85 - Only affects users who explicitly enable the experimental flag in lint mode.
86
87 ### 17. Missing `CompileUnexpectedThrow` event
88 - **TS**: `Program.ts:755-769` — logs when a pass incorrectly throws
89 - **Rust**: Event type defined but never emitted
90 - Development-time detection of misbehaving passes.
91
92 ### 18. Missing error for `sources`-specified-without-filename
93 - **TS**: Creates a Config error via `handleError`
94 - **Rust**: Silently sets `shouldCompile = false`
95
96 ### 19. Missing `codegen_block` temporary invariant check
97 - **TS**: `CodegenReactiveFunction.ts:474-492` — verifies no temporary was overwritten
98 - **Rust**: Restores snapshot without checking
99
100 ### 20. Extra `NullLiteralTypeAnnotation` rejection
101 - **Rust** rejects Flow `null` type annotation on first param (over-conservative vs TS)
102
103 ### 21. `UnsignedShiftRight` (`>>>`) not classified as primitive binary op
104 - **Rust**: `infer_types.rs:140-159` — missing from `is_primitive_binary_op`
105 - Operands won't be constrained to Primitive type, but result is still Primitive.
106
107 ### 22. Post-dominator frontier not cached in InferReactivePlaces
108 - **Rust**: Recomputes frontier on every call instead of caching per block ID
109 - Performance issue only, not correctness.
110
111 ### 23. `Math.random` missing `restParam`
112 - **TS**: `restParam: Effect.Read`
113 - **Rust**: `rest_param: None` (uses default `..Default::default()`)
114 - Affects extra-argument fallback effect only.
115
116 ### 24. `WeakSet.has` / `WeakMap.has` wrong signature shape
117 - **TS**: `positionalParams: [Effect.Read], restParam: null`
118 - **Rust**: Uses `pure_primitive_fn``positional_params: [], rest_param: Some(Effect::Read)`
119 - Difference in extra-argument fallback behavior only.
120
121 ### 25. Missing `throwUnknownException__testonly` in outlined function pipeline
122 - Test-only feature.