Skip to content

Commit 2eaf49f

Browse files
authored
Handle pseudo-references in getFlowCacheKey (#49828)
* Handle pseudo-references in getFlowCacheKey * Add tests * Accept new baselines
1 parent 9dde56c commit 2eaf49f

File tree

6 files changed

+361
-0
lines changed

6 files changed

+361
-0
lines changed

src/compiler/checker.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23348,6 +23348,15 @@ m2: ${(this.mapper2 as unknown as DebugTypeMapper).__debugToString().split("\n")
2334823348
const key = getFlowCacheKey((node as AccessExpression).expression, declaredType, initialType, flowContainer);
2334923349
return key && key + "." + propName;
2335023350
}
23351+
break;
23352+
case SyntaxKind.ObjectBindingPattern:
23353+
case SyntaxKind.ArrayBindingPattern:
23354+
case SyntaxKind.FunctionDeclaration:
23355+
case SyntaxKind.FunctionExpression:
23356+
case SyntaxKind.ArrowFunction:
23357+
case SyntaxKind.MethodDeclaration:
23358+
// Handle pseudo-references originating in getNarrowedTypeOfSymbol.
23359+
return `${getNodeId(node)}#${getTypeId(declaredType)}`;
2335123360
}
2335223361
return undefined;
2335323362
}

tests/baselines/reference/dependentDestructuredVariables.errors.txt

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -331,4 +331,47 @@ tests/cases/conformance/controlFlow/dependentDestructuredVariables.ts(314,5): er
331331
test8 = value1.test8,
332332
test9 = value1.test9
333333
}) {}
334+
335+
// Repro from #49772
336+
337+
function fa1(x: [true, number] | [false, string]) {
338+
const [guard, value] = x;
339+
if (guard) {
340+
for (;;) {
341+
value; // number
342+
}
343+
}
344+
else {
345+
while (!!true) {
346+
value; // string
347+
}
348+
}
349+
}
350+
351+
function fa2(x: { guard: true, value: number } | { guard: false, value: string }) {
352+
const { guard, value } = x;
353+
if (guard) {
354+
for (;;) {
355+
value; // number
356+
}
357+
}
358+
else {
359+
while (!!true) {
360+
value; // string
361+
}
362+
}
363+
}
364+
365+
const fa3: (...args: [true, number] | [false, string]) => void = (guard, value) => {
366+
if (guard) {
367+
for (;;) {
368+
value; // number
369+
}
370+
}
371+
else {
372+
while (!!true) {
373+
value; // string
374+
}
375+
}
376+
}
334377

tests/baselines/reference/dependentDestructuredVariables.js

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -323,6 +323,49 @@ function foo({
323323
test8 = value1.test8,
324324
test9 = value1.test9
325325
}) {}
326+
327+
// Repro from #49772
328+
329+
function fa1(x: [true, number] | [false, string]) {
330+
const [guard, value] = x;
331+
if (guard) {
332+
for (;;) {
333+
value; // number
334+
}
335+
}
336+
else {
337+
while (!!true) {
338+
value; // string
339+
}
340+
}
341+
}
342+
343+
function fa2(x: { guard: true, value: number } | { guard: false, value: string }) {
344+
const { guard, value } = x;
345+
if (guard) {
346+
for (;;) {
347+
value; // number
348+
}
349+
}
350+
else {
351+
while (!!true) {
352+
value; // string
353+
}
354+
}
355+
}
356+
357+
const fa3: (...args: [true, number] | [false, string]) => void = (guard, value) => {
358+
if (guard) {
359+
for (;;) {
360+
value; // number
361+
}
362+
}
363+
else {
364+
while (!!true) {
365+
value; // string
366+
}
367+
}
368+
}
326369

327370

328371
//// [dependentDestructuredVariables.js]
@@ -567,6 +610,45 @@ const f60 = (kind, payload) => {
567610
};
568611
// Repro from #48902
569612
function foo({ value1, test1 = value1.test1, test2 = value1.test2, test3 = value1.test3, test4 = value1.test4, test5 = value1.test5, test6 = value1.test6, test7 = value1.test7, test8 = value1.test8, test9 = value1.test9 }) { }
613+
// Repro from #49772
614+
function fa1(x) {
615+
const [guard, value] = x;
616+
if (guard) {
617+
for (;;) {
618+
value; // number
619+
}
620+
}
621+
else {
622+
while (!!true) {
623+
value; // string
624+
}
625+
}
626+
}
627+
function fa2(x) {
628+
const { guard, value } = x;
629+
if (guard) {
630+
for (;;) {
631+
value; // number
632+
}
633+
}
634+
else {
635+
while (!!true) {
636+
value; // string
637+
}
638+
}
639+
}
640+
const fa3 = (guard, value) => {
641+
if (guard) {
642+
for (;;) {
643+
value; // number
644+
}
645+
}
646+
else {
647+
while (!!true) {
648+
value; // string
649+
}
650+
}
651+
};
570652

571653

572654
//// [dependentDestructuredVariables.d.ts]
@@ -696,3 +778,12 @@ declare function foo({ value1, test1, test2, test3, test4, test5, test6, test7,
696778
test8?: any;
697779
test9?: any;
698780
}): void;
781+
declare function fa1(x: [true, number] | [false, string]): void;
782+
declare function fa2(x: {
783+
guard: true;
784+
value: number;
785+
} | {
786+
guard: false;
787+
value: string;
788+
}): void;
789+
declare const fa3: (...args: [true, number] | [false, string]) => void;

tests/baselines/reference/dependentDestructuredVariables.symbols

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -830,3 +830,81 @@ function foo({
830830

831831
}) {}
832832

833+
// Repro from #49772
834+
835+
function fa1(x: [true, number] | [false, string]) {
836+
>fa1 : Symbol(fa1, Decl(dependentDestructuredVariables.ts, 323, 5))
837+
>x : Symbol(x, Decl(dependentDestructuredVariables.ts, 327, 13))
838+
839+
const [guard, value] = x;
840+
>guard : Symbol(guard, Decl(dependentDestructuredVariables.ts, 328, 11))
841+
>value : Symbol(value, Decl(dependentDestructuredVariables.ts, 328, 17))
842+
>x : Symbol(x, Decl(dependentDestructuredVariables.ts, 327, 13))
843+
844+
if (guard) {
845+
>guard : Symbol(guard, Decl(dependentDestructuredVariables.ts, 328, 11))
846+
847+
for (;;) {
848+
value; // number
849+
>value : Symbol(value, Decl(dependentDestructuredVariables.ts, 328, 17))
850+
}
851+
}
852+
else {
853+
while (!!true) {
854+
value; // string
855+
>value : Symbol(value, Decl(dependentDestructuredVariables.ts, 328, 17))
856+
}
857+
}
858+
}
859+
860+
function fa2(x: { guard: true, value: number } | { guard: false, value: string }) {
861+
>fa2 : Symbol(fa2, Decl(dependentDestructuredVariables.ts, 339, 1))
862+
>x : Symbol(x, Decl(dependentDestructuredVariables.ts, 341, 13))
863+
>guard : Symbol(guard, Decl(dependentDestructuredVariables.ts, 341, 17))
864+
>value : Symbol(value, Decl(dependentDestructuredVariables.ts, 341, 30))
865+
>guard : Symbol(guard, Decl(dependentDestructuredVariables.ts, 341, 50))
866+
>value : Symbol(value, Decl(dependentDestructuredVariables.ts, 341, 64))
867+
868+
const { guard, value } = x;
869+
>guard : Symbol(guard, Decl(dependentDestructuredVariables.ts, 342, 11))
870+
>value : Symbol(value, Decl(dependentDestructuredVariables.ts, 342, 18))
871+
>x : Symbol(x, Decl(dependentDestructuredVariables.ts, 341, 13))
872+
873+
if (guard) {
874+
>guard : Symbol(guard, Decl(dependentDestructuredVariables.ts, 342, 11))
875+
876+
for (;;) {
877+
value; // number
878+
>value : Symbol(value, Decl(dependentDestructuredVariables.ts, 342, 18))
879+
}
880+
}
881+
else {
882+
while (!!true) {
883+
value; // string
884+
>value : Symbol(value, Decl(dependentDestructuredVariables.ts, 342, 18))
885+
}
886+
}
887+
}
888+
889+
const fa3: (...args: [true, number] | [false, string]) => void = (guard, value) => {
890+
>fa3 : Symbol(fa3, Decl(dependentDestructuredVariables.ts, 355, 5))
891+
>args : Symbol(args, Decl(dependentDestructuredVariables.ts, 355, 12))
892+
>guard : Symbol(guard, Decl(dependentDestructuredVariables.ts, 355, 66))
893+
>value : Symbol(value, Decl(dependentDestructuredVariables.ts, 355, 72))
894+
895+
if (guard) {
896+
>guard : Symbol(guard, Decl(dependentDestructuredVariables.ts, 355, 66))
897+
898+
for (;;) {
899+
value; // number
900+
>value : Symbol(value, Decl(dependentDestructuredVariables.ts, 355, 72))
901+
}
902+
}
903+
else {
904+
while (!!true) {
905+
value; // string
906+
>value : Symbol(value, Decl(dependentDestructuredVariables.ts, 355, 72))
907+
}
908+
}
909+
}
910+

tests/baselines/reference/dependentDestructuredVariables.types

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -955,3 +955,100 @@ function foo({
955955

956956
}) {}
957957

958+
// Repro from #49772
959+
960+
function fa1(x: [true, number] | [false, string]) {
961+
>fa1 : (x: [true, number] | [false, string]) => void
962+
>x : [true, number] | [false, string]
963+
>true : true
964+
>false : false
965+
966+
const [guard, value] = x;
967+
>guard : boolean
968+
>value : string | number
969+
>x : [true, number] | [false, string]
970+
971+
if (guard) {
972+
>guard : boolean
973+
974+
for (;;) {
975+
value; // number
976+
>value : number
977+
}
978+
}
979+
else {
980+
while (!!true) {
981+
>!!true : true
982+
>!true : false
983+
>true : true
984+
985+
value; // string
986+
>value : string
987+
}
988+
}
989+
}
990+
991+
function fa2(x: { guard: true, value: number } | { guard: false, value: string }) {
992+
>fa2 : (x: { guard: true; value: number;} | { guard: false; value: string;}) => void
993+
>x : { guard: true; value: number; } | { guard: false; value: string; }
994+
>guard : true
995+
>true : true
996+
>value : number
997+
>guard : false
998+
>false : false
999+
>value : string
1000+
1001+
const { guard, value } = x;
1002+
>guard : boolean
1003+
>value : string | number
1004+
>x : { guard: true; value: number; } | { guard: false; value: string; }
1005+
1006+
if (guard) {
1007+
>guard : boolean
1008+
1009+
for (;;) {
1010+
value; // number
1011+
>value : number
1012+
}
1013+
}
1014+
else {
1015+
while (!!true) {
1016+
>!!true : true
1017+
>!true : false
1018+
>true : true
1019+
1020+
value; // string
1021+
>value : string
1022+
}
1023+
}
1024+
}
1025+
1026+
const fa3: (...args: [true, number] | [false, string]) => void = (guard, value) => {
1027+
>fa3 : (...args: [true, number] | [false, string]) => void
1028+
>args : [true, number] | [false, string]
1029+
>true : true
1030+
>false : false
1031+
>(guard, value) => { if (guard) { for (;;) { value; // number } } else { while (!!true) { value; // string } }} : (guard: boolean, value: string | number) => void
1032+
>guard : boolean
1033+
>value : string | number
1034+
1035+
if (guard) {
1036+
>guard : boolean
1037+
1038+
for (;;) {
1039+
value; // number
1040+
>value : number
1041+
}
1042+
}
1043+
else {
1044+
while (!!true) {
1045+
>!!true : true
1046+
>!true : false
1047+
>true : true
1048+
1049+
value; // string
1050+
>value : string
1051+
}
1052+
}
1053+
}
1054+

0 commit comments

Comments
 (0)