Skip to content

Commit 2d84410

Browse files
committed
Pare down the PR to only fix the error message and check right operands
1 parent df5f297 commit 2d84410

File tree

3 files changed

+46
-81
lines changed

3 files changed

+46
-81
lines changed

src/compiler/checker.ts

Lines changed: 13 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -39667,29 +39667,15 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
3966739667
grammarErrorOnNode(right, Diagnostics._0_and_1_operations_cannot_be_mixed_without_parentheses, tokenToString(right.operatorToken.kind), tokenToString(operatorToken.kind));
3966839668
}
3966939669

39670-
const leftNullishSemantics = checkNullishCoalesceOperandLeft(node);
39671-
const rightNullishSemantics = checkNullishCoalesceOperandRight(node);
39672-
39673-
// check self if not checked by left operand of parent nullish coalesce expression
39674-
if (leftNullishSemantics === PredicateSemantics.Always && isNotWithinNullishCoalesceExpression(node)) {
39675-
if (rightNullishSemantics === PredicateSemantics.Always) {
39676-
error(node, Diagnostics.This_expression_is_always_nullish);
39677-
}
39678-
}
39670+
checkNullishCoalesceOperandLeft(node);
39671+
checkNullishCoalesceOperandRight(node);
3967939672
}
3968039673
}
3968139674

3968239675
function checkNullishCoalesceOperandLeft(node: BinaryExpression) {
3968339676
const leftTarget = skipOuterExpressions(node.left, OuterExpressionKinds.All);
3968439677

39685-
let nullishSemantics = getSyntacticNullishnessSemantics(leftTarget);
39686-
const isLiteral = nullishSemantics & PredicateSemantics.Literal;
39687-
nullishSemantics = nullishSemantics & ~PredicateSemantics.Literal;
39688-
39689-
if (isLiteral && isLeftmostNullishCoalesceOperand(node)) {
39690-
return nullishSemantics;
39691-
}
39692-
39678+
const nullishSemantics = getSyntacticNullishnessSemantics(leftTarget);
3969339679
if (nullishSemantics !== PredicateSemantics.Sometimes) {
3969439680
if (nullishSemantics === PredicateSemantics.Always) {
3969539681
error(leftTarget, Diagnostics.This_expression_is_always_nullish);
@@ -39698,30 +39684,21 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
3969839684
error(leftTarget, Diagnostics.Right_operand_of_is_unreachable_because_the_left_operand_is_never_nullish);
3969939685
}
3970039686
}
39701-
39702-
return nullishSemantics;
3970339687
}
3970439688

3970539689
function checkNullishCoalesceOperandRight(node: BinaryExpression) {
3970639690
const rightTarget = skipOuterExpressions(node.right, OuterExpressionKinds.All);
39707-
const nullishSemantics = getSyntacticNullishnessSemantics(rightTarget) & ~PredicateSemantics.Literal;
39691+
const nullishSemantics = getSyntacticNullishnessSemantics(rightTarget);
3970839692
if (isNotWithinNullishCoalesceExpression(node)) {
39709-
return nullishSemantics;
39693+
return;
3971039694
}
3971139695

3971239696
if (nullishSemantics === PredicateSemantics.Always) {
3971339697
error(rightTarget, Diagnostics.This_expression_is_always_nullish);
3971439698
}
39715-
39716-
return nullishSemantics;
39717-
}
39718-
39719-
function isLeftmostNullishCoalesceOperand(node: BinaryExpression) {
39720-
while (isBinaryExpression(node.parent) && node.parent.operatorToken.kind === SyntaxKind.QuestionQuestionToken && node.parent.left === node) {
39721-
node = node.parent;
39699+
else if (nullishSemantics === PredicateSemantics.Never) {
39700+
error(rightTarget, Diagnostics.This_expression_is_never_nullish);
3972239701
}
39723-
39724-
return isNotWithinNullishCoalesceExpression(node);
3972539702
}
3972639703

3972739704
function isNotWithinNullishCoalesceExpression(node: BinaryExpression) {
@@ -39741,35 +39718,24 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
3974139718
case SyntaxKind.BinaryExpression:
3974239719
// List of operators that can produce null/undefined:
3974339720
// = ??= ?? || ||= && &&=
39744-
const binaryExpression = node as BinaryExpression;
39745-
if (binaryExpression.operatorToken.kind === SyntaxKind.EqualsToken) {
39746-
return getSyntacticNullishnessSemantics(binaryExpression.right) & ~PredicateSemantics.Literal;
39747-
}
39748-
39749-
const leftSemantics = getSyntacticNullishnessSemantics(binaryExpression.left) & ~PredicateSemantics.Literal;
39750-
const rightSemantics = getSyntacticNullishnessSemantics(binaryExpression.right) & ~PredicateSemantics.Literal;
39751-
switch (binaryExpression.operatorToken.kind) {
39721+
switch ((node as BinaryExpression).operatorToken.kind) {
39722+
case SyntaxKind.EqualsToken:
3975239723
case SyntaxKind.QuestionQuestionToken:
3975339724
case SyntaxKind.QuestionQuestionEqualsToken:
3975439725
case SyntaxKind.BarBarToken:
3975539726
case SyntaxKind.BarBarEqualsToken:
39756-
return leftSemantics === PredicateSemantics.Never || rightSemantics === PredicateSemantics.Never ? PredicateSemantics.Never :
39757-
leftSemantics === PredicateSemantics.Sometimes || rightSemantics === PredicateSemantics.Sometimes ? PredicateSemantics.Sometimes :
39758-
PredicateSemantics.Always;
3975939727
case SyntaxKind.AmpersandAmpersandToken:
3976039728
case SyntaxKind.AmpersandAmpersandEqualsToken:
39761-
return leftSemantics === PredicateSemantics.Never && rightSemantics === PredicateSemantics.Never ? PredicateSemantics.Never :
39762-
leftSemantics === PredicateSemantics.Sometimes && rightSemantics === PredicateSemantics.Sometimes ? PredicateSemantics.Sometimes :
39763-
PredicateSemantics.Always;
39729+
return PredicateSemantics.Sometimes;
3976439730
}
3976539731
return PredicateSemantics.Never;
3976639732
case SyntaxKind.ConditionalExpression:
39767-
return (getSyntacticNullishnessSemantics((node as ConditionalExpression).whenTrue) | getSyntacticNullishnessSemantics((node as ConditionalExpression).whenFalse)) & ~PredicateSemantics.Literal;
39733+
return getSyntacticNullishnessSemantics((node as ConditionalExpression).whenTrue) | getSyntacticNullishnessSemantics((node as ConditionalExpression).whenFalse);
3976839734
case SyntaxKind.NullKeyword:
39769-
return PredicateSemantics.Always | PredicateSemantics.Literal;
39735+
return PredicateSemantics.Always;
3977039736
case SyntaxKind.Identifier:
3977139737
if (getResolvedSymbol(node as Identifier) === undefinedSymbol) {
39772-
return PredicateSemantics.Always | PredicateSemantics.Literal;
39738+
return PredicateSemantics.Always;
3977339739
}
3977439740
return PredicateSemantics.Sometimes;
3977539741
}

src/compiler/types.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -928,7 +928,6 @@ export const enum PredicateSemantics {
928928
None = 0,
929929
Always = 1 << 0,
930930
Never = 1 << 1,
931-
Literal = 1 << 2,
932931
Sometimes = Always | Never,
933932
}
934933

tests/baselines/reference/predicateSemantics.errors.txt

Lines changed: 33 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -2,31 +2,31 @@ predicateSemantics.ts(7,16): error TS2871: This expression is always nullish.
22
predicateSemantics.ts(10,16): error TS2869: Right operand of ?? is unreachable because the left operand is never nullish.
33
predicateSemantics.ts(26,13): error TS2869: Right operand of ?? is unreachable because the left operand is never nullish.
44
predicateSemantics.ts(27,13): error TS2869: Right operand of ?? is unreachable because the left operand is never nullish.
5+
predicateSemantics.ts(28,13): error TS2871: This expression is always nullish.
56
predicateSemantics.ts(29,13): error TS2871: This expression is always nullish.
67
predicateSemantics.ts(30,13): error TS2872: This kind of expression is always truthy.
78
predicateSemantics.ts(31,13): error TS2872: This kind of expression is always truthy.
89
predicateSemantics.ts(32,13): error TS2871: This expression is always nullish.
9-
predicateSemantics.ts(32,13): error TS2871: This expression is always nullish.
1010
predicateSemantics.ts(32,21): error TS2871: This expression is always nullish.
11-
predicateSemantics.ts(34,13): error TS2871: This expression is always nullish.
11+
predicateSemantics.ts(33,13): error TS2871: This expression is always nullish.
1212
predicateSemantics.ts(34,13): error TS2871: This expression is always nullish.
1313
predicateSemantics.ts(34,22): error TS2871: This expression is always nullish.
1414
predicateSemantics.ts(36,20): error TS2871: This expression is always nullish.
1515
predicateSemantics.ts(37,20): error TS2871: This expression is always nullish.
16+
predicateSemantics.ts(38,21): error TS2871: This expression is always nullish.
1617
predicateSemantics.ts(39,21): error TS2871: This expression is always nullish.
1718
predicateSemantics.ts(40,21): error TS2871: This expression is always nullish.
18-
predicateSemantics.ts(40,21): error TS2871: This expression is always nullish.
1919
predicateSemantics.ts(40,29): error TS2871: This expression is always nullish.
2020
predicateSemantics.ts(41,21): 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.
21+
predicateSemantics.ts(42,20): error TS2874: This expression is never nullish.
22+
predicateSemantics.ts(43,21): error TS2874: This expression is never nullish.
2523
predicateSemantics.ts(45,13): error TS2871: This expression is always nullish.
2624
predicateSemantics.ts(45,21): error TS2871: This expression is always nullish.
2725
predicateSemantics.ts(45,29): error TS2871: This expression is always nullish.
28-
predicateSemantics.ts(46,13): error TS2869: Right operand of ?? is unreachable because the left operand is never nullish.
29-
predicateSemantics.ts(47,13): error TS2869: Right operand of ?? is unreachable because the left operand is never nullish.
26+
predicateSemantics.ts(46,13): error TS2871: This expression is always nullish.
27+
predicateSemantics.ts(46,21): error TS2874: This expression is never nullish.
28+
predicateSemantics.ts(47,13): error TS2871: This expression is always nullish.
29+
predicateSemantics.ts(47,22): error TS2874: This expression is never nullish.
3030
predicateSemantics.ts(50,8): error TS2872: This kind of expression is always truthy.
3131
predicateSemantics.ts(51,11): error TS2872: This kind of expression is always truthy.
3232
predicateSemantics.ts(52,8): error TS2872: This kind of expression is always truthy.
@@ -70,8 +70,10 @@ predicateSemantics.ts(53,8): error TS2872: This kind of expression is always tru
7070
~~~~~
7171
!!! error TS2869: Right operand of ?? is unreachable because the left operand is never nullish.
7272
const p03 = null ?? 1;
73+
~~~~
74+
!!! error TS2871: This expression is always nullish.
7375
const p04 = null ?? null;
74-
~~~~~~~~~~~~
76+
~~~~
7577
!!! error TS2871: This expression is always nullish.
7678
const p05 = (class foo { }) && null;
7779
~~~~~~~~~~~~~~~
@@ -80,17 +82,15 @@ predicateSemantics.ts(53,8): error TS2872: This kind of expression is always tru
8082
~~~~~~~~~~~~~~~
8183
!!! error TS2872: This kind of expression is always truthy.
8284
const p07 = null ?? null ?? null;
83-
~~~~~~~~~~~~
84-
!!! error TS2871: This expression is always nullish.
85-
~~~~~~~~~~~~~~~~~~~~
85+
~~~~
8686
!!! error TS2871: This expression is always nullish.
8787
~~~~
8888
!!! error TS2871: This expression is always nullish.
8989
const p08 = null ?? opt ?? null;
90-
const p09 = null ?? (opt ? null : undefined) ?? null;
91-
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
90+
~~~~
9291
!!! error TS2871: This expression is always nullish.
93-
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
92+
const p09 = null ?? (opt ? null : undefined) ?? null;
93+
~~~~
9494
!!! error TS2871: This expression is always nullish.
9595
~~~~~~~~~~~~~~~~~~~~~~
9696
!!! error TS2871: This expression is always nullish.
@@ -102,43 +102,43 @@ predicateSemantics.ts(53,8): error TS2872: This kind of expression is always tru
102102
~~~~
103103
!!! error TS2871: This expression is always nullish.
104104
const p12 = opt ?? (null ?? 1);
105+
~~~~
106+
!!! error TS2871: This expression is always nullish.
105107
const p13 = opt ?? (null ?? null);
106-
~~~~~~~~~~~~
108+
~~~~
107109
!!! error TS2871: This expression is always nullish.
108110
const p14 = opt ?? (null ?? null ?? null);
109-
~~~~~~~~~~~~
110-
!!! error TS2871: This expression is always nullish.
111-
~~~~~~~~~~~~~~~~~~~~
111+
~~~~
112112
!!! error TS2871: This expression is always nullish.
113113
~~~~
114114
!!! error TS2871: This expression is always nullish.
115115
const p15 = opt ?? (opt ? null : undefined) ?? null;
116116
~~~~~~~~~~~~~~~~~~~~~~
117117
!!! error TS2871: This expression is always nullish.
118118
const p16 = opt ?? 1 ?? 2;
119-
~~~~~~~~
120-
!!! error TS2869: Right operand of ?? is unreachable because the left operand is never nullish.
119+
~
120+
!!! error TS2874: This expression is never nullish.
121121
const p17 = opt ?? (opt ? 1 : 2) ?? 3;
122-
~~~~~~~~~~~~~~~~~~~~
123-
!!! error TS2869: Right operand of ?? is unreachable because the left operand is never nullish.
122+
~~~~~~~~~~~
123+
!!! error TS2874: This expression is never nullish.
124124

125125
const p21 = null ?? null ?? null ?? null;
126-
~~~~~~~~~~~~
127-
!!! error TS2871: This expression is always nullish.
128-
~~~~~~~~~~~~~~~~~~~~
129-
!!! error TS2871: This expression is always nullish.
130-
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
126+
~~~~
131127
!!! error TS2871: This expression is always nullish.
132128
~~~~
133129
!!! error TS2871: This expression is always nullish.
134130
~~~~
135131
!!! error TS2871: This expression is always nullish.
136132
const p22 = null ?? 1 ?? 1;
137-
~~~~~~~~~
138-
!!! error TS2869: Right operand of ?? is unreachable because the left operand is never nullish.
133+
~~~~
134+
!!! error TS2871: This expression is always nullish.
135+
~
136+
!!! error TS2874: This expression is never nullish.
139137
const p23 = null ?? (opt ? 1 : 2) ?? 1;
140-
~~~~~~~~~~~~~~~~~~~~~
141-
!!! error TS2869: Right operand of ?? is unreachable because the left operand is never nullish.
138+
~~~~
139+
!!! error TS2871: This expression is always nullish.
140+
~~~~~~~~~~~
141+
!!! error TS2874: This expression is never nullish.
142142

143143
// Outer expression tests
144144
while ({} as any) { }

0 commit comments

Comments
 (0)