Skip to content

Commit 88336dd

Browse files
authored
fix: Don't assume LHS of binary overload has a valid type (#2098)
1 parent f900310 commit 88336dd

File tree

3 files changed

+43
-26
lines changed

3 files changed

+43
-26
lines changed

src/compiler.ts

Lines changed: 21 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -3903,7 +3903,7 @@ export class Compiler extends DiagnosticEmitter {
39033903
if (classReference) {
39043904
let overload = classReference.lookupOverload(OperatorKind.LT);
39053905
if (overload) {
3906-
expr = this.compileBinaryOverload(overload, left, leftExpr, right, expression);
3906+
expr = this.compileBinaryOverload(overload, left, leftExpr, leftType, right, expression);
39073907
break;
39083908
}
39093909
}
@@ -3938,7 +3938,7 @@ export class Compiler extends DiagnosticEmitter {
39383938
if (classReference) {
39393939
let overload = classReference.lookupOverload(OperatorKind.GT);
39403940
if (overload) {
3941-
expr = this.compileBinaryOverload(overload, left, leftExpr, right, expression);
3941+
expr = this.compileBinaryOverload(overload, left, leftExpr, leftType, right, expression);
39423942
break;
39433943
}
39443944
}
@@ -3973,7 +3973,7 @@ export class Compiler extends DiagnosticEmitter {
39733973
if (classReference) {
39743974
let overload = classReference.lookupOverload(OperatorKind.LE);
39753975
if (overload) {
3976-
expr = this.compileBinaryOverload(overload, left, leftExpr, right, expression);
3976+
expr = this.compileBinaryOverload(overload, left, leftExpr, leftType, right, expression);
39773977
break;
39783978
}
39793979
}
@@ -4008,7 +4008,7 @@ export class Compiler extends DiagnosticEmitter {
40084008
if (classReference) {
40094009
let overload = classReference.lookupOverload(OperatorKind.GE);
40104010
if (overload) {
4011-
expr = this.compileBinaryOverload(overload, left, leftExpr, right, expression);
4011+
expr = this.compileBinaryOverload(overload, left, leftExpr, leftType, right, expression);
40124012
break;
40134013
}
40144014
}
@@ -4046,7 +4046,7 @@ export class Compiler extends DiagnosticEmitter {
40464046
if (classReference) {
40474047
let overload = classReference.lookupOverload(OperatorKind.EQ);
40484048
if (overload) {
4049-
expr = this.compileBinaryOverload(overload, left, leftExpr, right, expression);
4049+
expr = this.compileBinaryOverload(overload, left, leftExpr, leftType, right, expression);
40504050
break;
40514051
}
40524052
}
@@ -4085,7 +4085,7 @@ export class Compiler extends DiagnosticEmitter {
40854085
if (classReference) {
40864086
let overload = classReference.lookupOverload(OperatorKind.NE);
40874087
if (overload) {
4088-
expr = this.compileBinaryOverload(overload, left, leftExpr, right, expression);
4088+
expr = this.compileBinaryOverload(overload, left, leftExpr, leftType, right, expression);
40894089
break;
40904090
}
40914091
}
@@ -4126,7 +4126,7 @@ export class Compiler extends DiagnosticEmitter {
41264126
if (classReference) {
41274127
let overload = classReference.lookupOverload(OperatorKind.ADD);
41284128
if (overload) {
4129-
expr = this.compileBinaryOverload(overload, left, leftExpr, right, expression);
4129+
expr = this.compileBinaryOverload(overload, left, leftExpr, leftType, right, expression);
41304130
break;
41314131
}
41324132
}
@@ -4170,7 +4170,7 @@ export class Compiler extends DiagnosticEmitter {
41704170
if (classReference) {
41714171
let overload = classReference.lookupOverload(OperatorKind.SUB);
41724172
if (overload) {
4173-
expr = this.compileBinaryOverload(overload, left, leftExpr, right, expression);
4173+
expr = this.compileBinaryOverload(overload, left, leftExpr, leftType, right, expression);
41744174
break;
41754175
}
41764176
}
@@ -4215,7 +4215,7 @@ export class Compiler extends DiagnosticEmitter {
42154215
if (classReference) {
42164216
let overload = classReference.lookupOverload(OperatorKind.MUL);
42174217
if (overload) {
4218-
expr = this.compileBinaryOverload(overload, left, leftExpr, right, expression);
4218+
expr = this.compileBinaryOverload(overload, left, leftExpr, leftType, right, expression);
42194219
break;
42204220
}
42214221
}
@@ -4260,7 +4260,7 @@ export class Compiler extends DiagnosticEmitter {
42604260
if (classReference) {
42614261
let overload = classReference.lookupOverload(OperatorKind.POW);
42624262
if (overload) {
4263-
expr = this.compileBinaryOverload(overload, left, leftExpr, right, expression);
4263+
expr = this.compileBinaryOverload(overload, left, leftExpr, leftType, right, expression);
42644264
break;
42654265
}
42664266
}
@@ -4305,7 +4305,7 @@ export class Compiler extends DiagnosticEmitter {
43054305
if (classReference) {
43064306
let overload = classReference.lookupOverload(OperatorKind.DIV);
43074307
if (overload) {
4308-
expr = this.compileBinaryOverload(overload, left, leftExpr, right, expression);
4308+
expr = this.compileBinaryOverload(overload, left, leftExpr, leftType, right, expression);
43094309
break;
43104310
}
43114311
}
@@ -4350,7 +4350,7 @@ export class Compiler extends DiagnosticEmitter {
43504350
if (classReference) {
43514351
let overload = classReference.lookupOverload(OperatorKind.REM);
43524352
if (overload) {
4353-
expr = this.compileBinaryOverload(overload, left, leftExpr, right, expression);
4353+
expr = this.compileBinaryOverload(overload, left, leftExpr, leftType, right, expression);
43544354
break;
43554355
}
43564356
}
@@ -4395,7 +4395,7 @@ export class Compiler extends DiagnosticEmitter {
43954395
if (classReference) {
43964396
let overload = classReference.lookupOverload(OperatorKind.BITWISE_SHL);
43974397
if (overload) {
4398-
expr = this.compileBinaryOverload(overload, left, leftExpr, right, expression);
4398+
expr = this.compileBinaryOverload(overload, left, leftExpr, leftType, right, expression);
43994399
break;
44004400
}
44014401
}
@@ -4422,7 +4422,7 @@ export class Compiler extends DiagnosticEmitter {
44224422
if (classReference) {
44234423
let overload = classReference.lookupOverload(OperatorKind.BITWISE_SHR);
44244424
if (overload) {
4425-
expr = this.compileBinaryOverload(overload, left, leftExpr, right, expression);
4425+
expr = this.compileBinaryOverload(overload, left, leftExpr, leftType, right, expression);
44264426
break;
44274427
}
44284428
}
@@ -4450,7 +4450,7 @@ export class Compiler extends DiagnosticEmitter {
44504450
if (classReference) {
44514451
let overload = classReference.lookupOverload(OperatorKind.BITWISE_SHR_U);
44524452
if (overload) {
4453-
expr = this.compileBinaryOverload(overload, left, leftExpr, right, expression);
4453+
expr = this.compileBinaryOverload(overload, left, leftExpr, leftType, right, expression);
44544454
break;
44554455
}
44564456
}
@@ -4477,7 +4477,7 @@ export class Compiler extends DiagnosticEmitter {
44774477
if (classReference) {
44784478
let overload = classReference.lookupOverload(OperatorKind.BITWISE_AND);
44794479
if (overload) {
4480-
expr = this.compileBinaryOverload(overload, left, leftExpr, right, expression);
4480+
expr = this.compileBinaryOverload(overload, left, leftExpr, leftType, right, expression);
44814481
break;
44824482
}
44834483
}
@@ -4522,7 +4522,7 @@ export class Compiler extends DiagnosticEmitter {
45224522
if (classReference) {
45234523
let overload = classReference.lookupOverload(OperatorKind.BITWISE_OR);
45244524
if (overload) {
4525-
expr = this.compileBinaryOverload(overload, left, leftExpr, right, expression);
4525+
expr = this.compileBinaryOverload(overload, left, leftExpr, leftType, right, expression);
45264526
break;
45274527
}
45284528
}
@@ -4567,7 +4567,7 @@ export class Compiler extends DiagnosticEmitter {
45674567
if (classReference) {
45684568
let overload = classReference.lookupOverload(OperatorKind.BITWISE_XOR);
45694569
if (overload) {
4570-
expr = this.compileBinaryOverload(overload, left, leftExpr, right, expression);
4570+
expr = this.compileBinaryOverload(overload, left, leftExpr, leftType, right, expression);
45714571
break;
45724572
}
45734573
}
@@ -5808,24 +5808,19 @@ export class Compiler extends DiagnosticEmitter {
58085808
operatorInstance: Function,
58095809
left: Expression,
58105810
leftExpr: ExpressionRef,
5811+
leftType: Type,
58115812
right: Expression,
58125813
reportNode: Node
58135814
): ExpressionRef {
58145815
var rightType: Type;
58155816
if (operatorInstance.is(CommonFlags.INSTANCE)) {
5817+
assert(leftType.isStrictlyAssignableTo(operatorInstance.signature.parameterTypes[0]));
58165818
let classInstance = assert(operatorInstance.parent); assert(classInstance.kind == ElementKind.CLASS);
58175819
rightType = operatorInstance.signature.parameterTypes[0];
58185820
} else {
5819-
// FIXME: if LHS type differs we can't recompile left because that'd completely confuse
5820-
// local states, like having local flags that actually do not even exist, possibly
5821-
// releasing something random in that local before and evil things like that. Hence this
5822-
// assumes that LHS type matches, which in turn means that static overloads must be
5823-
// guaranteed to never mismatch LHS type, which in turn means that we can't have shiny
5824-
// things like multiple static overloads for different combinations of LHS/RHS types.
5825-
// We might want that at some point of course, but requires to complete the resolver so
5826-
// it can actually resolve every kind of expression without ever having to recompile.
58275821
rightType = operatorInstance.signature.parameterTypes[1];
58285822
}
5823+
leftExpr = this.convertExpression(leftExpr, leftType, operatorInstance.signature.parameterTypes[0], false, left);
58295824
var rightExpr = this.compileExpression(right, rightType, Constraints.CONV_IMPLICIT);
58305825
return this.makeCallDirect(operatorInstance, [ leftExpr, rightExpr ], reportNode);
58315826
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"asc_flags": [
3+
],
4+
"stderr": [
5+
"TS2322: Type '~lib/string/String | null' is not assignable to type '~lib/string/String'",
6+
"a.b + a.c",
7+
"TS2322: Type '~lib/string/String | null' is not assignable to type '~lib/string/String'",
8+
"a.c + a.b",
9+
"EOF"
10+
]
11+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
class A {
2+
b: string | null = "b";
3+
c: string = "c";
4+
}
5+
6+
var a = new A();
7+
8+
a.b + a.c; // TS2322
9+
a.c + a.b; // TS2322
10+
11+
ERROR("EOF");

0 commit comments

Comments
 (0)