[compiler] Add fixture for objectexpr computed key bug (#31348)
We were bailing out on complex computed-key syntax (prior to #31344) as we assumed that this caused bugs (due to inferring computed key rvalues to have `freeze` effects). This fixture shows that this bailout is unrelated to the underlying bug
mofeiZ committed
Nov 5, 2024 at 17:56 UTC
bddb7c9b5c248c77fb52743cd319945d782bb7aa
3 files changed
+141
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/bug-object-expression-computed-key-modified-during-after-construction-hoisted-sequence-expr.expect.md
new
+109
@@ -0,0 +1,109 @@
1
+
2
+## Input
3
+
4
+```javascript
5
+import {identity, mutate} from 'shared-runtime';
6
+
7
+/**
8
+ * Bug: copy of error.todo-object-expression-computed-key-modified-during-after-construction-sequence-expr
9
+ * with the mutation hoisted to a named variable instead of being directly
10
+ * inlined into the Object key.
11
+ *
12
+ * Found differences in evaluator results
13
+ * Non-forget (expected):
14
+ * (kind: ok) [{"[object Object]":[42]},{"wat0":"joe","wat1":"joe"}]
15
+ * [{"[object Object]":[42]},{"wat0":"joe","wat1":"joe"}]
16
+ * Forget:
17
+ * (kind: ok) [{"[object Object]":[42]},{"wat0":"joe","wat1":"joe"}]
18
+ * [{"[object Object]":[42]},{"wat0":"joe","wat1":"joe","wat2":"joe"}]
19
+ */
20
+function Component(props) {
21
+ const key = {};
22
+ const tmp = (mutate(key), key);
23
+ const context = {
24
+ // Here, `tmp` is frozen (as it's inferred to be a primitive/string)
25
+ [tmp]: identity([props.value]),
26
+ };
27
+ mutate(key);
28
+ return [context, key];
29
+}
30
+
31
+export const FIXTURE_ENTRYPOINT = {
32
+ fn: Component,
33
+ params: [{value: 42}],
34
+ sequentialRenders: [{value: 42}, {value: 42}],
35
+};
36
+
37
+```
38
+
39
+## Code
40
+
41
+```javascript
42
+import { c as _c } from "react/compiler-runtime";
43
+import { identity, mutate } from "shared-runtime";
44
+
45
+/**
46
+ * Bug: copy of error.todo-object-expression-computed-key-modified-during-after-construction-sequence-expr
47
+ * with the mutation hoisted to a named variable instead of being directly
48
+ * inlined into the Object key.
49
+ *
50
+ * Found differences in evaluator results
51
+ * Non-forget (expected):
52
+ * (kind: ok) [{"[object Object]":[42]},{"wat0":"joe","wat1":"joe"}]
53
+ * [{"[object Object]":[42]},{"wat0":"joe","wat1":"joe"}]
54
+ * Forget:
55
+ * (kind: ok) [{"[object Object]":[42]},{"wat0":"joe","wat1":"joe"}]
56
+ * [{"[object Object]":[42]},{"wat0":"joe","wat1":"joe","wat2":"joe"}]
57
+ */
58
+function Component(props) {
59
+ const $ = _c(8);
60
+ let t0;
61
+ let key;
62
+ if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
63
+ key = {};
64
+ t0 = (mutate(key), key);
65
+ $[0] = t0;
66
+ $[1] = key;
67
+ } else {
68
+ t0 = $[0];
69
+ key = $[1];
70
+ }
71
+ const tmp = t0;
72
+ let t1;
73
+ if ($[2] !== props.value) {
74
+ t1 = identity([props.value]);
75
+ $[2] = props.value;
76
+ $[3] = t1;
77
+ } else {
78
+ t1 = $[3];
79
+ }
80
+ let t2;
81
+ if ($[4] !== t1) {
82
+ t2 = { [tmp]: t1 };
83
+ $[4] = t1;
84
+ $[5] = t2;
85
+ } else {
86
+ t2 = $[5];
87
+ }
88
+ const context = t2;
89
+
90
+ mutate(key);
91
+ let t3;
92
+ if ($[6] !== context) {
93
+ t3 = [context, key];
94
+ $[6] = context;
95
+ $[7] = t3;
96
+ } else {
97
+ t3 = $[7];
98
+ }
99
+ return t3;
100
+}
101
+
102
+export const FIXTURE_ENTRYPOINT = {
103
+ fn: Component,
104
+ params: [{ value: 42 }],
105
+ sequentialRenders: [{ value: 42 }, { value: 42 }],
106
+};
107
+
108
+```
109
+
\ No newline at end of file
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/bug-object-expression-computed-key-modified-during-after-construction-hoisted-sequence-expr.js
new
+31
@@ -0,0 +1,31 @@
1
+import {identity, mutate} from 'shared-runtime';
2
+
3
+/**
4
+ * Bug: copy of error.todo-object-expression-computed-key-modified-during-after-construction-sequence-expr
5
+ * with the mutation hoisted to a named variable instead of being directly
6
+ * inlined into the Object key.
7
+ *
8
+ * Found differences in evaluator results
9
+ * Non-forget (expected):
10
+ * (kind: ok) [{"[object Object]":[42]},{"wat0":"joe","wat1":"joe"}]
11
+ * [{"[object Object]":[42]},{"wat0":"joe","wat1":"joe"}]
12
+ * Forget:
13
+ * (kind: ok) [{"[object Object]":[42]},{"wat0":"joe","wat1":"joe"}]
14
+ * [{"[object Object]":[42]},{"wat0":"joe","wat1":"joe","wat2":"joe"}]
15
+ */
16
+function Component(props) {
17
+ const key = {};
18
+ const tmp = (mutate(key), key);
19
+ const context = {
20
+ // Here, `tmp` is frozen (as it's inferred to be a primitive/string)
21
+ [tmp]: identity([props.value]),
22
+ };
23
+ mutate(key);
24
+ return [context, key];
25
+}
26
+
27
+export const FIXTURE_ENTRYPOINT = {
28
+ fn: Component,
29
+ params: [{value: 42}],
30
+ sequentialRenders: [{value: 42}, {value: 42}],
31
+};
compiler/packages/snap/src/SproutTodoFilter.ts
+1
@@ -478,6 +478,7 @@ const skipFilter = new Set([
478
// bugs
479
'fbt/bug-fbt-plural-multiple-function-calls',
480
'fbt/bug-fbt-plural-multiple-mixed-call-tag',
481
+ 'bug-object-expression-computed-key-modified-during-after-construction-hoisted-sequence-expr',
482
'bug-invalid-hoisting-functionexpr',
483
'bug-try-catch-maybe-null-dependency',
484
'reduce-reactive-deps/bug-infer-function-cond-access-not-hoisted',