-
Notifications
You must be signed in to change notification settings - Fork 47.2k
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][hir-rewrite] Check mutability of base identifier when hoisting #31032
Conversation
[ghstack-poisoned]
The latest updates on your projects. Learn more about Vercel for Git ↗︎
|
[ghstack-poisoned]
Followup from #30894 , not sure how these got missed. Note that this PR just copies the fixtures without adding `@enablePropagateDepsInHIR`. #31032 follows and actually enables the HIR-version of propagateScopeDeps to run. I split this out into two PRs to make snapshot differences easier to review, but also happy to merge Fixtures found from locally setting snap test runner to default to `enablePropagateDepsInHIR: 'enabled_baseline'` and forking fixtures files with different output. ghstack-source-id: 7d7cf41aa923d83ad49f89079171b0411923ce6b Pull Request resolved: #31030
[ghstack-poisoned]
[ghstack-poisoned]
/** | ||
* Not safe to hoist read of maybeNullObject.value.inner outside of the | ||
* try-catch block, as that might throw | ||
*/ | ||
function useFoo(maybeNullObject: {value: {inner: number}} | null) { | ||
const y = []; | ||
try { | ||
y.push(identity(maybeNullObject.value.inner)); | ||
} catch { | ||
y.push('null'); | ||
} | ||
|
||
return y; | ||
} |
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.
Bug repro is unrelated to this fix
let x; | ||
if ($[0] !== props) { | ||
if ($[0] !== props.y || $[1] !== props.e) { |
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.
Note that we're now inferring props
as non-mutable. Previously, props.y
was not marked hoistable because the evaluation of LoadLocal props
had a mutable range (due to the try-catch).
[ghstack-poisoned]
[ghstack-poisoned]
[ghstack-poisoned]
…n decls (#31066) Stack from [ghstack](https://github.com/ezyang/ghstack) (oldest at bottom): * __->__ #31066 * #31032 Prior to this PR, we consider all of a nested function's accessed paths as 'hoistable' (to the basic block in which the function was defined). Now, we traverse nested functions and find all paths hoistable to their *entry block*. Note that this only replaces the *hoisting* part of function declarations, not dependencies. This realistically only affects optional chains within functions, which always get truncated to its inner non-optional path (see [todo-infer-function-uncond-optionals-hoisted.tsx](https://github.com/facebook/react/blob/576f3c0aa898cb99da1b7bf15317756e25c13708/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/propagate-scope-deps-hir-fork/reduce-reactive-deps/todo-infer-function-uncond-optionals-hoisted.tsx)) See newly added test fixtures for details Update: Note that toggling `enableTreatFunctionDepsAsConditional` makes a non-trivial impact on granularity of inferred deps (i.e. we find that function declarations uniquely identify some paths as hoistable). Snapshot comparison of internal code shows ~2.5% of files get worse dependencies ([internal link](https://www.internalfb.com/phabricator/paste/view/P1625792186))
Stack from ghstack (oldest at bottom):
Prior to this PR, we check whether the property load source (e.g. the evaluation of
<base>
in<base>.property
) is mutable + scoped to determine whether the property load itself is eligible for hoisting. This changes to check the base identifier of the load.