Skip to content

Commit b9d0e17

Browse files
authored
Ignore switch statement bypass control flows that produce never (#51703)
* Ignore switch statement bypass control flows that produce 'never' * Add regression test
1 parent d43112a commit b9d0e17

File tree

6 files changed

+140
-1
lines changed

6 files changed

+140
-1
lines changed

src/compiler/checker.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26073,7 +26073,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
2607326073
// If the bypass flow contributes a type we haven't seen yet and the switch statement
2607426074
// isn't exhaustive, process the bypass flow type. Since exhaustiveness checks increase
2607526075
// the risk of circularities, we only want to perform them when they make a difference.
26076-
if (!contains(antecedentTypes, type) && !isExhaustiveSwitchStatement(bypassFlow.switchStatement)) {
26076+
if (!(type.flags & TypeFlags.Never) && !contains(antecedentTypes, type) && !isExhaustiveSwitchStatement(bypassFlow.switchStatement)) {
2607726077
if (type === declaredType && declaredType === initialType) {
2607826078
return type;
2607926079
}

tests/baselines/reference/exhaustiveSwitchCheckCircularity.errors.txt

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,22 @@ tests/cases/compiler/exhaustiveSwitchCheckCircularity.ts(14,26): error TS2345: A
2222
}
2323
}
2424
}
25+
26+
// Repro from #51688
27+
28+
declare function functionB(key: string): string;
29+
30+
function functionC(): void {
31+
let unionVal: "A" | "B" = "A";
32+
while (true) {
33+
let key: string;
34+
switch (unionVal) {
35+
case "A": {
36+
key = "AA";
37+
break;
38+
}
39+
}
40+
functionB(key);
41+
}
42+
}
2543

tests/baselines/reference/exhaustiveSwitchCheckCircularity.js

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,24 @@ function f() {
1717
}
1818
}
1919
}
20+
21+
// Repro from #51688
22+
23+
declare function functionB(key: string): string;
24+
25+
function functionC(): void {
26+
let unionVal: "A" | "B" = "A";
27+
while (true) {
28+
let key: string;
29+
switch (unionVal) {
30+
case "A": {
31+
key = "AA";
32+
break;
33+
}
34+
}
35+
functionB(key);
36+
}
37+
}
2038

2139

2240
//// [exhaustiveSwitchCheckCircularity.js]
@@ -36,3 +54,16 @@ function f() {
3654
}
3755
}
3856
}
57+
function functionC() {
58+
var unionVal = "A";
59+
while (true) {
60+
var key = void 0;
61+
switch (unionVal) {
62+
case "A": {
63+
key = "AA";
64+
break;
65+
}
66+
}
67+
functionB(key);
68+
}
69+
}

tests/baselines/reference/exhaustiveSwitchCheckCircularity.symbols

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,35 @@ function f() {
3232
}
3333
}
3434

35+
// Repro from #51688
36+
37+
declare function functionB(key: string): string;
38+
>functionB : Symbol(functionB, Decl(exhaustiveSwitchCheckCircularity.ts, 17, 1))
39+
>key : Symbol(key, Decl(exhaustiveSwitchCheckCircularity.ts, 21, 27))
40+
41+
function functionC(): void {
42+
>functionC : Symbol(functionC, Decl(exhaustiveSwitchCheckCircularity.ts, 21, 48))
43+
44+
let unionVal: "A" | "B" = "A";
45+
>unionVal : Symbol(unionVal, Decl(exhaustiveSwitchCheckCircularity.ts, 24, 7))
46+
47+
while (true) {
48+
let key: string;
49+
>key : Symbol(key, Decl(exhaustiveSwitchCheckCircularity.ts, 26, 11))
50+
51+
switch (unionVal) {
52+
>unionVal : Symbol(unionVal, Decl(exhaustiveSwitchCheckCircularity.ts, 24, 7))
53+
54+
case "A": {
55+
key = "AA";
56+
>key : Symbol(key, Decl(exhaustiveSwitchCheckCircularity.ts, 26, 11))
57+
58+
break;
59+
}
60+
}
61+
functionB(key);
62+
>functionB : Symbol(functionB, Decl(exhaustiveSwitchCheckCircularity.ts, 17, 1))
63+
>key : Symbol(key, Decl(exhaustiveSwitchCheckCircularity.ts, 26, 11))
64+
}
65+
}
66+

tests/baselines/reference/exhaustiveSwitchCheckCircularity.types

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,3 +41,43 @@ function f() {
4141
}
4242
}
4343

44+
// Repro from #51688
45+
46+
declare function functionB(key: string): string;
47+
>functionB : (key: string) => string
48+
>key : string
49+
50+
function functionC(): void {
51+
>functionC : () => void
52+
53+
let unionVal: "A" | "B" = "A";
54+
>unionVal : "A" | "B"
55+
>"A" : "A"
56+
57+
while (true) {
58+
>true : true
59+
60+
let key: string;
61+
>key : string
62+
63+
switch (unionVal) {
64+
>unionVal : "A"
65+
66+
case "A": {
67+
>"A" : "A"
68+
69+
key = "AA";
70+
>key = "AA" : "AA"
71+
>key : string
72+
>"AA" : "AA"
73+
74+
break;
75+
}
76+
}
77+
functionB(key);
78+
>functionB(key) : string
79+
>functionB : (key: string) => string
80+
>key : string
81+
}
82+
}
83+

tests/cases/compiler/exhaustiveSwitchCheckCircularity.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,21 @@ function f() {
1818
}
1919
}
2020
}
21+
22+
// Repro from #51688
23+
24+
declare function functionB(key: string): string;
25+
26+
function functionC(): void {
27+
let unionVal: "A" | "B" = "A";
28+
while (true) {
29+
let key: string;
30+
switch (unionVal) {
31+
case "A": {
32+
key = "AA";
33+
break;
34+
}
35+
}
36+
functionB(key);
37+
}
38+
}

0 commit comments

Comments
 (0)