From 989a414a1a1509c64a08a503fcf135aa7b452e6a Mon Sep 17 00:00:00 2001 From: Lauren Tan Date: Wed, 8 Oct 2025 12:46:11 -0700 Subject: [PATCH] [compiler] Add VoidUseMemo rule to RecommendedLatest Adds a new error category VoidUseMemo which is only enabled in the RecommendedLatest preset for now. --- .../src/CompilerError.ts | 17 ++++++++++++++++- .../src/Inference/DropManualMemoization.ts | 2 +- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/compiler/packages/babel-plugin-react-compiler/src/CompilerError.ts b/compiler/packages/babel-plugin-react-compiler/src/CompilerError.ts index 0db911dbe56c8..1c077edd8d8a5 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/CompilerError.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/CompilerError.ts @@ -536,7 +536,8 @@ function printErrorSummary(category: ErrorCategory, message: string): string { case ErrorCategory.StaticComponents: case ErrorCategory.Suppression: case ErrorCategory.Syntax: - case ErrorCategory.UseMemo: { + case ErrorCategory.UseMemo: + case ErrorCategory.VoidUseMemo: { heading = 'Error'; break; } @@ -582,6 +583,10 @@ export enum ErrorCategory { * Checking for valid usage of manual memoization */ UseMemo = 'UseMemo', + /** + * Checking that useMemos always return a value + */ + VoidUseMemo = 'VoidUseMemo', /** * Checking for higher order functions acting as factories for components/hooks */ @@ -977,6 +982,16 @@ function getRuleForCategoryImpl(category: ErrorCategory): LintRule { preset: LintRulePreset.Recommended, }; } + case ErrorCategory.VoidUseMemo: { + return { + category, + severity: ErrorSeverity.Error, + name: 'void-use-memo', + description: + 'Validates that useMemos always return a value. See [`useMemo()` docs](https://react.dev/reference/react/useMemo) for more information.', + preset: LintRulePreset.RecommendedLatest, + }; + } case ErrorCategory.IncompatibleLibrary: { return { category, diff --git a/compiler/packages/babel-plugin-react-compiler/src/Inference/DropManualMemoization.ts b/compiler/packages/babel-plugin-react-compiler/src/Inference/DropManualMemoization.ts index 3eaeb5e4aa037..f86747618dd59 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/Inference/DropManualMemoization.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/Inference/DropManualMemoization.ts @@ -454,7 +454,7 @@ export function dropManualMemoization( if (!hasNonVoidReturn(funcToCheck.loweredFunc.func)) { errors.pushDiagnostic( CompilerDiagnostic.create({ - category: ErrorCategory.UseMemo, + category: ErrorCategory.VoidUseMemo, reason: 'useMemo() callbacks must return a value', description: `This ${ manualMemo.loadInstr.value.kind === 'PropertyLoad'