Skip to content

Conversation

mvitousek
Copy link
Contributor

@mvitousek mvitousek commented Aug 13, 2024

Stack from ghstack (oldest at bottom):

Summary:
In theory, as I understand it, the result of a useRef will never change between renders, because we'll always provide the same ref value consistently. We can mark useRef as producing a stable value to get better memoization

…n dependency is a ref

Summary:
In theory, as I understand it, the result of a useRef will never change between renders, because we'll always provide the same ref value consistently. That means that memoization that depends on a ref value will never re-compute, so I think we could not infer it as a dependency in Forget. This diff, however, doesn't do that: it instead allows the validatePreserveExistingMemoizationGuarantees analysis to admit mismatches between explicit dependencies and implicit ones when the implicit dependency is a ref that doesn't exist in source.

[ghstack-poisoned]
Copy link

vercel bot commented Aug 13, 2024

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
react-compiler-playground ✅ Ready (Inspect) Visit Preview 💬 Add feedback Aug 13, 2024 9:33pm

mvitousek added a commit that referenced this pull request Aug 13, 2024
…n dependency is a ref

Summary:
In theory, as I understand it, the result of a useRef will never change between renders, because we'll always provide the same ref value consistently. That means that memoization that depends on a ref value will never re-compute, so I think we could not infer it as a dependency in Forget. This diff, however, doesn't do that: it instead allows the validatePreserveExistingMemoizationGuarantees analysis to admit mismatches between explicit dependencies and implicit ones when the implicit dependency is a ref that doesn't exist in source.

ghstack-source-id: 5cd2aa1
Pull Request resolved: #30679
return;
}
}
let errorDiagnostic: CompareDependencyResult | null = null;
Copy link
Member

Choose a reason for hiding this comment

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

nit: move the let errorDiagnostic ... down since it's unrelated to the new if block

Copy link
Member

@josephsavona josephsavona left a comment

Choose a reason for hiding this comment

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

One thing to note is that it's possible to have a reactive ref:

const ref1 = useRef(..);
const ref2 = useRef(..);
const ref = props.cond ? ref1 : ref2;

...in which case we wouldn't want to prune ref as dependency in a subsequent reactive-scope/memo-block. In practice this is very rare, but unless we guard against that case the change here isn't 100% safe.

…ization when dependency is a ref"

Summary:
In theory, as I understand it, the result of a useRef will never change between renders, because we'll always provide the same ref value consistently. That means that memoization that depends on a ref value will never re-compute, so I think we could not infer it as a dependency in Forget. This diff, however, doesn't do that: it instead allows the validatePreserveExistingMemoizationGuarantees analysis to admit mismatches between explicit dependencies and implicit ones when the implicit dependency is a ref that doesn't exist in source.

[ghstack-poisoned]
mvitousek added a commit that referenced this pull request Aug 13, 2024
…n dependency is a ref

Summary:
In theory, as I understand it, the result of a useRef will never change between renders, because we'll always provide the same ref value consistently. That means that memoization that depends on a ref value will never re-compute, so I think we could not infer it as a dependency in Forget. This diff, however, doesn't do that: it instead allows the validatePreserveExistingMemoizationGuarantees analysis to admit mismatches between explicit dependencies and implicit ones when the implicit dependency is a ref that doesn't exist in source.

ghstack-source-id: a8e56b5
Pull Request resolved: #30679
@mvitousek
Copy link
Contributor Author

mvitousek commented Aug 13, 2024

@josephsavona Good catch! I pulled this thread a little more and realized that we already have the technology to mark useRef results as non-reactive at their point of creation (the isStableType predicate) and we just weren't doing so. I updated this PR to include refs as nonreactive, which now changes a lot of memoization results to never include refs in the first place. And of course, refs will now be reactive if the dominator analysis determines that they should be, as in your example

…ization when dependency is a ref"

Summary:
In theory, as I understand it, the result of a useRef will never change between renders, because we'll always provide the same ref value consistently. That means that memoization that depends on a ref value will never re-compute, so I think we could not infer it as a dependency in Forget. This diff, however, doesn't do that: it instead allows the validatePreserveExistingMemoizationGuarantees analysis to admit mismatches between explicit dependencies and implicit ones when the implicit dependency is a ref that doesn't exist in source.

[ghstack-poisoned]
mvitousek added a commit that referenced this pull request Aug 13, 2024
…n dependency is a ref

Summary:
In theory, as I understand it, the result of a useRef will never change between renders, because we'll always provide the same ref value consistently. That means that memoization that depends on a ref value will never re-compute, so I think we could not infer it as a dependency in Forget. This diff, however, doesn't do that: it instead allows the validatePreserveExistingMemoizationGuarantees analysis to admit mismatches between explicit dependencies and implicit ones when the implicit dependency is a ref that doesn't exist in source.

ghstack-source-id: 01f0078
Pull Request resolved: #30679
…ization when dependency is a ref"

Summary:
In theory, as I understand it, the result of a useRef will never change between renders, because we'll always provide the same ref value consistently. That means that memoization that depends on a ref value will never re-compute, so I think we could not infer it as a dependency in Forget. This diff, however, doesn't do that: it instead allows the validatePreserveExistingMemoizationGuarantees analysis to admit mismatches between explicit dependencies and implicit ones when the implicit dependency is a ref that doesn't exist in source.

[ghstack-poisoned]
mvitousek added a commit that referenced this pull request Aug 13, 2024
…n dependency is a ref

Summary:
In theory, as I understand it, the result of a useRef will never change between renders, because we'll always provide the same ref value consistently. That means that memoization that depends on a ref value will never re-compute, so I think we could not infer it as a dependency in Forget. This diff, however, doesn't do that: it instead allows the validatePreserveExistingMemoizationGuarantees analysis to admit mismatches between explicit dependencies and implicit ones when the implicit dependency is a ref that doesn't exist in source.

ghstack-source-id: 685d859
Pull Request resolved: #30679
…ization when dependency is a ref"

Summary:
In theory, as I understand it, the result of a useRef will never change between renders, because we'll always provide the same ref value consistently. That means that memoization that depends on a ref value will never re-compute, so I think we could not infer it as a dependency in Forget. This diff, however, doesn't do that: it instead allows the validatePreserveExistingMemoizationGuarantees analysis to admit mismatches between explicit dependencies and implicit ones when the implicit dependency is a ref that doesn't exist in source.

[ghstack-poisoned]
Copy link
Member

@josephsavona josephsavona left a comment

Choose a reason for hiding this comment

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

sogood

@mvitousek mvitousek changed the title [compiler] Allow different dependencies from explicit memoization when dependency is a ref [compiler] Recognize that refs are stable Aug 14, 2024
@mvitousek mvitousek merged commit 7e0d3d8 into gh/mvitousek/25/base Aug 14, 2024
mvitousek added a commit that referenced this pull request Aug 14, 2024
…n dependency is a ref

Summary:
In theory, as I understand it, the result of a useRef will never change between renders, because we'll always provide the same ref value consistently. That means that memoization that depends on a ref value will never re-compute, so I think we could not infer it as a dependency in Forget. This diff, however, doesn't do that: it instead allows the validatePreserveExistingMemoizationGuarantees analysis to admit mismatches between explicit dependencies and implicit ones when the implicit dependency is a ref that doesn't exist in source.

ghstack-source-id: 685d859
Pull Request resolved: #30679
@mvitousek mvitousek deleted the gh/mvitousek/25/head branch August 14, 2024 17:54
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