Skip to content

Fix preserve-manual-memoization false positive with optional chaining deps#577

Open
everettbu wants to merge 2 commits into
mainfrom
fix-35577
Open

Fix preserve-manual-memoization false positive with optional chaining deps#577
everettbu wants to merge 2 commits into
mainfrom
fix-35577

Conversation

@everettbu

Copy link
Copy Markdown

Mirror of facebook/react#35859
Original author: sleitor


Summary

When a dependency array uses optional chaining (e.g. [obj?.id]), the compiler may infer a less specific dependency (e.g. obj) because optional chain lowering introduces conditionals. Previously this triggered a Subpath error ("Inferred less specific property than source"), but the user's more specific optional dependency is semantically correct — using ?. acknowledges the conditionality and produces undefined when the base is nullish.

This change treats the inferred-less-specific case as OK when the source dependency continues with an optional property access from where the inferred dependency ends. Non-optional source deps that are more specific than inferred deps still correctly produce the Subpath error.

Test

Added useCallback-optional-chaining-dep test fixture that reproduces the exact pattern from #35577. All 1712 existing tests pass.

Fixes #35577
Fixes #35167

… deps

When a dependency array uses optional chaining (e.g. [obj?.id]), the compiler
may infer a less specific dependency (e.g. obj) because optional chain lowering
introduces conditionals. Previously this triggered a Subpath error, but the
user's more specific optional dependency is semantically correct — using ?.
acknowledges the conditionality and produces undefined when the base is nullish.

This change treats the inferred-less-specific case as OK when the source
dependency continues with an optional property access from where the inferred
dependency ends.

Fixes #35577
Fixes #35167
@greptile-apps

greptile-apps Bot commented Feb 21, 2026

Copy link
Copy Markdown

Greptile Summary

Fixes a false positive in the React Compiler's ValidatePreservedManualMemoization pass where using optional chaining in a dependency array (e.g., [obj?.id]) would incorrectly trigger a "Subpath" error ("Inferred less specific property than source"). The compiler infers obj instead of obj?.id because optional chain lowering introduces conditionals, but the user's more specific optional dependency is semantically correct.

  • Adds a new branch in compareDeps() that returns Ok when the inferred dependency is a prefix of the source and the source continues with an optional property access (?.), while preserving existing error behavior for non-optional subpath mismatches and ref-type accesses
  • Adds a test fixture (useCallback-optional-chaining-dep) reproducing the exact pattern from #35577

Confidence Score: 5/5

  • This PR is safe to merge — it's a narrowly scoped fix with correct logic and a test fixture.
  • The change is minimal (17 lines of logic + comments), well-guarded by existing conditions, and only relaxes validation for a specific case (optional chaining deps) that was already semantically correct. Existing error cases for non-optional subpath mismatches are preserved. A new test fixture covers the exact pattern being fixed, and the PR description confirms all 1712 existing tests pass.
  • No files require special attention.

Important Files Changed

Filename Overview
compiler/packages/babel-plugin-react-compiler/src/Validation/ValidatePreservedManualMemoization.ts Adds a new else if branch in compareDeps to return Ok when the inferred dependency is a prefix of the source and the source continues with an optional property access (?.). The logic is correct, properly guarded by ref-access checks, and preserves existing error behavior for non-optional subpath cases.
compiler/packages/babel-plugin-react-compiler/src/tests/fixtures/compiler/preserve-memo-validation/useCallback-optional-chaining-dep.ts New test fixture that reproduces the false positive from #35577: useCallback with [obj?.id] as a dependency where the body uses obj?.id in a conditional. Validates that the compiler no longer emits a spurious Subpath error.
compiler/packages/babel-plugin-react-compiler/src/tests/fixtures/compiler/preserve-memo-validation/useCallback-optional-chaining-dep.expect.md Expected output for the new test fixture — shows successful compilation (no errors) with correct memoization using obj as the cache key.

Last reviewed commit: 504e590

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

3 files reviewed, no comments

Edit Code Review Agent Settings | Greptile

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants