From 8e4d2fb69d690695db0a33001fb1aee586bde15f Mon Sep 17 00:00:00 2001 From: Joe Savona Date: Thu, 11 Jan 2024 16:52:57 -0800 Subject: [PATCH] Repro for false positive in validatePreserveMemoization on non-escaping value This demonstrates a false positive in validatePreserveExistingManualMemoization. We prune memoization of non-escaping values, but the validation pass just sees that the value "should" have a scope and that scope doesn't exist, and thinks we failed to preserve memoization. --- ...ve-memoization-nonescaping-value.expect.md | 28 +++++++++++++++++++ ...-preserve-memoization-nonescaping-value.js | 13 +++++++++ 2 files changed, 41 insertions(+) create mode 100644 compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.repro-false-positive-preserve-memoization-nonescaping-value.expect.md create mode 100644 compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.repro-false-positive-preserve-memoization-nonescaping-value.js diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.repro-false-positive-preserve-memoization-nonescaping-value.expect.md b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.repro-false-positive-preserve-memoization-nonescaping-value.expect.md new file mode 100644 index 0000000000..b7b4d75aed --- /dev/null +++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.repro-false-positive-preserve-memoization-nonescaping-value.expect.md @@ -0,0 +1,28 @@ + +## Input + +```javascript +// @validatePreserveExistingMemoizationGuarantees @enableAssumeHooksFollowRulesOfReact @enableTransitivelyFreezeFunctionExpressions +function Component({ entity, children }) { + // showMessage doesn't escape so we don't memoize it. + // However, validatePreserveExistingMemoizationGuarantees only sees that the scope + // doesn't exist, and thinks the memoization was missed instead of being intentionally dropped. + const showMessage = useCallback(() => entity != null); + + if (!showMessage) { + return children; + } + + return {children}; +} + +``` + + +## Error + +``` +[ReactForget] InvalidReact: This value was manually memoized, but cannot be memoized under Forget because it may be mutated after it is memoized (6:6) +``` + + \ No newline at end of file diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.repro-false-positive-preserve-memoization-nonescaping-value.js b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.repro-false-positive-preserve-memoization-nonescaping-value.js new file mode 100644 index 0000000000..d917e72ea3 --- /dev/null +++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.repro-false-positive-preserve-memoization-nonescaping-value.js @@ -0,0 +1,13 @@ +// @validatePreserveExistingMemoizationGuarantees @enableAssumeHooksFollowRulesOfReact @enableTransitivelyFreezeFunctionExpressions +function Component({ entity, children }) { + // showMessage doesn't escape so we don't memoize it. + // However, validatePreserveExistingMemoizationGuarantees only sees that the scope + // doesn't exist, and thinks the memoization was missed instead of being intentionally dropped. + const showMessage = useCallback(() => entity != null); + + if (!showMessage) { + return children; + } + + return {children}; +}