[compiler] Fix false positive refs-rule errors when forwarding props.ref#36293
Open
ousamabenyounes wants to merge 2 commits intofacebook:mainfrom
Open
[compiler] Fix false positive refs-rule errors when forwarding props.ref#36293ousamabenyounes wants to merge 2 commits intofacebook:mainfrom
ousamabenyounes wants to merge 2 commits intofacebook:mainfrom
Conversation
In ValidateNoRefAccessInRender, collectTemporariesSidemap unconditionally aliased every PropertyLoad lvalue to its object (except ref.current). Combined with Env.set's widening via the sidemap, this caused `env[props]` to be joined with the Ref classification of `props.ref`, making every subsequent `props.<sibling>` read appear to be a RefValue access and triggering false positive "Cannot access ref value during render" errors on unrelated props (fixes facebook#34775). Skip the alias when the loaded property is itself typed as a ref (UseRef or RefValue). The sidemap is still applied for generic property loads so the existing Structure/readRefEffect tracking (e.g. for `object.foo = () => ref.current; object.foo()`) continues to work. Adds a regression fixture reproducing the reported JSX snippet. Co-Authored-By: Claude <noreply@anthropic.com>
…34342) The fix in the previous commit also resolves facebook#34342: accessing both `props.ref` and a non-ref sibling property (e.g. `props.value`) no longer raises a false positive "Cannot access ref value during render" error on the sibling read. This fixture exercises the minimal repro from the issue. Co-Authored-By: Claude <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes #34775. Also fixes #34342 (same root cause, verified by the added regression fixture).
ValidateNoRefAccessInRender'scollectTemporariesSidemapaliased every PropertyLoad lvalue back to its object (exceptref.current). BecauseEnv.setwidens via the sidemap's canonical id, settingenv[$propsRef] = Ref(fromrefTypeOfTypeon theBuiltInUseRefId-typed lvalue) also widenedenv[props]toRef. Every subsequentprops.<sibling>load then inherited thatRefclassification and the JSX operand check flagged them with "Cannot access ref value during render".The fix: skip the sidemap alias when the loaded property is itself typed as a ref (
UseReforRefValue). Generic property loads still alias (so the existingStructure/readRefEffectpropagation used for patterns likeobject.foo = () => ref.current; object.foo()is preserved).Repro (#34775)
Before: 3 errors (
props.ref,props.placeholder,props.disabledall flagged).After: 0 errors.
Repro (#34342)
Before: 2 errors (both
props.refandprops.valueflagged).After: 0 errors.
props.ref.current(actual ref-value access during render) still correctly errors.How did you test this change?
yarn snap— 1721 passed / 1721 (1719 existing + 2 new regression fixtures:allow-forwarding-props-ref-does-not-taint-sibling-propsandallow-accessing-non-ref-prop-alongside-props-ref).yarn workspace babel-plugin-react-compiler lint— clean.yarn flow dom-node— clean.yarn linc/yarn prettier— clean.error.invalid-access-ref-in-render-mutate-object-with-ref-function,error.invalid-use-ref-added-to-dep-without-type-info,allow-assigning-ref-accessing-function-to-object-property-if-not-mutated) continue to pass unchanged — the sidemap is only skipped for ref-typed lvalues.Files changed
ValidateNoRefAccessInRender.tsallow-forwarding-props-ref-does-not-taint-sibling-props.{js,expect.md}allow-accessing-non-ref-prop-alongside-props-ref.{js,expect.md}🤖 Generated with Claude Code