@samitouri / QOS-React / commits / 5063b3283f

[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;