@samitouri / QOS-React-2 / commits / b8bedc267f

[compiler][autodeps/fire] Do not include fire functions in autodep arrays (#32532)

Summary: We landed on not including fire functions in dep arrays. They aren't needed because all values returned from the useFire hook call will read from the same ref. The linter will error if you include a fired function in an explicit dep array. Test Plan: yarn snap --watch --

Jordan Brown committed Apr 17, 2025 at 13:03 UTC b8bedc267f79db375f3147db4d766e09de599b68
6 files changed +31 -5
compiler/packages/babel-plugin-react-compiler/src/HIR/Globals.ts
+7 -1
@@ -9,6 +9,7 @@ import {Effect, ValueKind, ValueReason} from './HIR';
9 import {
10 BUILTIN_SHAPES,
11 BuiltInArrayId,
12 + BuiltInFireFunctionId,
13 BuiltInFireId,
14 BuiltInMapId,
15 BuiltInMixedReadonlyId,
@@ -674,7 +675,12 @@ const REACT_APIS: Array<[string, BuiltInType]> = [
675 {
676 positionalParams: [],
677 restParam: null,
677 - returnType: {kind: 'Primitive'},
678 + returnType: {
679 + kind: 'Function',
680 + return: {kind: 'Poly'},
681 + shapeId: BuiltInFireFunctionId,
682 + isConstructor: false,
683 + },
684 calleeEffect: Effect.Read,
685 returnValueKind: ValueKind.Frozen,
686 },
compiler/packages/babel-plugin-react-compiler/src/HIR/HIR.ts
+6
@@ -1722,6 +1722,12 @@ export function isDispatcherType(id: Identifier): boolean {
1722 return id.type.kind === 'Function' && id.type.shapeId === 'BuiltInDispatch';
1723 }
1724
1725 +export function isFireFunctionType(id: Identifier): boolean {
1726 + return (
1727 + id.type.kind === 'Function' && id.type.shapeId === 'BuiltInFireFunction'
1728 + );
1729 +}
1730 +
1731 export function isStableType(id: Identifier): boolean {
1732 return (
1733 isSetStateType(id) ||
compiler/packages/babel-plugin-react-compiler/src/HIR/ObjectShape.ts
+1
@@ -223,6 +223,7 @@ export const BuiltInUseContextHookId = 'BuiltInUseContextHook';
223 export const BuiltInUseTransitionId = 'BuiltInUseTransition';
224 export const BuiltInStartTransitionId = 'BuiltInStartTransition';
225 export const BuiltInFireId = 'BuiltInFire';
226 +export const BuiltInFireFunctionId = 'BuiltInFireFunction';
227
228 // ShapeRegistry with default definitions for built-ins.
229 export const BUILTIN_SHAPES: ShapeRegistry = new Map();
compiler/packages/babel-plugin-react-compiler/src/Inference/InferEffectDependencies.ts
+4 -2
@@ -17,6 +17,7 @@ import {
17 ReactiveScopeDependencies,
18 isUseRefType,
19 isSetStateType,
20 + isFireFunctionType,
21 } from '../HIR';
22 import {DEFAULT_EXPORT} from '../HIR/Environment';
23 import {
@@ -189,9 +190,10 @@ export function inferEffectDependencies(fn: HIRFunction): void {
190 */
191 for (const dep of scopeInfo.deps) {
192 if (
192 - (isUseRefType(dep.identifier) ||
193 + ((isUseRefType(dep.identifier) ||
194 isSetStateType(dep.identifier)) &&
194 - !reactiveIds.has(dep.identifier.id)
195 + !reactiveIds.has(dep.identifier.id)) ||
196 + isFireFunctionType(dep.identifier)
197 ) {
198 // exclude non-reactive hook results, which will never be in a memo block
199 continue;
compiler/packages/babel-plugin-react-compiler/src/Transform/TransformFire.ts
+12 -1
@@ -34,7 +34,11 @@ import {
34 } from '../HIR';
35 import {createTemporaryPlace, markInstructionIds} from '../HIR/HIRBuilder';
36 import {getOrInsertWith} from '../Utils/utils';
37 -import {BuiltInFireId, DefaultNonmutatingHook} from '../HIR/ObjectShape';
37 +import {
38 + BuiltInFireFunctionId,
39 + BuiltInFireId,
40 + DefaultNonmutatingHook,
41 +} from '../HIR/ObjectShape';
42 import {eachInstructionOperand} from '../HIR/visitors';
43 import {printSourceLocationLine} from '../HIR/PrintHIR';
44 import {USE_FIRE_FUNCTION_NAME} from '../HIR/Environment';
@@ -633,6 +637,13 @@ class Context {
637 () => createTemporaryPlace(this.#env, GeneratedSource),
638 );
639
640 + fireFunctionBinding.identifier.type = {
641 + kind: 'Function',
642 + shapeId: BuiltInFireFunctionId,
643 + return: {kind: 'Poly'},
644 + isConstructor: false,
645 + };
646 +
647 this.#capturedCalleeIdentifierIds.set(callee.identifier.id, {
648 fireFunctionBinding,
649 capturedCalleeIdentifier: callee.identifier,
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/transform-fire/fire-and-autodeps.expect.md
+1 -1
@@ -49,7 +49,7 @@ function Component(props) {
49 } else {
50 t2 = $[4];
51 }
52 - useEffect(t2, [t1, props]);
52 + useEffect(t2, [props]);
53 return null;
54 }
55