Skip to content

Conversation

@mofeiZ
Copy link
Contributor

@mofeiZ mofeiZ commented Mar 13, 2025

This change fixes a coverage hole in rolling out with gating. Prior to this PR, configuring gating causes React Compiler to bail out of optimizing some functions.

This means that it's not entirely safe to cutover from gating enabled for all users (i.e. rolled out 100%) to removing the gating config altogether, as new functions may be opted into compilation when they stop bailing out due to gating-specific logic.

This is technically slightly slower due to the additional function indirection. An alternative approach is to recommend running a codemod to insert use no memos on currently-bailing out functions before removing thegating config.


Tested internally by enabling on a page that previously had a few hundred bailouts due to gating + hoisted function declarations and (1) clicking around locally and (2) running a bunch of e2e tests

CompilerError.throwTodo({
reason: `Encountered a function used before its declaration, which breaks Forget's gating codegen due to hoisting`,
description: `Rewrite the reference to ${fnPath.node.id?.name ?? 'this function'} to not rely on hoisting to fix this issue`,
if (referencedBeforeDeclaration && fnPath.isFunctionDeclaration()) {
Copy link
Contributor Author

@mofeiZ mofeiZ Mar 13, 2025

Choose a reason for hiding this comment

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

Note that this changes us to only bail out for function declarations which are referenced before declaration.
See invalid-fnexpr-reference and reassigned-fnexpr-variable fixtures for examples why we don't need special handling for other function kinds.

This should be correct as other referenced-before-declaration identifiers are handled by directly replacing ast nodes. This may error at runtime, but still preserves source semantics (e.g. compiler-optimized code errors if and only if source code errors)

@@ -0,0 +1,62 @@

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This fixture no longer bails out (component syntax refs produce a hoisted React.forwardRef)

@@ -0,0 +1,61 @@

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This fixture also no longer bails out (renamed from error.gating-hoisting)

@mofeiZ mofeiZ requested a review from poteto March 13, 2025 21:07
Copy link
Member

@poteto poteto left a comment

Choose a reason for hiding this comment

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

nice find!

mofeiZ added a commit that referenced this pull request Mar 13, 2025
…2597)

Some code movement for the next PR
---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/facebook/react/pull/32597).
* #32598
* __->__ #32597
This change fixes a coverage hole in rolling out with `gating`. Prior to this PR, configuring `gating` causes React Compiler to bail out of optimizing some functions.

This means that it's not entirely safe to cutover from `gating` enabled for all users (i.e. rolled out 100%) to removing the `gating` config altogether, as new functions may be opted into compilation when they stop bailing out due to gating-specific logic.

This is technically slightly slower due to the additional function indirection. An alternative approach is to recommend running a codemod to insert `use no memo`s on currently-bailing out functions before removing the`gating` config.

---
Tested [internally](
https://fburl.com/diff/q982ovua) by enabling on a page that previously had a few hundred bailouts due to gating + hoisted function declarations and (1) clicking around locally and (2) running a bunch of e2e tests
@mofeiZ mofeiZ merged commit d92e571 into main Mar 13, 2025
23 checks passed
github-actions bot pushed a commit that referenced this pull request Mar 13, 2025
This change fixes a coverage hole in rolling out with `gating`. Prior to
this PR, configuring `gating` causes React Compiler to bail out of
optimizing some functions.

This means that it's not entirely safe to cutover from `gating` enabled
for all users (i.e. rolled out 100%) to removing the `gating` config
altogether, as new functions may be opted into compilation when they
stop bailing out due to gating-specific logic.

This is technically slightly slower due to the additional function
indirection. An alternative approach is to recommend running a codemod
to insert `use no memo`s on currently-bailing out functions before
removing the`gating` config.

---
Tested [internally](
https://fburl.com/diff/q982ovua) by enabling on a page that previously
had a few hundred bailouts due to gating + hoisted function declarations
and (1) clicking around locally and (2) running a bunch of e2e tests

DiffTrain build for [d92e571](d92e571)
@poteto poteto deleted the pr32598 branch March 26, 2025 22:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed React Core Team Opened by a member of the React Core Team

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants