Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

compiler: Allow mutating refs in callbacks passed to JSX #29733

Merged
merged 4 commits into from
Jun 7, 2024

Conversation

josephsavona
Copy link
Contributor

@josephsavona josephsavona commented Jun 3, 2024

Stack from ghstack (oldest at bottom):

Fixes false positives where we currently disallow mutations of refs from callbacks passed to JSX, if the ref is also passed to jsx. We consider these to be mutations of "frozen" values, but refs are explicitly allowed to have interior mutability. The fix is to always allow (at leat within InferReferenceEffects) for refs to be mutated. This means we completely rely on ValidateNoRefAccessInRender to validate ref access and stop reporting false positives.

Copy link

vercel bot commented Jun 3, 2024

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
react-compiler-playground ✅ Ready (Inspect) Visit Preview 💬 Add feedback Jun 7, 2024 0:11am

josephsavona added a commit that referenced this pull request Jun 3, 2024
ghstack-source-id: c534d4943f1433f79afdad7ed2d926589cfdea31
Pull Request resolved: #29733
@facebook-github-bot facebook-github-bot added CLA Signed React Core Team Opened by a member of the React Core Team labels Jun 3, 2024
@josephsavona josephsavona marked this pull request as ready for review June 3, 2024 15:05
@react-sizebot
Copy link

react-sizebot commented Jun 3, 2024

Comparing: c4b433f...2cfa72f

Critical size changes

Includes critical production bundles, as well as any change greater than 2%:

Name +/- Base Current +/- gzip Base gzip Current gzip
oss-stable/react-dom/cjs/react-dom.production.js = 6.66 kB 6.66 kB = 1.82 kB 1.82 kB
oss-stable/react-dom/cjs/react-dom-client.production.js = 497.26 kB 497.26 kB = 89.11 kB 89.11 kB
oss-experimental/react-dom/cjs/react-dom.production.js = 6.67 kB 6.67 kB = 1.83 kB 1.83 kB
oss-experimental/react-dom/cjs/react-dom-client.production.js = 502.08 kB 502.08 kB = 89.80 kB 89.80 kB
facebook-www/ReactDOM-prod.classic.js = 594.56 kB 594.56 kB = 104.72 kB 104.72 kB
facebook-www/ReactDOM-prod.modern.js = 570.95 kB 570.95 kB = 101.13 kB 101.13 kB
test_utils/ReactAllWarnings.js Deleted 63.89 kB 0.00 kB Deleted 15.97 kB 0.00 kB

Significant size changes

Includes any change greater than 0.2%:

Expand to show
Name +/- Base Current +/- gzip Base gzip Current gzip
test_utils/ReactAllWarnings.js Deleted 63.89 kB 0.00 kB Deleted 15.97 kB 0.00 kB

Generated by 🚫 dangerJS against 2cfa72f

Fixes false positives where we currently disallow mutations of refs from callbacks passed to JSX, if the ref is also passed to jsx. We consider these to be mutations of "frozen" values, but refs are explicitly allowed to have interior mutability.

The fix is to add a new RefMutation variant to FunctionEffect, which we emit whenever a ref is mutated. We disallow this effect type from within a function body, but allow it within function expressions that are passed to useEffect and friends as well as to jsx.

[ghstack-poisoned]
josephsavona added a commit that referenced this pull request Jun 3, 2024
Fixes false positives where we currently disallow mutations of refs from callbacks passed to JSX, if the ref is also passed to jsx. We consider these to be mutations of "frozen" values, but refs are explicitly allowed to have interior mutability.

The fix is to add a new RefMutation variant to FunctionEffect, which we emit whenever a ref is mutated. We disallow this effect type from within a function body, but allow it within function expressions that are passed to useEffect and friends as well as to jsx.

ghstack-source-id: 057e505c16be50d16fc1dc12c1e5ed754ace87ed
Pull Request resolved: #29733
@josephsavona
Copy link
Contributor Author

Fixes #29741
Fixes #29703

Comment on lines 528 to 532
if (
isRefValueType(place.identifier) ||
isUseRefType(place.identifier)
) {
if (this.#env.config.validateRefAccessDuringRender) {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Previously refs would have fallen through to the case where the valueKind is mutable, and we would record it as a mutation. Now we always treat refs specially, and either ignore them (default) or record a RefMutation error when ref validation is on.

Ref validation still has a bunch of false positives that we have to fix before we can enable it more broadly. However, the fix here avoids the false negatives even when the validation is off.

Copy link
Member

@gsathya gsathya left a comment

Choose a reason for hiding this comment

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

awesome!

Fixes false positives where we currently disallow mutations of refs from callbacks passed to JSX, if the ref is also passed to jsx. We consider these to be mutations of "frozen" values, but refs are explicitly allowed to have interior mutability.

The fix is to add a new RefMutation variant to FunctionEffect, which we emit whenever a ref is mutated. We disallow this effect type from within a function body, but allow it within function expressions that are passed to useEffect and friends as well as to jsx.

Fixes #29741
Fixes #29703

[ghstack-poisoned]
josephsavona added a commit that referenced this pull request Jun 7, 2024
Fixes false positives where we currently disallow mutations of refs from callbacks passed to JSX, if the ref is also passed to jsx. We consider these to be mutations of "frozen" values, but refs are explicitly allowed to have interior mutability. The fix is to always allow (at leat within InferReferenceEffects) for refs to be mutated. This means we completely rely on ValidateNoRefAccessInRender to validate ref access and stop reporting false positives.

ghstack-source-id: 1a30609f5f7831086077d10dac46ab70687f47e0
Pull Request resolved: #29733
Fixes false positives where we currently disallow mutations of refs from callbacks passed to JSX, if the ref is also passed to jsx. We consider these to be mutations of "frozen" values, but refs are explicitly allowed to have interior mutability. The fix is to always allow (at leat within InferReferenceEffects) for refs to be mutated. This means we completely rely on ValidateNoRefAccessInRender to validate ref access and stop reporting false positives.

[ghstack-poisoned]
josephsavona added a commit that referenced this pull request Jun 7, 2024
Fixes false positives where we currently disallow mutations of refs from callbacks passed to JSX, if the ref is also passed to jsx. We consider these to be mutations of "frozen" values, but refs are explicitly allowed to have interior mutability. The fix is to always allow (at leat within InferReferenceEffects) for refs to be mutated. This means we completely rely on ValidateNoRefAccessInRender to validate ref access and stop reporting false positives.

ghstack-source-id: 1a30609f5f7831086077d10dac46ab70687f47e0
Pull Request resolved: #29733
@josephsavona josephsavona changed the title compiler: Add support for ref effects compiler: Allow mutating refs in callbacks passed to JSX Jun 7, 2024
@josephsavona
Copy link
Contributor Author

Heads up that i updated this to remove the RefMutation variant of FunctionEffect, we can keep this simple by just ignoring ref mutations completely in InferReferenceEffects.

@josephsavona josephsavona merged commit 2cfa72f into gh/josephsavona/20/base Jun 7, 2024
54 of 55 checks passed
josephsavona added a commit that referenced this pull request Jun 7, 2024
Fixes false positives where we currently disallow mutations of refs from callbacks passed to JSX, if the ref is also passed to jsx. We consider these to be mutations of "frozen" values, but refs are explicitly allowed to have interior mutability. The fix is to always allow (at leat within InferReferenceEffects) for refs to be mutated. This means we completely rely on ValidateNoRefAccessInRender to validate ref access and stop reporting false positives.

ghstack-source-id: 1a30609f5f7831086077d10dac46ab70687f47e0
Pull Request resolved: #29733
@josephsavona josephsavona deleted the gh/josephsavona/20/head branch June 7, 2024 00:19
github-actions bot pushed a commit that referenced this pull request Jun 7, 2024
Fixes false positives where we currently disallow mutations of refs from callbacks passed to JSX, if the ref is also passed to jsx. We consider these to be mutations of "frozen" values, but refs are explicitly allowed to have interior mutability. The fix is to always allow (at leat within InferReferenceEffects) for refs to be mutated. This means we completely rely on ValidateNoRefAccessInRender to validate ref access and stop reporting false positives.

ghstack-source-id: 1a30609f5f7831086077d10dac46ab70687f47e0
Pull Request resolved: #29733

DiffTrain build for commit 827cbea.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants