Repository: facebook/react
Pull request: [compiler] Remove now-unused FunctionEffect type


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.


Changed files:
filename: compiler/packages/babel-plugin-react-compiler/src/HIR/HIR.ts
patch: @@ -7,7 +7,7 @@
 
 import {BindingKind} from '@babel/traverse';
 import * as t from '@babel/types';
-import {CompilerError, CompilerErrorDetailOptions} from '../CompilerError';
+import {CompilerError} from '../CompilerError';
 import {assertExhaustive} from '../Utils/utils';
 import {Environment, ReactFunctionType} from './Environment';
 import type {HookKind} from './ObjectShape';
@@ -282,30 +282,13 @@ export type HIRFunction = {
   returnTypeAnnotation: t.FlowType | t.TSType | null;
   returns: Place;
   context: Array<Place>;
-  effects: Array<FunctionEffect> | null;
   body: HIR;
   generator: boolean;
   async: boolean;
   directives: Array<string>;
-  aliasingEffects?: Array<AliasingEffect> | null;
+  aliasingEffects: Array<AliasingEffect> | null;
 };
 
-export type FunctionEffect =
-  | {
-      kind: 'GlobalMutation';
-      error: CompilerErrorDetailOptions;
-    }
-  | {
-      kind: 'ReactMutation';
-      error: CompilerErrorDetailOptions;
-    }
-  | {
-      kind: 'ContextMutation';
-      places: ReadonlySet<Place>;
-      effect: Effect;
-      loc: SourceLocation;
-    };
-
 /*
  * Each reactive scope may have its own control-flow, so the instructions form
  * a control-flow graph. The graph comprises a set of basic blocks which reference

filename: compiler/packages/babel-plugin-react-compiler/src/HIR/PrintHIR.ts
patch: @@ -554,23 +554,11 @@ export function printInstructionValue(instrValue: ReactiveValue): string {
       const context = instrValue.loweredFunc.func.context
         .map(dep => printPlace(dep))
         .join(',');
-      const effects =
-        instrValue.loweredFunc.func.effects
-          ?.map(effect => {
-            if (effect.kind === 'ContextMutation') {
-              return `ContextMutation places=[${[...effect.places]
-                .map(place => printPlace(place))
-                .join(', ')}] effect=${effect.effect}`;
-            } else {
-              return `GlobalMutation`;
-            }
-          })
-          .join(', ') ?? '';
       const aliasingEffects =
         instrValue.loweredFunc.func.aliasingEffects
           ?.map(printAliasingEffect)
           ?.join(', ') ?? '';
-      value = `${kind} ${name} @context[${context}] @effects[${effects}] @aliasingEffects=[${aliasingEffects}]\n${fn}`;
+      value = `${kind} ${name} @context[${context}] @aliasingEffects=[${aliasingEffects}]\n${fn}`;
       break;
     }
     case 'TaggedTemplateExpression': {

filename: compiler/packages/babel-plugin-react-compiler/src/Optimization/LowerContextAccess.ts
patch: @@ -255,14 +255,14 @@ function emitSelectorFn(env: Environment, keys: Array<string>): Instruction {
     returnTypeAnnotation: null,
     returns: createTemporaryPlace(env, GeneratedSource),
     context: [],
-    effects: null,
     body: {
       entry: block.id,
       blocks: new Map([[block.id, block]]),
     },
     generator: false,
     async: false,
     directives: [],
+    aliasingEffects: [],
   };
 
   reversePostorderBlocks(fn.body);

filename: compiler/packages/babel-plugin-react-compiler/src/Optimization/OutlineJsx.ts
patch: @@ -370,14 +370,14 @@ function emitOutlinedFn(
     returnTypeAnnotation: null,
     returns: createTemporaryPlace(env, GeneratedSource),
     context: [],
-    effects: null,
     body: {
       entry: block.id,
       blocks: new Map([[block.id, block]]),
     },
     generator: false,
     async: false,
     directives: [],
+    aliasingEffects: [],
   };
   return fn;
 }

filename: compiler/packages/babel-plugin-react-compiler/src/Validation/ValidateNoFreezingKnownMutableFunctions.ts
patch: @@ -7,19 +7,17 @@
 
 import {CompilerDiagnostic, CompilerError, Effect, ErrorSeverity} from '..';
 import {
-  FunctionEffect,
   HIRFunction,
   IdentifierId,
-  isMutableEffect,
   isRefOrRefLikeMutableType,
   Place,
 } from '../HIR';
 import {
   eachInstructionValueOperand,
   eachTerminalOperand,
 } from '../HIR/visitors';
+import {AliasingEffect} from '../Inference/AliasingEffects';
 import {Result} from '../Utils/Result';
-import {Iterable_some} from '../Utils/utils';
 
 /**
  * Validates that functions with known mutations (ie due to types) cannot be passed
@@ -50,14 +48,14 @@ export function validateNoFreezingKnownMutableFunctions(
   const errors = new CompilerError();
   const contextMutationEffects: Map<
     IdentifierId,
-    Extract<FunctionEffect, {kind: 'ContextMutation'}>
+    Extract<AliasingEffect, {kind: 'Mutate'} | {kind: 'MutateTransitive'}>
   > = new Map();
 
   function visitOperand(operand: Place): void {
     if (operand.effect === Effect.Freeze) {
       const effect = contextMutationEffects.get(operand.identifier.id);
       if (effect != null) {
-        const place = [...effect.places][0];
+        const place = effect.value;
         const variable =
           place != null &&
           place.identifier.name != null &&
@@ -77,7 +75,7 @@ export function validateNoFreezingKnownMutableFunctions(
             })
             .withDetail({
               kind: 'error',
-              loc: effect.loc,
+              loc: effect.value.loc,
               message: `This modifies ${variable}`,
             }),
         );
@@ -108,24 +106,7 @@ export function validateNoFreezingKnownMutableFunctions(
           break;
         }
         case 'FunctionExpression': {
-          const knownMutation = (value.loweredFunc.func.effects ?? []).find(
-            effect => {
-              return (
-                effect.kind === 'ContextMutation' &&
-                (effect.effect === Effect.Store ||
-                  effect.effect === Effect.Mutate) &&
-                Iterable_some(effect.places, place => {
-                  return (
-                    isMutableEffect(place.effect, place.loc) &&
-                    !isRefOrRefLikeMutableType(place.identifier.type)
-                  );
-                })
-              );
-            },
-          );
-          if (knownMutation && knownMutation.kind === 'ContextMutation') {
-            contextMutationEffects.set(lvalue.identifier.id, knownMutation);
-          } else if (value.loweredFunc.func.aliasingEffects != null) {
+          if (value.loweredFunc.func.aliasingEffects != null) {
             const context = new Set(
               value.loweredFunc.func.context.map(p => p.identifier.id),
             );
@@ -146,12 +127,7 @@ export function validateNoFreezingKnownMutableFunctions(
                     context.has(effect.value.identifier.id) &&
                     !isRefOrRefLikeMutableType(effect.value.identifier.type)
                   ) {
-                    contextMutationEffects.set(lvalue.identifier.id, {
-                      kind: 'ContextMutation',
-                      effect: Effect.Mutate,
-                      loc: effect.value.loc,
-                      places: new Set([effect.value]),
-                    });
+                    contextMutationEffects.set(lvalue.identifier.id, effect);
                     break effects;
                   }
                   break;