Skip to content

Commit fc33710

Browse files

File tree

4 files changed

+158
-1
lines changed

4 files changed

+158
-1
lines changed
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
2+
## Input
3+
4+
```javascript
5+
import {arrayPush, CONST_NUMBER0, mutate} from 'shared-runtime';
6+
7+
/**
8+
* Repro for bug in our type inference system. We currently propagate inferred
9+
* types through control flow / potential type guards. Note that this is
10+
* inconsistent with both Flow and Typescript.
11+
* https://flow.org/try/#1N4Igxg9gdgZglgcxALlAIwIZoKYBsD6uEEAztvhgE6UYCe+JADpdhgCYowa5kA0I2KAFcAtiRQAXSkOz9sADwxgJ+NPTbYuQ3BMnTZA+Y2yU4IwRO4A6SFBIrGVDGM7c+h46fNRLuKxJIGWh8MeT0ZfhYlCStpHzNsFBAMIQkIEQwJODAQfiEyfBE4eWw2fDgofDBMsAALfAA3KjgsXGxxZC4eAw0G-GhcWn9aY3wWZldu-g1mbGqJUoBaCRHEzrcDEgBrbAk62kXhXFxJ923d-cPRHEpTgyEoMDaqZdW7vKgoOfaSKgOKpqmDA+d4gB5fMA-P6LCCMLLQbiLOoYCqgh6-GDYRYIXYLSgkRZkCR4jpddwPfJLZjpOBkO4AX34kA0SRWxgABAAxYjsgC87OAAB0oOzReythU2Mh2YKQNyILLeMKxeymrgZNLhCIbsL6QBuYVs7DsgBCVD5AuVYolUClMpAZsoiqtorVGvZWpuSqg9OFMAeyjg0HZdTmW3lAAp5NKAPJoABWcwkAEppWZGLg4O12fJ2bSuTyhSKxSwJEJKCKAOQ2tiVvMi3MAMkbOasNb5vP5svlsoNPuFfoD8JFGQqUel8vZAB9TVReCHoHa0MRnlBUwWIJbi6K4DB2RHbGxk1uVSrd-uAIShsDh4hR5PHoun5-siS1SgQADuHuw34AotQECUBGsqysmfYvuyvrbqepblg2EFitBKpwRWOZ9vSuQgA0JgkEGUBJBk9gmCA9JAA
12+
* https://www.typescriptlang.org/play/?#code/C4TwDgpgBAYg9nKBeKBvAUFLUDWBLAOwBMAuKAInjnIBpNsA3AQwBsBXCMgtgWwCMIAJ3QBfANzpQkKACEmg5GnpZ8xMuTmDayqM3aco3fkLoj0AMzYEAxsDxwCUawAsI1nFQAUADzJw+AFZuwACUZEwAzhFCwBFQ3lB4cVRK2InmUJ4AhJ4A5KpEuYmOCQBkpfEAdAXISCiUCOQhIalp2MDOgnAA7oYQvQCigl2CnuRWEN6QthBETTpmZhZWtvaOPEyEPmQpAD6y8jRODqRQfAgsEEwEYbAIrVh4GZ7WJy0Ybdgubh4IPiEST5YQQQYBsQQlQHYMxpEFgiHxCQiIA
13+
*
14+
* Found differences in evaluator results
15+
* Non-forget (expected):
16+
* (kind: ok)
17+
* [2]
18+
* [3]
19+
* Forget:
20+
* (kind: ok)
21+
* [2]
22+
* [2,3]
23+
*/
24+
function useFoo({cond, value}: {cond: boolean; value: number}) {
25+
const x = {value: cond ? CONST_NUMBER0 : []};
26+
mutate(x);
27+
28+
const xValue = x.value;
29+
let result;
30+
if (typeof xValue === 'number') {
31+
result = xValue + 1; // (1) here we infer xValue is a primitive
32+
} else {
33+
result = arrayPush(xValue, value); // (2) and propagate it to all other xValue references
34+
}
35+
36+
return result;
37+
}
38+
export const FIXTURE_ENTRYPOINT = {
39+
fn: useFoo,
40+
params: [{cond: true}],
41+
sequentialRenders: [
42+
{cond: false, value: 2},
43+
{cond: false, value: 3},
44+
],
45+
};
46+
47+
```
48+
49+
## Code
50+
51+
```javascript
52+
import { c as _c } from "react/compiler-runtime";
53+
import { arrayPush, CONST_NUMBER0, mutate } from "shared-runtime";
54+
55+
/**
56+
* Repro for bug in our type inference system. We currently propagate inferred
57+
* types through control flow / potential type guards. Note that this is
58+
* inconsistent with both Flow and Typescript.
59+
* https://flow.org/try/#1N4Igxg9gdgZglgcxALlAIwIZoKYBsD6uEEAztvhgE6UYCe+JADpdhgCYowa5kA0I2KAFcAtiRQAXSkOz9sADwxgJ+NPTbYuQ3BMnTZA+Y2yU4IwRO4A6SFBIrGVDGM7c+h46fNRLuKxJIGWh8MeT0ZfhYlCStpHzNsFBAMIQkIEQwJODAQfiEyfBE4eWw2fDgofDBMsAALfAA3KjgsXGxxZC4eAw0G-GhcWn9aY3wWZldu-g1mbGqJUoBaCRHEzrcDEgBrbAk62kXhXFxJ923d-cPRHEpTgyEoMDaqZdW7vKgoOfaSKgOKpqmDA+d4gB5fMA-P6LCCMLLQbiLOoYCqgh6-GDYRYIXYLSgkRZkCR4jpddwPfJLZjpOBkO4AX34kA0SRWxgABAAxYjsgC87OAAB0oOzReythU2Mh2YKQNyILLeMKxeymrgZNLhCIbsL6QBuYVs7DsgBCVD5AuVYolUClMpAZsoiqtorVGvZWpuSqg9OFMAeyjg0HZdTmW3lAAp5NKAPJoABWcwkAEppWZGLg4O12fJ2bSuTyhSKxSwJEJKCKAOQ2tiVvMi3MAMkbOasNb5vP5svlsoNPuFfoD8JFGQqUel8vZAB9TVReCHoHa0MRnlBUwWIJbi6K4DB2RHbGxk1uVSrd-uAIShsDh4hR5PHoun5-siS1SgQADuHuw34AotQECUBGsqysmfYvuyvrbqepblg2EFitBKpwRWOZ9vSuQgA0JgkEGUBJBk9gmCA9JAA
60+
* https://www.typescriptlang.org/play/?#code/C4TwDgpgBAYg9nKBeKBvAUFLUDWBLAOwBMAuKAInjnIBpNsA3AQwBsBXCMgtgWwCMIAJ3QBfANzpQkKACEmg5GnpZ8xMuTmDayqM3aco3fkLoj0AMzYEAxsDxwCUawAsI1nFQAUADzJw+AFZuwACUZEwAzhFCwBFQ3lB4cVRK2InmUJ4AhJ4A5KpEuYmOCQBkpfEAdAXISCiUCOQhIalp2MDOgnAA7oYQvQCigl2CnuRWEN6QthBETTpmZhZWtvaOPEyEPmQpAD6y8jRODqRQfAgsEEwEYbAIrVh4GZ7WJy0Ybdgubh4IPiEST5YQQQYBsQQlQHYMxpEFgiHxCQiIA
61+
*
62+
* Found differences in evaluator results
63+
* Non-forget (expected):
64+
* (kind: ok)
65+
* [2]
66+
* [3]
67+
* Forget:
68+
* (kind: ok)
69+
* [2]
70+
* [2,3]
71+
*/
72+
function useFoo(t0) {
73+
const $ = _c(5);
74+
const { cond, value } = t0;
75+
let x;
76+
if ($[0] !== cond) {
77+
x = { value: cond ? CONST_NUMBER0 : [] };
78+
mutate(x);
79+
$[0] = cond;
80+
$[1] = x;
81+
} else {
82+
x = $[1];
83+
}
84+
85+
const xValue = x.value;
86+
let result;
87+
if (typeof xValue === "number") {
88+
result = xValue + 1;
89+
} else {
90+
let t1;
91+
if ($[2] !== value || $[3] !== xValue) {
92+
t1 = arrayPush(xValue, value);
93+
$[2] = value;
94+
$[3] = xValue;
95+
$[4] = t1;
96+
} else {
97+
t1 = $[4];
98+
}
99+
result = t1;
100+
}
101+
return result;
102+
}
103+
104+
export const FIXTURE_ENTRYPOINT = {
105+
fn: useFoo,
106+
params: [{ cond: true }],
107+
sequentialRenders: [
108+
{ cond: false, value: 2 },
109+
{ cond: false, value: 3 },
110+
],
111+
};
112+
113+
```
114+
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import {arrayPush, CONST_NUMBER0, mutate} from 'shared-runtime';
2+
3+
/**
4+
* Repro for bug in our type inference system. We currently propagate inferred
5+
* types through control flow / potential type guards. Note that this is
6+
* inconsistent with both Flow and Typescript.
7+
* https://flow.org/try/#1N4Igxg9gdgZglgcxALlAIwIZoKYBsD6uEEAztvhgE6UYCe+JADpdhgCYowa5kA0I2KAFcAtiRQAXSkOz9sADwxgJ+NPTbYuQ3BMnTZA+Y2yU4IwRO4A6SFBIrGVDGM7c+h46fNRLuKxJIGWh8MeT0ZfhYlCStpHzNsFBAMIQkIEQwJODAQfiEyfBE4eWw2fDgofDBMsAALfAA3KjgsXGxxZC4eAw0G-GhcWn9aY3wWZldu-g1mbGqJUoBaCRHEzrcDEgBrbAk62kXhXFxJ923d-cPRHEpTgyEoMDaqZdW7vKgoOfaSKgOKpqmDA+d4gB5fMA-P6LCCMLLQbiLOoYCqgh6-GDYRYIXYLSgkRZkCR4jpddwPfJLZjpOBkO4AX34kA0SRWxgABAAxYjsgC87OAAB0oOzReythU2Mh2YKQNyILLeMKxeymrgZNLhCIbsL6QBuYVs7DsgBCVD5AuVYolUClMpAZsoiqtorVGvZWpuSqg9OFMAeyjg0HZdTmW3lAAp5NKAPJoABWcwkAEppWZGLg4O12fJ2bSuTyhSKxSwJEJKCKAOQ2tiVvMi3MAMkbOasNb5vP5svlsoNPuFfoD8JFGQqUel8vZAB9TVReCHoHa0MRnlBUwWIJbi6K4DB2RHbGxk1uVSrd-uAIShsDh4hR5PHoun5-siS1SgQADuHuw34AotQECUBGsqysmfYvuyvrbqepblg2EFitBKpwRWOZ9vSuQgA0JgkEGUBJBk9gmCA9JAA
8+
* https://www.typescriptlang.org/play/?#code/C4TwDgpgBAYg9nKBeKBvAUFLUDWBLAOwBMAuKAInjnIBpNsA3AQwBsBXCMgtgWwCMIAJ3QBfANzpQkKACEmg5GnpZ8xMuTmDayqM3aco3fkLoj0AMzYEAxsDxwCUawAsI1nFQAUADzJw+AFZuwACUZEwAzhFCwBFQ3lB4cVRK2InmUJ4AhJ4A5KpEuYmOCQBkpfEAdAXISCiUCOQhIalp2MDOgnAA7oYQvQCigl2CnuRWEN6QthBETTpmZhZWtvaOPEyEPmQpAD6y8jRODqRQfAgsEEwEYbAIrVh4GZ7WJy0Ybdgubh4IPiEST5YQQQYBsQQlQHYMxpEFgiHxCQiIA
9+
*
10+
* Found differences in evaluator results
11+
* Non-forget (expected):
12+
* (kind: ok)
13+
* [2]
14+
* [3]
15+
* Forget:
16+
* (kind: ok)
17+
* [2]
18+
* [2,3]
19+
*/
20+
function useFoo({cond, value}: {cond: boolean; value: number}) {
21+
const x = {value: cond ? CONST_NUMBER0 : []};
22+
mutate(x);
23+
24+
const xValue = x.value;
25+
let result;
26+
if (typeof xValue === 'number') {
27+
result = xValue + 1; // (1) here we infer xValue is a primitive
28+
} else {
29+
result = arrayPush(xValue, value); // (2) and propagate it to all other xValue references
30+
}
31+
32+
return result;
33+
}
34+
export const FIXTURE_ENTRYPOINT = {
35+
fn: useFoo,
36+
params: [{cond: true}],
37+
sequentialRenders: [
38+
{cond: false, value: 2},
39+
{cond: false, value: 3},
40+
],
41+
};

compiler/packages/snap/src/SproutTodoFilter.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -485,6 +485,7 @@ const skipFilter = new Set([
485485
'bug-aliased-capture-mutate',
486486
'bug-functiondecl-hoisting',
487487
'bug-try-catch-maybe-null-dependency',
488+
'bug-type-inference-control-flow',
488489
'reduce-reactive-deps/bug-infer-function-cond-access-not-hoisted',
489490
'bug-invalid-phi-as-dependency',
490491
'reduce-reactive-deps/bug-merge-uncond-optional-chain-and-cond',

compiler/packages/snap/src/sprout/shared-runtime.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,8 +107,9 @@ export function setPropertyByKey<
107107
return arg;
108108
}
109109

110-
export function arrayPush<T>(arr: Array<T>, ...values: Array<T>): void {
110+
export function arrayPush<T>(arr: Array<T>, ...values: Array<T>): Array<T> {
111111
arr.push(...values);
112+
return arr;
112113
}
113114

114115
export function graphql(value: string): string {

0 commit comments

Comments
 (0)