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

Code before:
            loc: value.loc,
          });
          if (scopeInfo.pruned || !scopeInfo.hasSingleInstr) {
            /**
             * TODO: retry pipeline that ensures effect function expressions
             * are placed into their own scope
             */
            CompilerError.throwTodo({
              reason:
                '[InferEffectDependencies] Expected effect function to have non-pruned scope and its scope to have exactly one instruction',
              loc: fnExpr.loc,
            });
          }

          /**
           * Step 1: push dependencies to the effect deps array
           *
           * Note that it's invalid to prune all non-reactive deps in this pass, see
           * the `infer-effect-deps/pruned-nonreactive-obj` fixture for an
           * explanation.
           */
          for (const dep of scopeInfo.deps) {
            // If it is reactive OR it is not reactive and neither a ref or setState call, then we need to add it to the deps array
            if (
              reactiveIds.has(dep.identifier.id) ||
              (!isUseRefType(dep.identifier) && !isSetStateType(dep.identifier))
            ) {
              const {place, instructions} = writeDependencyToInstructions(
                dep,
                reactiveIds.has(dep.identifier.id),
                fn.env,
                fnExpr.loc,
              );
              newInstructions.push(...instructions);
              effectDeps.push(place);
            }
          }

          newInstructions.push({
            id: makeInstructionId(0),
            loc: GeneratedSource,
            lvalue: {...depsPlace, effect: Effect.Mutate},
            value: deps,
          });

          // Step 2: push the inferred deps array as an argument of the useEffect
          value.args.push({...depsPlace, effect: Effect.Freeze});
          rewriteInstrs.set(instr.id, newInstructions);
        } else if (loadGlobals.has(value.args[0].identifier.id)) {
          // Global functions have no reactive dependencies, so we can insert an empty array
          newInstructions.push({

Review comment (suggestion):
Reactivity inference should already account for these types, why do we need to check them here? Note that you could still have a ref or state setter that is conditional on some other reactive value. 

Code after:
            CompilerError.invariant(scopeInfo != null, {
              reason: 'Expected function expression scope to exist',
              loc: value.loc,
            });
            if (scopeInfo.pruned || !scopeInfo.hasSingleInstr) {
              /**
               * TODO: retry pipeline that ensures effect function expressions
               * are placed into their own scope
               */
              CompilerError.throwTodo({
                reason:
                  '[InferEffectDependencies] Expected effect function to have non-pruned scope and its scope to have exactly one instruction',
                loc: fnExpr.loc,
              });
            }

            /**
             * Step 1: push dependencies to the effect deps array
             *
             * Note that it's invalid to prune all non-reactive deps in this pass, see
             * the `infer-effect-deps/pruned-nonreactive-obj` fixture for an
             * explanation.
             */
            for (const dep of scopeInfo.deps) {
              if (
                (isUseRefType(dep.identifier) ||
                  isSetStateType(dep.identifier)) &&
                !reactiveIds.has(dep.identifier.id)
              ) {
                // exclude non-reactive hook results, which will never be in a memo block
                continue;
              }

              const {place, instructions} = writeDependencyToInstructions(
                dep,
                reactiveIds.has(dep.identifier.id),
                fn.env,
                fnExpr.loc,
              );
              newInstructions.push(...instructions);
              effectDeps.push(place);
            }

            newInstructions.push({
              id: makeInstructionId(0),
              loc: GeneratedSource,
              lvalue: {...depsPlace, effect: Effect.Mutate},
              value: deps,
            });

            // Step 2: push the inferred deps array as an argument of the useEffect