@samitouri / QOS-React-2 / commits / bddb7c9b5c

[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',