diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.todo-useCallback-accesses-ref-mutated-later-via-function-preserve-memoization.expect.md b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.todo-useCallback-accesses-ref-mutated-later-via-function-preserve-memoization.expect.md
new file mode 100644
index 0000000000..eb8ace2ed3
--- /dev/null
+++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.todo-useCallback-accesses-ref-mutated-later-via-function-preserve-memoization.expect.md
@@ -0,0 +1,42 @@
+
+## Input
+
+```javascript
+// @enablePreserveExistingMemoizationGuarantees
+import { useCallback, useRef } from "react";
+
+function Component(props) {
+ const ref = useRef({ inner: null });
+
+ const onChange = useCallback((event) => {
+ // The ref should still be mutable here even though function deps are frozen in
+ // @enablePreserveExistingMemoizationGuarantees mode
+ ref.current.inner = event.target.value;
+ });
+
+ // The ref is modified later, extending its range and preventing memoization of onChange
+ const reset = () => {
+ ref.current.inner = null;
+ };
+ reset();
+
+ return ;
+}
+
+export const FIXTURE_ENTRYPOINT = {
+ fn: Component,
+ params: [{}],
+};
+
+```
+
+
+## Error
+
+```
+[ReactForget] InvalidReact: This value was manually memoized, but cannot be memoized under Forget because it may be mutated after it is memoized (7:11)
+
+[ReactForget] InvalidReact: This value was manually memoized, but cannot be memoized under Forget because it may be mutated after it is memoized (7:11)
+```
+
+
\ No newline at end of file
diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.todo-useCallback-accesses-ref-mutated-later-via-function-preserve-memoization.js b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.todo-useCallback-accesses-ref-mutated-later-via-function-preserve-memoization.js
new file mode 100644
index 0000000000..b96e65780b
--- /dev/null
+++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.todo-useCallback-accesses-ref-mutated-later-via-function-preserve-memoization.js
@@ -0,0 +1,25 @@
+// @enablePreserveExistingMemoizationGuarantees
+import { useCallback, useRef } from "react";
+
+function Component(props) {
+ const ref = useRef({ inner: null });
+
+ const onChange = useCallback((event) => {
+ // The ref should still be mutable here even though function deps are frozen in
+ // @enablePreserveExistingMemoizationGuarantees mode
+ ref.current.inner = event.target.value;
+ });
+
+ // The ref is modified later, extending its range and preventing memoization of onChange
+ const reset = () => {
+ ref.current.inner = null;
+ };
+ reset();
+
+ return ;
+}
+
+export const FIXTURE_ENTRYPOINT = {
+ fn: Component,
+ params: [{}],
+};
diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.todo-useCallback-set-ref-nested-property-preserve-memoization.expect.md b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.todo-useCallback-set-ref-nested-property-ref-modified-later-preserve-memoization.expect.md
similarity index 90%
rename from compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.todo-useCallback-set-ref-nested-property-preserve-memoization.expect.md
rename to compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.todo-useCallback-set-ref-nested-property-ref-modified-later-preserve-memoization.expect.md
index 6d811b9889..169870e86e 100644
--- a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.todo-useCallback-set-ref-nested-property-preserve-memoization.expect.md
+++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.todo-useCallback-set-ref-nested-property-ref-modified-later-preserve-memoization.expect.md
@@ -14,6 +14,7 @@ function Component(props) {
ref.current.inner = event.target.value;
});
+ // The ref is modified later, extending its range and preventing memoization of onChange
ref.current.inner = null;
return ;
diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.todo-useCallback-set-ref-nested-property-ref-modified-later-preserve-memoization.js b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.todo-useCallback-set-ref-nested-property-ref-modified-later-preserve-memoization.js
new file mode 100644
index 0000000000..349e8f40c7
--- /dev/null
+++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.todo-useCallback-set-ref-nested-property-ref-modified-later-preserve-memoization.js
@@ -0,0 +1,22 @@
+// @enablePreserveExistingMemoizationGuarantees
+import { useCallback, useRef } from "react";
+
+function Component(props) {
+ const ref = useRef({ inner: null });
+
+ const onChange = useCallback((event) => {
+ // The ref should still be mutable here even though function deps are frozen in
+ // @enablePreserveExistingMemoizationGuarantees mode
+ ref.current.inner = event.target.value;
+ });
+
+ // The ref is modified later, extending its range and preventing memoization of onChange
+ ref.current.inner = null;
+
+ return ;
+}
+
+export const FIXTURE_ENTRYPOINT = {
+ fn: Component,
+ params: [{}],
+};
diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/useCallback-multiple-callbacks-modifying-same-ref-preserve-memoization.expect.md b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/useCallback-multiple-callbacks-modifying-same-ref-preserve-memoization.expect.md
new file mode 100644
index 0000000000..d770acd5f8
--- /dev/null
+++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/useCallback-multiple-callbacks-modifying-same-ref-preserve-memoization.expect.md
@@ -0,0 +1,91 @@
+
+## Input
+
+```javascript
+// @enablePreserveExistingMemoizationGuarantees
+import { useCallback, useRef } from "react";
+
+function Component(props) {
+ const ref = useRef({ inner: null });
+
+ const onChange = useCallback((event) => {
+ // The ref should still be mutable here even though function deps are frozen in
+ // @enablePreserveExistingMemoizationGuarantees mode
+ ref.current.inner = event.target.value;
+ });
+
+ const onReset = useCallback(() => {
+ ref.current.inner = null;
+ });
+
+ return ;
+}
+
+export const FIXTURE_ENTRYPOINT = {
+ fn: Component,
+ params: [{}],
+};
+
+```
+
+## Code
+
+```javascript
+// @enablePreserveExistingMemoizationGuarantees
+import {
+ useCallback,
+ useRef,
+ unstable_useMemoCache as useMemoCache,
+} from "react";
+
+function Component(props) {
+ const $ = useMemoCache(6);
+ let t0;
+ if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
+ t0 = { inner: null };
+ $[0] = t0;
+ } else {
+ t0 = $[0];
+ }
+ const ref = useRef(t0);
+ let t1;
+ if ($[1] === Symbol.for("react.memo_cache_sentinel")) {
+ t1 = (event) => {
+ ref.current.inner = event.target.value;
+ };
+ $[1] = t1;
+ } else {
+ t1 = $[1];
+ }
+ const onChange = t1;
+ let t2;
+ if ($[2] === Symbol.for("react.memo_cache_sentinel")) {
+ t2 = () => {
+ ref.current.inner = null;
+ };
+ $[2] = t2;
+ } else {
+ t2 = $[2];
+ }
+ const onReset = t2;
+ let t3;
+ if ($[3] !== onChange || $[4] !== onReset) {
+ t3 = ;
+ $[3] = onChange;
+ $[4] = onReset;
+ $[5] = t3;
+ } else {
+ t3 = $[5];
+ }
+ return t3;
+}
+
+export const FIXTURE_ENTRYPOINT = {
+ fn: Component,
+ params: [{}],
+};
+
+```
+
+### Eval output
+(kind: ok)
\ No newline at end of file
diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/useCallback-multiple-callbacks-modifying-same-ref-preserve-memoization.js b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/useCallback-multiple-callbacks-modifying-same-ref-preserve-memoization.js
new file mode 100644
index 0000000000..9031ae221a
--- /dev/null
+++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/useCallback-multiple-callbacks-modifying-same-ref-preserve-memoization.js
@@ -0,0 +1,23 @@
+// @enablePreserveExistingMemoizationGuarantees
+import { useCallback, useRef } from "react";
+
+function Component(props) {
+ const ref = useRef({ inner: null });
+
+ const onChange = useCallback((event) => {
+ // The ref should still be mutable here even though function deps are frozen in
+ // @enablePreserveExistingMemoizationGuarantees mode
+ ref.current.inner = event.target.value;
+ });
+
+ const onReset = useCallback(() => {
+ ref.current.inner = null;
+ });
+
+ return ;
+}
+
+export const FIXTURE_ENTRYPOINT = {
+ fn: Component,
+ params: [{}],
+};
diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/useCallback-set-ref-nested-property-dont-preserve-memoization.expect.md b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/useCallback-set-ref-nested-property-dont-preserve-memoization.expect.md
index 28a9e95668..3273c08df9 100644
--- a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/useCallback-set-ref-nested-property-dont-preserve-memoization.expect.md
+++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/useCallback-set-ref-nested-property-dont-preserve-memoization.expect.md
@@ -62,4 +62,6 @@ export const FIXTURE_ENTRYPOINT = {
};
```
-
\ No newline at end of file
+
+### Eval output
+(kind: ok)
\ No newline at end of file
diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/useCallback-set-ref-nested-property-preserve-memoization.expect.md b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/useCallback-set-ref-nested-property-preserve-memoization.expect.md
new file mode 100644
index 0000000000..14a7cc3ba3
--- /dev/null
+++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/useCallback-set-ref-nested-property-preserve-memoization.expect.md
@@ -0,0 +1,76 @@
+
+## Input
+
+```javascript
+// @enablePreserveExistingMemoizationGuarantees
+import { useCallback, useRef } from "react";
+
+function Component(props) {
+ const ref = useRef({ inner: null });
+
+ const onChange = useCallback((event) => {
+ // The ref should still be mutable here even though function deps are frozen in
+ // @enablePreserveExistingMemoizationGuarantees mode
+ ref.current.inner = event.target.value;
+ });
+
+ return ;
+}
+
+export const FIXTURE_ENTRYPOINT = {
+ fn: Component,
+ params: [{}],
+};
+
+```
+
+## Code
+
+```javascript
+// @enablePreserveExistingMemoizationGuarantees
+import {
+ useCallback,
+ useRef,
+ unstable_useMemoCache as useMemoCache,
+} from "react";
+
+function Component(props) {
+ const $ = useMemoCache(4);
+ let t0;
+ if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
+ t0 = { inner: null };
+ $[0] = t0;
+ } else {
+ t0 = $[0];
+ }
+ const ref = useRef(t0);
+ let t1;
+ if ($[1] === Symbol.for("react.memo_cache_sentinel")) {
+ t1 = (event) => {
+ ref.current.inner = event.target.value;
+ };
+ $[1] = t1;
+ } else {
+ t1 = $[1];
+ }
+ const onChange = t1;
+ let t2;
+ if ($[2] !== onChange) {
+ t2 = ;
+ $[2] = onChange;
+ $[3] = t2;
+ } else {
+ t2 = $[3];
+ }
+ return t2;
+}
+
+export const FIXTURE_ENTRYPOINT = {
+ fn: Component,
+ params: [{}],
+};
+
+```
+
+### Eval output
+(kind: ok)
\ No newline at end of file
diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.todo-useCallback-set-ref-nested-property-preserve-memoization.js b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/useCallback-set-ref-nested-property-preserve-memoization.js
similarity index 94%
rename from compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.todo-useCallback-set-ref-nested-property-preserve-memoization.js
rename to compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/useCallback-set-ref-nested-property-preserve-memoization.js
index 2bbf682733..8ee70dc4de 100644
--- a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.todo-useCallback-set-ref-nested-property-preserve-memoization.js
+++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/useCallback-set-ref-nested-property-preserve-memoization.js
@@ -10,8 +10,6 @@ function Component(props) {
ref.current.inner = event.target.value;
});
- ref.current.inner = null;
-
return ;
}