mirror of
https://github.com/facebook/react.git
synced 2026-02-26 03:45:17 +00:00
Add concise fault tolerance documentation to CLAUDE.md and the passes README covering error accumulation, tryRecord wrapping, and the distinction between validation vs infrastructure passes. Remove the detailed planning document now that the work is complete.
React Compiler Passes Documentation
This directory contains detailed documentation for each pass in the React Compiler pipeline. The compiler transforms React components and hooks to add automatic memoization.
High-Level Architecture
┌─────────────────────────────────────────────────────────────┐
│ COMPILATION PIPELINE │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────────────────────┐
│ PHASE 1: HIR CONSTRUCTION │
│ ┌─────────┐ │
│ │ Babel │──▶ lower ──▶ enterSSA ──▶ eliminateRedundantPhi │
│ │ AST │ │ │
│ └─────────┘ ▼ │
│ ┌──────────┐ │
│ │ HIR │ (Control Flow Graph in SSA Form) │
│ └──────────┘ │
└─────────────────────────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────────────────────┐
│ PHASE 2: OPTIMIZATION │
│ │
│ constantPropagation ──▶ deadCodeElimination │
│ │
└─────────────────────────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────────────────────┐
│ PHASE 3: TYPE & EFFECT INFERENCE │
│ │
│ inferTypes ──▶ analyseFunctions ──▶ inferMutationAliasingEffects │
│ │ │
│ ▼ │
│ inferMutationAliasingRanges ──▶ inferReactivePlaces │
│ │
└─────────────────────────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────────────────────┐
│ PHASE 4: REACTIVE SCOPE CONSTRUCTION │
│ │
│ inferReactiveScopeVariables ──▶ alignMethodCallScopes ──▶ alignObjectMethodScopes │
│ │ │
│ ▼ │
│ alignReactiveScopesToBlockScopesHIR ──▶ mergeOverlappingReactiveScopesHIR │
│ │ │
│ ▼ │
│ buildReactiveScopeTerminalsHIR ──▶ flattenReactiveLoopsHIR │
│ │ │
│ ▼ │
│ flattenScopesWithHooksOrUseHIR ──▶ propagateScopeDependenciesHIR │
│ │
└─────────────────────────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────────────────────┐
│ PHASE 5: HIR → REACTIVE FUNCTION │
│ │
│ buildReactiveFunction │
│ │ │
│ ▼ │
│ ┌───────────────────┐ │
│ │ ReactiveFunction │ (Tree Structure) │
│ └───────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────────────────────┐
│ PHASE 6: REACTIVE FUNCTION OPTIMIZATION │
│ │
│ pruneUnusedLabels ──▶ pruneNonEscapingScopes ──▶ pruneNonReactiveDependencies │
│ │ │
│ ▼ │
│ pruneUnusedScopes ──▶ mergeReactiveScopesThatInvalidateTogether │
│ │ │
│ ▼ │
│ pruneAlwaysInvalidatingScopes ──▶ propagateEarlyReturns ──▶ promoteUsedTemporaries │
│ │
└─────────────────────────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────────────────────┐
│ PHASE 7: CODE GENERATION │
│ │
│ renameVariables ──▶ codegenReactiveFunction │
│ │ │
│ ▼ │
│ ┌─────────────┐ │
│ │ Babel AST │ (With Memoization) │
│ └─────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────────────────┘
Pass Categories
HIR Construction & SSA (1-3)
| # | Pass | File | Description |
|---|---|---|---|
| 1 | lower | HIR/BuildHIR.ts |
Convert Babel AST to HIR control-flow graph |
| 2 | enterSSA | SSA/EnterSSA.ts |
Convert to Static Single Assignment form |
| 3 | eliminateRedundantPhi | SSA/EliminateRedundantPhi.ts |
Remove unnecessary phi nodes |
Optimization (4-5)
| # | Pass | File | Description |
|---|---|---|---|
| 4 | constantPropagation | Optimization/ConstantPropagation.ts |
Sparse conditional constant propagation |
| 5 | deadCodeElimination | Optimization/DeadCodeElimination.ts |
Remove unreferenced instructions |
Type Inference (6)
| # | Pass | File | Description |
|---|---|---|---|
| 6 | inferTypes | TypeInference/InferTypes.ts |
Constraint-based type unification |
Mutation/Aliasing Inference (7-10)
| # | Pass | File | Description |
|---|---|---|---|
| 7 | analyseFunctions | Inference/AnalyseFunctions.ts |
Analyze nested function effects |
| 8 | inferMutationAliasingEffects | Inference/InferMutationAliasingEffects.ts |
Infer mutation/aliasing via abstract interpretation |
| 9 | inferMutationAliasingRanges | Inference/InferMutationAliasingRanges.ts |
Compute mutable ranges from effects |
| 10 | inferReactivePlaces | Inference/InferReactivePlaces.ts |
Mark reactive places (props, hooks, derived) |
Reactive Scope Variables (11-12)
| # | Pass | File | Description |
|---|---|---|---|
| 11 | inferReactiveScopeVariables | ReactiveScopes/InferReactiveScopeVariables.ts |
Group co-mutating variables into scopes |
| 12 | rewriteInstructionKindsBasedOnReassignment | SSA/RewriteInstructionKindsBasedOnReassignment.ts |
Convert SSA loads to context loads for reassigned vars |
Scope Alignment (13-15)
| # | Pass | File | Description |
|---|---|---|---|
| 13 | alignMethodCallScopes | ReactiveScopes/AlignMethodCallScopes.ts |
Align method call scopes with receivers |
| 14 | alignObjectMethodScopes | ReactiveScopes/AlignObjectMethodScopes.ts |
Align object method scopes |
| 15 | alignReactiveScopesToBlockScopesHIR | ReactiveScopes/AlignReactiveScopesToBlockScopesHIR.ts |
Align to control-flow block boundaries |
Scope Construction (16-18)
| # | Pass | File | Description |
|---|---|---|---|
| 16 | mergeOverlappingReactiveScopesHIR | HIR/MergeOverlappingReactiveScopesHIR.ts |
Merge overlapping scopes |
| 17 | buildReactiveScopeTerminalsHIR | HIR/BuildReactiveScopeTerminalsHIR.ts |
Insert scope terminals into CFG |
| 18 | flattenReactiveLoopsHIR | ReactiveScopes/FlattenReactiveLoopsHIR.ts |
Prune scopes inside loops |
Scope Flattening & Dependencies (19-20)
| # | Pass | File | Description |
|---|---|---|---|
| 19 | flattenScopesWithHooksOrUseHIR | ReactiveScopes/FlattenScopesWithHooksOrUseHIR.ts |
Prune scopes containing hooks |
| 20 | propagateScopeDependenciesHIR | HIR/PropagateScopeDependenciesHIR.ts |
Derive minimal scope dependencies |
HIR → Reactive Conversion (21)
| # | Pass | File | Description |
|---|---|---|---|
| 21 | buildReactiveFunction | ReactiveScopes/BuildReactiveFunction.ts |
Convert CFG to tree structure |
Reactive Function Pruning (22-25)
| # | Pass | File | Description |
|---|---|---|---|
| 22 | pruneUnusedLabels | ReactiveScopes/PruneUnusedLabels.ts |
Remove unused labels |
| 23 | pruneNonEscapingScopes | ReactiveScopes/PruneNonEscapingScopes.ts |
Remove non-escaping scopes |
| 24 | pruneNonReactiveDependencies | ReactiveScopes/PruneNonReactiveDependencies.ts |
Remove non-reactive dependencies |
| 25 | pruneUnusedScopes | ReactiveScopes/PruneUnusedScopes.ts |
Remove empty scopes |
Scope Optimization (26-28)
| # | Pass | File | Description |
|---|---|---|---|
| 26 | mergeReactiveScopesThatInvalidateTogether | ReactiveScopes/MergeReactiveScopesThatInvalidateTogether.ts |
Merge co-invalidating scopes |
| 27 | pruneAlwaysInvalidatingScopes | ReactiveScopes/PruneAlwaysInvalidatingScopes.ts |
Prune always-invalidating scopes |
| 28 | propagateEarlyReturns | ReactiveScopes/PropagateEarlyReturns.ts |
Handle early returns in scopes |
Codegen Preparation (29-31)
| # | Pass | File | Description |
|---|---|---|---|
| 29 | promoteUsedTemporaries | ReactiveScopes/PromoteUsedTemporaries.ts |
Promote temps to named vars |
| 30 | renameVariables | ReactiveScopes/RenameVariables.ts |
Ensure unique variable names |
| 31 | codegenReactiveFunction | ReactiveScopes/CodegenReactiveFunction.ts |
Generate final Babel AST |
Transformations (32-38)
| # | Pass | File | Description |
|---|---|---|---|
| 34 | optimizePropsMethodCalls | Optimization/OptimizePropsMethodCalls.ts |
Normalize props method calls |
| 35 | optimizeForSSR | Optimization/OptimizeForSSR.ts |
SSR-specific optimizations |
| 36 | outlineJSX | Optimization/OutlineJsx.ts |
Outline JSX to components |
| 37 | outlineFunctions | Optimization/OutlineFunctions.ts |
Outline pure functions |
| 38 | memoizeFbtAndMacroOperandsInSameScope | ReactiveScopes/MemoizeFbtAndMacroOperandsInSameScope.ts |
Keep FBT operands together |
Validation (39-55)
| # | Pass | File | Description |
|---|---|---|---|
| 39 | validateContextVariableLValues | Validation/ValidateContextVariableLValues.ts |
Variable reference consistency |
| 40 | validateUseMemo | Validation/ValidateUseMemo.ts |
useMemo callback requirements |
| 41 | validateHooksUsage | Validation/ValidateHooksUsage.ts |
Rules of Hooks |
| 42 | validateNoCapitalizedCalls | Validation/ValidateNoCapitalizedCalls.ts |
Component vs function calls |
| 43 | validateLocalsNotReassignedAfterRender | Validation/ValidateLocalsNotReassignedAfterRender.ts |
Variable mutation safety |
| 44 | validateNoSetStateInRender | Validation/ValidateNoSetStateInRender.ts |
No setState during render |
| 45 | validateNoDerivedComputationsInEffects | Validation/ValidateNoDerivedComputationsInEffects.ts |
Effect optimization hints |
| 46 | validateNoSetStateInEffects | Validation/ValidateNoSetStateInEffects.ts |
Effect performance |
| 47 | validateNoJSXInTryStatement | Validation/ValidateNoJSXInTryStatement.ts |
Error boundary usage |
| 48 | validateNoImpureValuesInRender | Validation/ValidateNoImpureValuesInRender.ts |
Impure value isolation |
| 49 | validateNoRefAccessInRender | Validation/ValidateNoRefAccessInRender.ts |
Ref access constraints |
| 50 | validateNoFreezingKnownMutableFunctions | Validation/ValidateNoFreezingKnownMutableFunctions.ts |
Mutable function isolation |
| 51 | validateExhaustiveDependencies | Validation/ValidateExhaustiveDependencies.ts |
Dependency array completeness |
| 53 | validatePreservedManualMemoization | Validation/ValidatePreservedManualMemoization.ts |
Manual memo preservation |
| 54 | validateStaticComponents | Validation/ValidateStaticComponents.ts |
Component identity stability |
| 55 | validateSourceLocations | Validation/ValidateSourceLocations.ts |
Source location preservation |
Key Data Structures
HIR (High-level Intermediate Representation)
The compiler converts source code to HIR for analysis. Key types:
-
HIRFunction: A function being compiled
body.blocks: Map of BasicBlocks (control flow graph)context: Captured variables from outer scopeparams: Function parametersreturns: The function's return place
-
BasicBlock: A sequence of instructions with a terminal
instructions: Array of Instructionsterminal: Control flow (return, branch, etc.)phis: Phi nodes for SSA
-
Instruction: A single operation
lvalue: The place being assigned tovalue: The instruction kind (CallExpression, FunctionExpression, etc.)effects: Array of AliasingEffects
-
Place: A reference to a value
identifier.id: Unique IdentifierIdeffect: How the place is used (read, mutate, etc.)
ReactiveFunction
After HIR is analyzed, it's converted to ReactiveFunction:
- Tree structure instead of CFG
- Contains ReactiveScopes that define memoization boundaries
- Each scope has dependencies and declarations
AliasingEffects
Effects describe data flow and operations:
- Capture/Alias: Value relationships
- Mutate/MutateTransitive: Mutation tracking
- Freeze: Immutability marking
- Render: JSX usage context
- Create/CreateFunction: Value creation
Feature Flags
Many passes are controlled by feature flags in Environment.ts:
| Flag | Enables Pass |
|---|---|
enableJsxOutlining |
outlineJSX |
enableFunctionOutlining |
outlineFunctions |
validateNoSetStateInRender |
validateNoSetStateInRender |
enableUseMemoCacheInterop |
Preserves manual memoization |
Running Tests
# Run all tests
yarn snap
# Run specific fixture
yarn snap -p <fixture-name>
# Run with debug output (shows all passes)
yarn snap -p <fixture-name> -d
# Compile any file (not just fixtures) and see output
yarn snap compile <path>
# Compile any file with debug output (alternative to yarn snap -d -p when you don't have a fixture)
yarn snap compile --debug <path>
# Minimize a failing test case to its minimal reproduction
yarn snap minimize <path>
# Update expected outputs
yarn snap -u
Fault Tolerance
The pipeline is fault-tolerant: all passes run to completion, accumulating errors on Environment rather than aborting on the first error.
- Validation passes are wrapped in
env.tryRecord()in Pipeline.ts, which catches non-invariantCompilerErrors and records them. If a validation pass throws, compilation continues. - Infrastructure/transformation passes (enterSSA, eliminateRedundantPhi, inferMutationAliasingEffects, codegen, etc.) are NOT wrapped in
tryRecord()because subsequent passes depend on their output being structurally valid. If they fail, compilation aborts. lower()(BuildHIR) always produces anHIRFunction, recording errors onenvinstead of returningErr. Unsupported constructs (e.g.,var) are lowered best-effort.- At the end of the pipeline,
env.hasErrors()determines whether to returnOk(codegen)orErr(aggregatedErrors).
Further Reading
- MUTABILITY_ALIASING_MODEL.md: Detailed aliasing model docs
- Pipeline.ts: Pass ordering and orchestration
- HIR.ts: Core data structure definitions