[compiler] Remove now-unused FunctionEffect type (#34029)
The new mutation/aliasing model significantly expands on the idea of FunctionEffect. The type (and its usage in HIRFunction.effects) was only necessary for the now-deleted old inference model so we can clean up this code now.
Joseph Savona committed
Aug 15, 2025 at 15:27 UTC
5063b3283fcae4bb43756d0d18d32008e3910bea
5 files changed
+11
-64
compiler/packages/babel-plugin-react-compiler/src/HIR/HIR.ts
+2
-19
@@ -7,7 +7,7 @@
7
8
import {BindingKind} from '@babel/traverse';
9
import * as t from '@babel/types';
10
-import {CompilerError, CompilerErrorDetailOptions} from '../CompilerError';
10
+import {CompilerError} from '../CompilerError';
11
import {assertExhaustive} from '../Utils/utils';
12
import {Environment, ReactFunctionType} from './Environment';
13
import type {HookKind} from './ObjectShape';
@@ -282,30 +282,13 @@ export type HIRFunction = {
282
returnTypeAnnotation: t.FlowType | t.TSType | null;
283
returns: Place;
284
context: Array<Place>;
285
- effects: Array<FunctionEffect> | null;
285
body: HIR;
286
generator: boolean;
287
async: boolean;
288
directives: Array<string>;
290
- aliasingEffects?: Array<AliasingEffect> | null;
289
+ aliasingEffects: Array<AliasingEffect> | null;
290
};
291
293
-export type FunctionEffect =
294
- | {
295
- kind: 'GlobalMutation';
296
- error: CompilerErrorDetailOptions;
297
- }
298
- | {
299
- kind: 'ReactMutation';
300
- error: CompilerErrorDetailOptions;
301
- }
302
- | {
303
- kind: 'ContextMutation';
304
- places: ReadonlySet<Place>;
305
- effect: Effect;
306
- loc: SourceLocation;
307
- };
308
-
292
/*
293
* Each reactive scope may have its own control-flow, so the instructions form
294
* a control-flow graph. The graph comprises a set of basic blocks which reference
compiler/packages/babel-plugin-react-compiler/src/HIR/PrintHIR.ts
+1
-13
@@ -554,23 +554,11 @@ export function printInstructionValue(instrValue: ReactiveValue): string {
554
const context = instrValue.loweredFunc.func.context
555
.map(dep => printPlace(dep))
556
.join(',');
557
- const effects =
558
- instrValue.loweredFunc.func.effects
559
- ?.map(effect => {
560
- if (effect.kind === 'ContextMutation') {
561
- return `ContextMutation places=[${[...effect.places]
562
- .map(place => printPlace(place))
563
- .join(', ')}] effect=${effect.effect}`;
564
- } else {
565
- return `GlobalMutation`;
566
- }
567
- })
568
- .join(', ') ?? '';
557
const aliasingEffects =
558
instrValue.loweredFunc.func.aliasingEffects
559
?.map(printAliasingEffect)
560
?.join(', ') ?? '';
573
- value = `${kind} ${name} @context[${context}] @effects[${effects}] @aliasingEffects=[${aliasingEffects}]\n${fn}`;
561
+ value = `${kind} ${name} @context[${context}] @aliasingEffects=[${aliasingEffects}]\n${fn}`;
562
break;
563
}
564
case 'TaggedTemplateExpression': {
compiler/packages/babel-plugin-react-compiler/src/Optimization/LowerContextAccess.ts
+1
-1
@@ -255,7 +255,6 @@ function emitSelectorFn(env: Environment, keys: Array<string>): Instruction {
255
returnTypeAnnotation: null,
256
returns: createTemporaryPlace(env, GeneratedSource),
257
context: [],
258
- effects: null,
258
body: {
259
entry: block.id,
260
blocks: new Map([[block.id, block]]),
@@ -263,6 +262,7 @@ function emitSelectorFn(env: Environment, keys: Array<string>): Instruction {
262
generator: false,
263
async: false,
264
directives: [],
265
+ aliasingEffects: [],
266
};
267
268
reversePostorderBlocks(fn.body);
compiler/packages/babel-plugin-react-compiler/src/Optimization/OutlineJsx.ts
+1
-1
@@ -370,7 +370,6 @@ function emitOutlinedFn(
370
returnTypeAnnotation: null,
371
returns: createTemporaryPlace(env, GeneratedSource),
372
context: [],
373
- effects: null,
373
body: {
374
entry: block.id,
375
blocks: new Map([[block.id, block]]),
@@ -378,6 +377,7 @@ function emitOutlinedFn(
377
generator: false,
378
async: false,
379
directives: [],
380
+ aliasingEffects: [],
381
};
382
return fn;
383
}
compiler/packages/babel-plugin-react-compiler/src/Validation/ValidateNoFreezingKnownMutableFunctions.ts
+6
-30
@@ -7,10 +7,8 @@
7
8
import {CompilerDiagnostic, CompilerError, Effect, ErrorSeverity} from '..';
9
import {
10
- FunctionEffect,
10
HIRFunction,
11
IdentifierId,
13
- isMutableEffect,
12
isRefOrRefLikeMutableType,
13
Place,
14
} from '../HIR';
@@ -18,8 +16,8 @@ import {
16
eachInstructionValueOperand,
17
eachTerminalOperand,
18
} from '../HIR/visitors';
19
+import {AliasingEffect} from '../Inference/AliasingEffects';
20
import {Result} from '../Utils/Result';
22
-import {Iterable_some} from '../Utils/utils';
21
22
/**
23
* Validates that functions with known mutations (ie due to types) cannot be passed
@@ -50,14 +48,14 @@ export function validateNoFreezingKnownMutableFunctions(
48
const errors = new CompilerError();
49
const contextMutationEffects: Map<
50
IdentifierId,
53
- Extract<FunctionEffect, {kind: 'ContextMutation'}>
51
+ Extract<AliasingEffect, {kind: 'Mutate'} | {kind: 'MutateTransitive'}>
52
> = new Map();
53
54
function visitOperand(operand: Place): void {
55
if (operand.effect === Effect.Freeze) {
56
const effect = contextMutationEffects.get(operand.identifier.id);
57
if (effect != null) {
60
- const place = [...effect.places][0];
58
+ const place = effect.value;
59
const variable =
60
place != null &&
61
place.identifier.name != null &&
@@ -77,7 +75,7 @@ export function validateNoFreezingKnownMutableFunctions(
75
})
76
.withDetail({
77
kind: 'error',
80
- loc: effect.loc,
78
+ loc: effect.value.loc,
79
message: `This modifies ${variable}`,
80
}),
81
);
@@ -108,24 +106,7 @@ export function validateNoFreezingKnownMutableFunctions(
106
break;
107
}
108
case 'FunctionExpression': {
111
- const knownMutation = (value.loweredFunc.func.effects ?? []).find(
112
- effect => {
113
- return (
114
- effect.kind === 'ContextMutation' &&
115
- (effect.effect === Effect.Store ||
116
- effect.effect === Effect.Mutate) &&
117
- Iterable_some(effect.places, place => {
118
- return (
119
- isMutableEffect(place.effect, place.loc) &&
120
- !isRefOrRefLikeMutableType(place.identifier.type)
121
- );
122
- })
123
- );
124
- },
125
- );
126
- if (knownMutation && knownMutation.kind === 'ContextMutation') {
127
- contextMutationEffects.set(lvalue.identifier.id, knownMutation);
128
- } else if (value.loweredFunc.func.aliasingEffects != null) {
109
+ if (value.loweredFunc.func.aliasingEffects != null) {
110
const context = new Set(
111
value.loweredFunc.func.context.map(p => p.identifier.id),
112
);
@@ -146,12 +127,7 @@ export function validateNoFreezingKnownMutableFunctions(
127
context.has(effect.value.identifier.id) &&
128
!isRefOrRefLikeMutableType(effect.value.identifier.type)
129
) {
149
- contextMutationEffects.set(lvalue.identifier.id, {
150
- kind: 'ContextMutation',
151
- effect: Effect.Mutate,
152
- loc: effect.value.loc,
153
- places: new Set([effect.value]),
154
- });
130
+ contextMutationEffects.set(lvalue.identifier.id, effect);
131
break effects;
132
}
133
break;