From 5ca2bc6d631dde8c221fa482cb8729a67115c7f9 Mon Sep 17 00:00:00 2001
From: mofeiZ <34200447+mofeiZ@users.noreply.github.com>
Date: Tue, 5 Nov 2024 17:56:53 -0500
Subject: [PATCH] [compiler][ez] Fixture repro for function hoisting bug
(#31349)
Repro for bug reported by @alexmckenley
---
.../bug-functiondecl-hoisting.expect.md | 81 +++++++++++++++++++
.../compiler/bug-functiondecl-hoisting.tsx | 22 +++++
.../packages/snap/src/SproutTodoFilter.ts | 1 +
3 files changed, 104 insertions(+)
create mode 100644 compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/bug-functiondecl-hoisting.expect.md
create mode 100644 compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/bug-functiondecl-hoisting.tsx
diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/bug-functiondecl-hoisting.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/bug-functiondecl-hoisting.expect.md
new file mode 100644
index 0000000000..2b0031b117
--- /dev/null
+++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/bug-functiondecl-hoisting.expect.md
@@ -0,0 +1,81 @@
+
+## Input
+
+```javascript
+import {Stringify} from 'shared-runtime';
+
+/**
+ * Fixture currently fails with
+ * Found differences in evaluator results
+ * Non-forget (expected):
+ * (kind: ok)
{"result":{"value":2},"fn":{"kind":"Function","result":{"value":2}},"shouldInvokeFns":true}
+ * Forget:
+ * (kind: exception) bar is not a function
+ */
+function Foo({value}) {
+ const result = bar();
+ function bar() {
+ return {value};
+ }
+ return ;
+}
+
+export const FIXTURE_ENTRYPOINT = {
+ fn: Foo,
+ params: [{value: 2}],
+};
+
+```
+
+## Code
+
+```javascript
+import { c as _c } from "react/compiler-runtime";
+import { Stringify } from "shared-runtime";
+
+/**
+ * Fixture currently fails with
+ * Found differences in evaluator results
+ * Non-forget (expected):
+ * (kind: ok) {"result":{"value":2},"fn":{"kind":"Function","result":{"value":2}},"shouldInvokeFns":true}
+ * Forget:
+ * (kind: exception) bar is not a function
+ */
+function Foo(t0) {
+ const $ = _c(6);
+ const { value } = t0;
+ let bar;
+ let result;
+ if ($[0] !== value) {
+ result = bar();
+ bar = function bar() {
+ return { value };
+ };
+ $[0] = value;
+ $[1] = bar;
+ $[2] = result;
+ } else {
+ bar = $[1];
+ result = $[2];
+ }
+
+ const t1 = bar;
+ let t2;
+ if ($[3] !== result || $[4] !== t1) {
+ t2 = ;
+ $[3] = result;
+ $[4] = t1;
+ $[5] = t2;
+ } else {
+ t2 = $[5];
+ }
+ return t2;
+}
+
+export const FIXTURE_ENTRYPOINT = {
+ fn: Foo,
+ params: [{ value: 2 }],
+};
+
+```
+
\ No newline at end of file
diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/bug-functiondecl-hoisting.tsx b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/bug-functiondecl-hoisting.tsx
new file mode 100644
index 0000000000..c454101282
--- /dev/null
+++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/bug-functiondecl-hoisting.tsx
@@ -0,0 +1,22 @@
+import {Stringify} from 'shared-runtime';
+
+/**
+ * Fixture currently fails with
+ * Found differences in evaluator results
+ * Non-forget (expected):
+ * (kind: ok) {"result":{"value":2},"fn":{"kind":"Function","result":{"value":2}},"shouldInvokeFns":true}
+ * Forget:
+ * (kind: exception) bar is not a function
+ */
+function Foo({value}) {
+ const result = bar();
+ function bar() {
+ return {value};
+ }
+ return ;
+}
+
+export const FIXTURE_ENTRYPOINT = {
+ fn: Foo,
+ params: [{value: 2}],
+};
diff --git a/compiler/packages/snap/src/SproutTodoFilter.ts b/compiler/packages/snap/src/SproutTodoFilter.ts
index 76914f1dd2..b868afc52b 100644
--- a/compiler/packages/snap/src/SproutTodoFilter.ts
+++ b/compiler/packages/snap/src/SproutTodoFilter.ts
@@ -480,6 +480,7 @@ const skipFilter = new Set([
'fbt/bug-fbt-plural-multiple-mixed-call-tag',
'bug-object-expression-computed-key-modified-during-after-construction-hoisted-sequence-expr',
'bug-invalid-hoisting-functionexpr',
+ 'bug-functiondecl-hoisting',
'bug-try-catch-maybe-null-dependency',
'reduce-reactive-deps/bug-infer-function-cond-access-not-hoisted',
'bug-invalid-phi-as-dependency',