-
Notifications
You must be signed in to change notification settings - Fork 48.3k
[compiler] Fallback for inferred effect dependencies #32984
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
base: main
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR implements a fallback mechanism for inferring effect dependencies when memoization-related bailouts occur and updates several test fixtures and utility functions accordingly. Key changes include:
- Introducing a fallback to infer minimal dependencies in effect callbacks.
- Updating test fixtures to include explicit dependency arrays for hooks.
- Exporting and refactoring internal dependency collection functions for broader use.
Reviewed Changes
Copilot reviewed 12 out of 12 changed files in this pull request and generated 1 comment.
Show a summary per file
File | Description |
---|---|
transform-fire/bailout-retry/infer-deps-on-retry.expect.md | Updates the effect hook call to include an additional dependency array and changes the parameter naming in the effect function. |
transform-fire/bailout-retry/error.todo-infer-deps-on-retry.expect.md | Removes the error fixture as part of the change. |
infer-effect-dependencies/bailout-retry/mutate-after-useeffect.js | Adds an explicit dependency array in the useEffect hook. |
infer-effect-dependencies/bailout-retry/mutate-after-useeffect.expect.md | Updates the useEffect hook usage to include dependencies. |
infer-effect-dependencies/bailout-retry/mutate-after-useeffect-ref-access.js expect.md | Updates the useEffect hook usage with dependency arrays but contains an incorrect variable reference. |
infer-effect-dependencies/bailout-retry/mutate-after-useeffect-granular-access.expect.md | Updates the dependency array in the useEffect hook for granular access. |
Inference/InferEffectDependencies.ts | Refactors dependency inference to use a fallback for minimal dependencies instead of invariant errors. |
HIR/PropagateScopeDependenciesHIR.ts | Exports and renames dependency collection functions for consistency. |
HIR/CollectHoistablePropertyLoads.ts | Adds a new function for collecting hoistable property loads in inner functions. |
Comments suppressed due to low confidence (1)
compiler/packages/babel-plugin-react-compiler/src/tests/fixtures/compiler/transform-fire/bailout-retry/infer-deps-on-retry.expect.md:37
- [nitpick] The parameter 't0' is ambiguous; consider renaming it to a more descriptive identifier (e.g., 'props' or '{cond}').
function useFoo(t0) {
arr.current.val = 2; | ||
return arr; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The code references 'arr.current' and returns 'arr', but the parameter destructuring provides 'arrRef'. Update these to refer to 'arrRef.current' and return 'arrRef' to match the intended variable.
arr.current.val = 2; | |
return arr; | |
arrRef.current.val = 2; | |
return arrRef; |
Copilot is powered by AI, so mistakes are possible. Review output carefully before use.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yea this is correct!
When effect dependencies cannot be inferred due to memoization-related bailouts or unexpected mutable ranges (which currently often have to do with writes to refs), fall back to traversing the effect lambda itself. This fallback uses the same logic as PropagateScopeDependencies: 1. Collect a sidemap of loads and property loads 2. Find hoistable accesses from the control flow graph. Note that here, we currently take into account the mutable ranges of instructions (see `mutate-after-useeffect-granular-access` fixture) 3. Collect the set of property paths accessed by the effect 4. Merge to get the set of minimal dependencies
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice, this makes sense! I'll have to take a look at propagate scope dependencies to confirm my understanding of how we decide to hoist
arr.current.val = 2; | ||
return arr; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yea this is correct!
When effect dependencies cannot be inferred due to memoization-related bailouts or unexpected mutable ranges (which currently often have to do with writes to refs), fall back to traversing the effect lambda itself.
This fallback uses the same logic as PropagateScopeDependencies:
mutate-after-useeffect-granular-access
fixture)