Skip to content

Commit 29570a9

Browse files
committed
Totally different fix
1 parent 1961197 commit 29570a9

File tree

3 files changed

+48
-78
lines changed

3 files changed

+48
-78
lines changed

src/compiler/checker.ts

Lines changed: 4 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -40534,12 +40534,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
4053440534
}
4053540535
}
4053640536
checkNullishCoalesceOperandLeft(node);
40537-
checkNullishCoalesceOperandRight(node);
4053840537
}
4053940538

4054040539
function checkNullishCoalesceOperandLeft(node: BinaryExpression) {
4054140540
const leftTarget = skipOuterExpressions(node.left, OuterExpressionKinds.All);
40542-
4054340541
const nullishSemantics = getSyntacticNullishnessSemantics(leftTarget);
4054440542
if (nullishSemantics !== PredicateSemantics.Sometimes) {
4054540543
if (nullishSemantics === PredicateSemantics.Always) {
@@ -40551,26 +40549,6 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
4055140549
}
4055240550
}
4055340551

40554-
function checkNullishCoalesceOperandRight(node: BinaryExpression) {
40555-
const rightTarget = skipOuterExpressions(node.right, OuterExpressionKinds.All);
40556-
const nullishSemantics = getSyntacticNullishnessSemantics(rightTarget);
40557-
if (isNotWithinNullishCoalesceExpression(node)) {
40558-
return;
40559-
}
40560-
40561-
if (nullishSemantics === PredicateSemantics.Always) {
40562-
error(rightTarget, Diagnostics.This_expression_is_always_nullish);
40563-
}
40564-
else if (nullishSemantics === PredicateSemantics.Never) {
40565-
error(rightTarget, Diagnostics.This_expression_is_never_nullish);
40566-
}
40567-
}
40568-
40569-
function isNotWithinNullishCoalesceExpression(node: BinaryExpression) {
40570-
const parent = walkUpOuterExpressions(node);
40571-
return !isBinaryExpression(parent) || parent.operatorToken.kind !== SyntaxKind.QuestionQuestionToken;
40572-
}
40573-
4057440552
function getSyntacticNullishnessSemantics(node: Node): PredicateSemantics {
4057540553
node = skipOuterExpressions(node);
4057640554
switch (node.kind) {
@@ -40588,15 +40566,16 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
4058840566
// List of operators that can produce null/undefined:
4058940567
// = ??= ?? || ||= && &&=
4059040568
switch ((node as BinaryExpression).operatorToken.kind) {
40591-
case SyntaxKind.EqualsToken:
40592-
case SyntaxKind.QuestionQuestionToken:
40593-
case SyntaxKind.QuestionQuestionEqualsToken:
4059440569
case SyntaxKind.BarBarToken:
4059540570
case SyntaxKind.BarBarEqualsToken:
4059640571
case SyntaxKind.AmpersandAmpersandToken:
4059740572
case SyntaxKind.AmpersandAmpersandEqualsToken:
4059840573
return PredicateSemantics.Sometimes;
40574+
// For these operator kinds, the right operand is effectively controlling
4059940575
case SyntaxKind.CommaToken:
40576+
case SyntaxKind.EqualsToken:
40577+
case SyntaxKind.QuestionQuestionToken:
40578+
case SyntaxKind.QuestionQuestionEqualsToken:
4060040579
return getSyntacticNullishnessSemantics((node as BinaryExpression).right);
4060140580
}
4060240581
return PredicateSemantics.Never;
Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
neverNullishThroughParentheses.ts(6,21): error TS2881: This expression is never nullish.
2-
neverNullishThroughParentheses.ts(7,22): error TS2881: This expression is never nullish.
3-
neverNullishThroughParentheses.ts(10,23): error TS2881: This expression is never nullish.
4-
neverNullishThroughParentheses.ts(11,24): error TS2881: This expression is never nullish.
1+
neverNullishThroughParentheses.ts(6,13): error TS2869: Right operand of ?? is unreachable because the left operand is never nullish.
2+
neverNullishThroughParentheses.ts(7,14): error TS2869: Right operand of ?? is unreachable because the left operand is never nullish.
3+
neverNullishThroughParentheses.ts(10,15): error TS2869: Right operand of ?? is unreachable because the left operand is never nullish.
4+
neverNullishThroughParentheses.ts(11,16): error TS2869: Right operand of ?? is unreachable because the left operand is never nullish.
55
neverNullishThroughParentheses.ts(14,15): error TS2869: Right operand of ?? is unreachable because the left operand is never nullish.
66
neverNullishThroughParentheses.ts(15,16): error TS2869: Right operand of ?? is unreachable because the left operand is never nullish.
77
neverNullishThroughParentheses.ts(16,17): error TS2869: Right operand of ?? is unreachable because the left operand is never nullish.
8-
neverNullishThroughParentheses.ts(16,24): error TS2881: This expression is never nullish.
8+
neverNullishThroughParentheses.ts(16,17): error TS2869: Right operand of ?? is unreachable because the left operand is never nullish.
99

1010

1111
==== neverNullishThroughParentheses.ts (8 errors) ====
@@ -15,19 +15,19 @@ neverNullishThroughParentheses.ts(16,24): error TS2881: This expression is never
1515

1616
// Both should error - both expressions are guaranteed to be "oops"
1717
const foo = x?.y ?? `oops` ?? "";
18-
~~~~~~
19-
!!! error TS2881: This expression is never nullish.
18+
~~~~~~~~~~~~~~
19+
!!! error TS2869: Right operand of ?? is unreachable because the left operand is never nullish.
2020
const bar = (x?.y ?? `oops`) ?? "";
21-
~~~~~~
22-
!!! error TS2881: This expression is never nullish.
21+
~~~~~~~~~~~~~~
22+
!!! error TS2869: Right operand of ?? is unreachable because the left operand is never nullish.
2323

2424
// Additional test cases with various levels of nesting
2525
const baz = ((x?.y ?? `oops`)) ?? "";
26-
~~~~~~
27-
!!! error TS2881: This expression is never nullish.
26+
~~~~~~~~~~~~~~
27+
!!! error TS2869: Right operand of ?? is unreachable because the left operand is never nullish.
2828
const qux = (((x?.y ?? `oops`))) ?? "";
29-
~~~~~~
30-
!!! error TS2881: This expression is never nullish.
29+
~~~~~~~~~~~~~~
30+
!!! error TS2869: Right operand of ?? is unreachable because the left operand is never nullish.
3131

3232
// Test with different types
3333
const str1 = ("literal") ?? "fallback";
@@ -39,6 +39,6 @@ neverNullishThroughParentheses.ts(16,24): error TS2881: This expression is never
3939
const nested = ("a" ?? "b") ?? "c";
4040
~~~
4141
!!! error TS2869: Right operand of ?? is unreachable because the left operand is never nullish.
42-
~~~
43-
!!! error TS2881: This expression is never nullish.
42+
~~~~~~~~~~
43+
!!! error TS2869: Right operand of ?? is unreachable because the left operand is never nullish.
4444

tests/baselines/reference/predicateSemantics.errors.txt

Lines changed: 29 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -7,29 +7,26 @@ predicateSemantics.ts(29,13): error TS2871: This expression is always nullish.
77
predicateSemantics.ts(30,13): error TS2872: This kind of expression is always truthy.
88
predicateSemantics.ts(31,13): error TS2872: This kind of expression is always truthy.
99
predicateSemantics.ts(32,13): error TS2871: This expression is always nullish.
10-
predicateSemantics.ts(32,21): error TS2871: This expression is always nullish.
10+
predicateSemantics.ts(32,13): error TS2871: This expression is always nullish.
1111
predicateSemantics.ts(33,13): error TS2871: This expression is always nullish.
1212
predicateSemantics.ts(34,13): error TS2871: This expression is always nullish.
13-
predicateSemantics.ts(34,22): error TS2871: This expression is always nullish.
14-
predicateSemantics.ts(36,20): error TS2871: This expression is always nullish.
15-
predicateSemantics.ts(37,20): error TS2871: This expression is always nullish.
13+
predicateSemantics.ts(34,13): error TS2871: This expression is always nullish.
14+
predicateSemantics.ts(36,13): error TS2871: This expression is always nullish.
15+
predicateSemantics.ts(37,13): error TS2871: This expression is always nullish.
1616
predicateSemantics.ts(38,21): error TS2871: This expression is always nullish.
17-
predicateSemantics.ts(38,29): error TS2881: This expression is never nullish.
1817
predicateSemantics.ts(39,21): error TS2871: This expression is always nullish.
19-
predicateSemantics.ts(39,29): error TS2871: This expression is always nullish.
2018
predicateSemantics.ts(40,21): error TS2871: This expression is always nullish.
21-
predicateSemantics.ts(40,29): error TS2871: This expression is always nullish.
22-
predicateSemantics.ts(40,37): error TS2871: This expression is always nullish.
23-
predicateSemantics.ts(41,21): error TS2871: This expression is always nullish.
24-
predicateSemantics.ts(42,20): error TS2881: This expression is never nullish.
25-
predicateSemantics.ts(43,21): error TS2881: This expression is never nullish.
19+
predicateSemantics.ts(40,21): error TS2871: This expression is always nullish.
20+
predicateSemantics.ts(41,13): error TS2871: This expression is always nullish.
21+
predicateSemantics.ts(42,13): error TS2869: Right operand of ?? is unreachable because the left operand is never nullish.
22+
predicateSemantics.ts(43,13): error TS2869: Right operand of ?? is unreachable because the left operand is never nullish.
23+
predicateSemantics.ts(45,13): error TS2871: This expression is always nullish.
24+
predicateSemantics.ts(45,13): error TS2871: This expression is always nullish.
2625
predicateSemantics.ts(45,13): error TS2871: This expression is always nullish.
27-
predicateSemantics.ts(45,21): error TS2871: This expression is always nullish.
28-
predicateSemantics.ts(45,29): error TS2871: This expression is always nullish.
2926
predicateSemantics.ts(46,13): error TS2871: This expression is always nullish.
30-
predicateSemantics.ts(46,21): error TS2881: This expression is never nullish.
27+
predicateSemantics.ts(46,13): error TS2869: Right operand of ?? is unreachable because the left operand is never nullish.
3128
predicateSemantics.ts(47,13): error TS2871: This expression is always nullish.
32-
predicateSemantics.ts(47,22): error TS2881: This expression is never nullish.
29+
predicateSemantics.ts(47,13): error TS2869: Right operand of ?? is unreachable because the left operand is never nullish.
3330
predicateSemantics.ts(50,8): error TS2872: This kind of expression is always truthy.
3431
predicateSemantics.ts(51,11): error TS2872: This kind of expression is always truthy.
3532
predicateSemantics.ts(52,8): error TS2872: This kind of expression is always truthy.
@@ -41,7 +38,7 @@ predicateSemantics.ts(89,1): error TS2869: Right operand of ?? is unreachable be
4138
predicateSemantics.ts(90,1): error TS2869: Right operand of ?? is unreachable because the left operand is never nullish.
4239

4340

44-
==== predicateSemantics.ts (41 errors) ====
41+
==== predicateSemantics.ts (38 errors) ====
4542
declare let opt: number | undefined;
4643

4744
// OK: One or other operand is possibly nullish
@@ -92,67 +89,61 @@ predicateSemantics.ts(90,1): error TS2869: Right operand of ?? is unreachable be
9289
const p07 = null ?? null ?? null;
9390
~~~~
9491
!!! error TS2871: This expression is always nullish.
95-
~~~~
92+
~~~~~~~~~~~~
9693
!!! error TS2871: This expression is always nullish.
9794
const p08 = null ?? opt ?? null;
9895
~~~~
9996
!!! error TS2871: This expression is always nullish.
10097
const p09 = null ?? (opt ? null : undefined) ?? null;
10198
~~~~
10299
!!! error TS2871: This expression is always nullish.
103-
~~~~~~~~~~~~~~~~~~~~~~
100+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
104101
!!! error TS2871: This expression is always nullish.
105102

106103
const p10 = opt ?? null ?? 1;
107-
~~~~
104+
~~~~~~~~~~~
108105
!!! error TS2871: This expression is always nullish.
109106
const p11 = opt ?? null ?? null;
110-
~~~~
107+
~~~~~~~~~~~
111108
!!! error TS2871: This expression is always nullish.
112109
const p12 = opt ?? (null ?? 1);
113110
~~~~
114111
!!! error TS2871: This expression is always nullish.
115-
~
116-
!!! error TS2881: This expression is never nullish.
117112
const p13 = opt ?? (null ?? null);
118113
~~~~
119-
!!! error TS2871: This expression is always nullish.
120-
~~~~
121114
!!! error TS2871: This expression is always nullish.
122115
const p14 = opt ?? (null ?? null ?? null);
123116
~~~~
124117
!!! error TS2871: This expression is always nullish.
125-
~~~~
126-
!!! error TS2871: This expression is always nullish.
127-
~~~~
118+
~~~~~~~~~~~~
128119
!!! error TS2871: This expression is always nullish.
129120
const p15 = opt ?? (opt ? null : undefined) ?? null;
130-
~~~~~~~~~~~~~~~~~~~~~~
121+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
131122
!!! error TS2871: This expression is always nullish.
132123
const p16 = opt ?? 1 ?? 2;
133-
~
134-
!!! error TS2881: This expression is never nullish.
124+
~~~~~~~~
125+
!!! error TS2869: Right operand of ?? is unreachable because the left operand is never nullish.
135126
const p17 = opt ?? (opt ? 1 : 2) ?? 3;
136-
~~~~~~~~~~~
137-
!!! error TS2881: This expression is never nullish.
127+
~~~~~~~~~~~~~~~~~~~~
128+
!!! error TS2869: Right operand of ?? is unreachable because the left operand is never nullish.
138129

139130
const p21 = null ?? null ?? null ?? null;
140131
~~~~
141132
!!! error TS2871: This expression is always nullish.
142-
~~~~
133+
~~~~~~~~~~~~
143134
!!! error TS2871: This expression is always nullish.
144-
~~~~
135+
~~~~~~~~~~~~~~~~~~~~
145136
!!! error TS2871: This expression is always nullish.
146137
const p22 = null ?? 1 ?? 1;
147138
~~~~
148139
!!! error TS2871: This expression is always nullish.
149-
~
150-
!!! error TS2881: This expression is never nullish.
140+
~~~~~~~~~
141+
!!! error TS2869: Right operand of ?? is unreachable because the left operand is never nullish.
151142
const p23 = null ?? (opt ? 1 : 2) ?? 1;
152143
~~~~
153144
!!! error TS2871: This expression is always nullish.
154-
~~~~~~~~~~~
155-
!!! error TS2881: This expression is never nullish.
145+
~~~~~~~~~~~~~~~~~~~~~
146+
!!! error TS2869: Right operand of ?? is unreachable because the left operand is never nullish.
156147

157148
// Outer expression tests
158149
while ({} as any) { }

0 commit comments

Comments
 (0)