Skip to content

[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

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open

Conversation

mofeiZ
Copy link
Contributor

@mofeiZ mofeiZ commented Apr 21, 2025

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

Copy link

@Copilot Copilot AI left a 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) {

Comment on lines 31 to 32
arr.current.val = 2;
return arr;
Copy link
Preview

Copilot AI Apr 22, 2025

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.

Suggested change
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.

Copy link
Contributor

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
Copy link
Contributor

@jbrown215 jbrown215 left a 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

Comment on lines 31 to 32
arr.current.val = 2;
return arr;
Copy link
Contributor

Choose a reason for hiding this comment

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

yea this is correct!

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.

3 participants