Repository: facebook/react
File: compiler/packages/babel-plugin-react-compiler/src/Inference/InferReferenceEffects.ts (TypeScript)

Code before:
      case "RegExpLiteral": {
        // RegExp instances are mutable objects
        valueKind = {
          kind: ValueKind.Mutable,
          reason: new Set([ValueReason.Other]),
          context: new Set(),
        };
        effect = {
          kind: Effect.ConditionallyMutate,
          reason: ValueReason.Other,
        };
        break;
      }
      case "MetaProperty":
      case "LoadGlobal":
        valueKind = {
          kind: ValueKind.Global,
          reason: new Set([ValueReason.Global]),
          context: new Set(),
        };
        break;
      case "Debugger":
      case "JSXText":
      case "Primitive": {
        valueKind = {
          kind: ValueKind.Primitive,
          reason: new Set([ValueReason.Other]),
          context: new Set(),
        };
        break;
      }
      case "ObjectMethod":
      case "FunctionExpression": {
        let hasMutableOperand = false;
        for (const operand of eachInstructionOperand(instr)) {
          state.referenceAndRecordEffects(
            operand,
            operand.effect === Effect.Unknown ? Effect.Read : operand.effect,
            ValueReason.Other,
            []
          );
          hasMutableOperand ||= isMutableEffect(operand.effect, operand.loc);

          /**
           * If this function references other functions, propagate the referenced function's
           * effects to this function.
           *
           * ```
           * let f = () => global = true;
           * let g = () => f();
           * g();

Review comment (suggestion):
hmmm this isn't safe: the `new.target` meta-property may refer to a mutable object (constructor function), so we can't consider this value to be immutable. If we want to do this, we'll need to restrict support to just `import` meta properties which shouldn't be modified

Code after:
        /*
         * template literal (with no tag function) always produces
         * an immutable string
         */
        valueKind = {
          kind: ValueKind.Primitive,
          reason: new Set([ValueReason.Other]),
          context: new Set(),
        };
        effect = { kind: Effect.Read, reason: ValueReason.Other };
        break;
      }
      case "RegExpLiteral": {
        // RegExp instances are mutable objects
        valueKind = {
          kind: ValueKind.Mutable,
          reason: new Set([ValueReason.Other]),
          context: new Set(),
        };
        effect = {
          kind: Effect.ConditionallyMutate,
          reason: ValueReason.Other,
        };
        break;
      }
      case "MetaProperty": {
        if (instrValue.meta !== "import" || instrValue.property !== "meta") {
          continue;
        }

        valueKind = {
          kind: ValueKind.Global,
          reason: new Set([ValueReason.Global]),
          context: new Set(),
        };
        break;
      }
      case "LoadGlobal":
        valueKind = {
          kind: ValueKind.Global,
          reason: new Set([ValueReason.Global]),
          context: new Set(),
        };
        break;
      case "Debugger":
      case "JSXText":
      case "Primitive": {
        valueKind = {
          kind: ValueKind.Primitive,
          reason: new Set([ValueReason.Other]),
          context: new Set(),