Repository: facebook/react
Pull request: [compiler] Adjustments to exhaustive deps messages, disable the lint rule


Similar to ValidateHookUsage, we implement this check in the compiler for safety but (for now) continue to rely on the existing rule for actually reporting errors to users.

---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed with [ReviewStack](https://reviewstack.dev/facebook/react/pull/35192).
* #35201
* #35202
* __->__ #35192

Changed files:
filename: compiler/packages/babel-plugin-react-compiler/src/CompilerError.ts
patch: @@ -1067,7 +1067,15 @@ function getRuleForCategoryImpl(category: ErrorCategory): LintRule {
         name: 'memo-dependencies',
         description:
           'Validates that useMemo() and useCallback() specify comprehensive dependencies without extraneous values. See [`useMemo()` docs](https://react.dev/reference/react/useMemo) for more information.',
-        preset: LintRulePreset.RecommendedLatest,
+        /**
+         * TODO: the "MemoDependencies" rule largely reimplements the "exhaustive-deps" non-compiler rule,
+         * allowing the compiler to ensure it does not regress change behavior due to different dependencies.
+         * We previously relied on the source having ESLint suppressions for any exhaustive-deps violations,
+         * but it's more reliable to verify it within the compiler.
+         *
+         * Long-term we should de-duplicate these implementations.
+         */
+        preset: LintRulePreset.Off,
       };
     }
     case ErrorCategory.IncompatibleLibrary: {

filename: compiler/packages/babel-plugin-react-compiler/src/Entrypoint/Pipeline.ts
patch: @@ -303,9 +303,11 @@ function runWithEnvironment(
   inferReactivePlaces(hir);
   log({kind: 'hir', name: 'InferReactivePlaces', value: hir});
 
-  if (env.config.validateExhaustiveMemoizationDependencies) {
-    // NOTE: this relies on reactivity inference running first
-    validateExhaustiveDependencies(hir).unwrap();
+  if (env.enableValidations) {
+    if (env.config.validateExhaustiveMemoizationDependencies) {
+      // NOTE: this relies on reactivity inference running first
+      validateExhaustiveDependencies(hir).unwrap();
+    }
   }
 
   rewriteInstructionKindsBasedOnReassignment(hir);

filename: compiler/packages/babel-plugin-react-compiler/src/Validation/ValidateExhaustiveDependencies.ts
patch: @@ -284,7 +284,7 @@ export function validateExhaustiveDependencies(
       if (missing.length !== 0) {
         const diagnostic = CompilerDiagnostic.create({
           category: ErrorCategory.MemoDependencies,
-          reason: 'Found non-exhaustive dependencies',
+          reason: 'Found missing memoization dependencies',
           description:
             'Missing dependencies can cause a value not to update when those inputs change, ' +
             'resulting in stale UI',
@@ -309,7 +309,7 @@ export function validateExhaustiveDependencies(
           reason: 'Found unnecessary memoization dependencies',
           description:
             'Unnecessary dependencies can cause a value to update more often than necessary, ' +
-            'which can cause effects to run more than expected',
+            'causing performance regressions and effects to fire more often than expected',
         });
         diagnostic.withDetails({
           kind: 'error',

filename: compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.invalid-exhaustive-deps.expect.md
patch: @@ -53,7 +53,7 @@ function Component({x, y, z}) {
 ```
 Found 4 errors:
 
-Error: Found non-exhaustive dependencies
+Error: Found missing memoization dependencies
 
 Missing dependencies can cause a value not to update when those inputs change, resulting in stale UI.
 
@@ -66,7 +66,7 @@ error.invalid-exhaustive-deps.ts:7:11
    9 |   }, [x?.y.z?.a.b]);
   10 |   const b = useMemo(() => {
 
-Error: Found non-exhaustive dependencies
+Error: Found missing memoization dependencies
 
 Missing dependencies can cause a value not to update when those inputs change, resulting in stale UI.
 
@@ -81,7 +81,7 @@ error.invalid-exhaustive-deps.ts:15:11
 
 Error: Found unnecessary memoization dependencies
 
-Unnecessary dependencies can cause a value to update more often than necessary, which can cause effects to run more than expected.
+Unnecessary dependencies can cause a value to update more often than necessary, causing performance regressions and effects to fire more often than expected.
 
 error.invalid-exhaustive-deps.ts:31:5
   29 |     return [];
@@ -92,7 +92,7 @@ error.invalid-exhaustive-deps.ts:31:5
   33 |   const ref2 = useRef(null);
   34 |   const ref = z ? ref1 : ref2;
 
-Error: Found non-exhaustive dependencies
+Error: Found missing memoization dependencies
 
 Missing dependencies can cause a value not to update when those inputs change, resulting in stale UI.