Skip to content

[compiler] InferEffects uses effects as value keys#33650

Open
josephsavona wants to merge 1 commit into
mainfrom
pr33650
Open

[compiler] InferEffects uses effects as value keys#33650
josephsavona wants to merge 1 commit into
mainfrom
pr33650

Conversation

@josephsavona
Copy link
Copy Markdown
Member

@josephsavona josephsavona commented Jun 26, 2025

In InferReferenceEffects we used InstructionValue as the key to represent values, since each time we process an instruction this object will be the same. However this was always a bit of a hack, and in the new model and InferMutationAliasingEffects we can instead use the (creation) effect as the stable value. This avoids an extra layer of memoization since the effects are already interned anyway.


Stack created with Sapling. Best reviewed with ReviewStack.

@github-actions github-actions Bot added the React Core Team Opened by a member of the React Core Team label Jun 26, 2025
@josephsavona josephsavona force-pushed the pr33650 branch 3 times, most recently from 3810f4d to 946d551 Compare August 7, 2025 06:18
josephsavona added a commit that referenced this pull request Aug 27, 2025
We currently assume that any functions passes as props may be event
handlers or effect functions, and thus don't check for side effects such
as mutating globals. However, if a prop is a function that returns JSX
that is a sure sign that it's actually a render helper and not an event
handler or effect function. So we now emit a `Render` effect for any
prop that is a JSX-returning function, triggering all of our render
validation.

This required a small fix to InferTypes: we weren't correctly populating
the `return` type of function types during unification. I also improved
the printing of types so we can see the inferred return types.

---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/facebook/react/pull/33647).
* #33643
* #33650
* #33642
* __->__ #33647
github-actions Bot pushed a commit that referenced this pull request Aug 27, 2025
We currently assume that any functions passes as props may be event
handlers or effect functions, and thus don't check for side effects such
as mutating globals. However, if a prop is a function that returns JSX
that is a sure sign that it's actually a render helper and not an event
handler or effect function. So we now emit a `Render` effect for any
prop that is a JSX-returning function, triggering all of our render
validation.

This required a small fix to InferTypes: we weren't correctly populating
the `return` type of function types during unification. I also improved
the printing of types so we can see the inferred return types.

---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/facebook/react/pull/33647).
* #33643
* #33650
* #33642
* __->__ #33647

DiffTrain build for [33a1095](33a1095)
github-actions Bot pushed a commit that referenced this pull request Aug 27, 2025
We currently assume that any functions passes as props may be event
handlers or effect functions, and thus don't check for side effects such
as mutating globals. However, if a prop is a function that returns JSX
that is a sure sign that it's actually a render helper and not an event
handler or effect function. So we now emit a `Render` effect for any
prop that is a JSX-returning function, triggering all of our render
validation.

This required a small fix to InferTypes: we weren't correctly populating
the `return` type of function types during unification. I also improved
the printing of types so we can see the inferred return types.

---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/facebook/react/pull/33647).
* #33643
* #33650
* #33642
* __->__ #33647

DiffTrain build for [33a1095](33a1095)
In InferReferenceEffects we used `InstructionValue` as the key to represent values, since each time we process an instruction this object will be the same. However this was always a bit of a hack, and in the new model and InferMutationAliasingEffects we can instead use the (creation) effect as the stable value. This avoids an extra layer of memoization since the effects are already interned anyway.
josephsavona pushed a commit to josephsavona/react that referenced this pull request Mar 15, 2026
…er needs redesign

Investigated which compiler passes strictly need to store references to
Instruction or InstructionValue objects while mutating other values.
Found that InferMutationAliasingEffects was the primary concern: its
InferenceState used InstructionValue as map keys (including synthetic
allocation-site tokens), creating fundamental borrow conflicts for Rust.

Evaluated whether InstructionId could replace InstructionValue in all
maps. Determined it cannot — the pass fabricates synthetic InstructionValue
objects (ObjectExpression/Primitive) as allocation-site identity tokens
that have no associated InstructionId.

However, an upstream refactor (facebook#33650) eliminates this
entirely by replacing InstructionValue keys with interned AliasingEffect
objects. Since effects are already interned by content hash, they map
directly to a copyable EffectId index in Rust. This moves
InferMutationAliasingEffects from "significant redesign" to "moderate
refactoring" — all remaining maps use Copy ID types.

Updated all relevant sections: executive summary, side maps taxonomy,
structural similarity rankings, pass-by-pass analysis, risk assessment,
and migration strategy.
josephsavona pushed a commit to josephsavona/react that referenced this pull request Mar 15, 2026
…nership

Research questions addressed:
- What values are shared by reference between Instruction, InstructionValue,
  and AliasingEffect variants?
- Which passes read/write effects and how would they work in Rust?
- How does PR facebook#33650 (replacing InstructionValue with interned AliasingEffect
  as allocation-site keys) combine with the CreateFunction sharing pattern?

Key findings added as new section "AliasingEffect: Shared References and
Rust Ownership":

- Place sharing: every AliasingEffect variant shares Place objects with
  InstructionValue fields (same JS references). Resolved by cloning, which
  is cheap since Place stores IdentifierId (Copy).
- Apply effect shares the args array reference from InstructionValue.
  Resolved by cloning the Vec.
- CreateFunction holds the actual FunctionExpression InstructionValue,
  used for deep structural access and context variable mutation. In Rust,
  store InstructionId and look up from the HIR.
- PR facebook#33650 replaces InstructionValue allocation-site keys with interned
  AliasingEffect, eliminating effectInstructionValueCache. In Rust, EffectId
  (interning table index) serves as allocation-site identity directly — no
  separate AllocationSiteId needed.
- All effect consumers (InferMutationAliasingRanges, AnalyseFunctions,
  validation passes) access identifiers through IDs, never comparing Place
  references directly.

Updated cross-references throughout existing sections (executive summary,
side maps, structural similarity, Phase 6 pass analysis, risk assessment,
migration strategy).
zaroonjamil18-dev

This comment was marked as spam.

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.

3 participants