@@ -3779,7 +3779,7 @@ export class Compiler extends DiagnosticEmitter {
37793779
37803780 rightExpr = this . compileExpression ( right , leftType ) ;
37813781 rightType = this . currentType ;
3782- commonType = Type . commonDenominator ( leftType , rightType , true ) ;
3782+ commonType = Type . commonType ( leftType , rightType , contextualType , true ) ;
37833783 if ( ! commonType || ! commonType . isNumericValue ) {
37843784 this . error (
37853785 DiagnosticCode . Operator_0_cannot_be_applied_to_types_1_and_2 ,
@@ -3814,7 +3814,7 @@ export class Compiler extends DiagnosticEmitter {
38143814
38153815 rightExpr = this . compileExpression ( right , leftType ) ;
38163816 rightType = this . currentType ;
3817- commonType = Type . commonDenominator ( leftType , rightType , true ) ;
3817+ commonType = Type . commonType ( leftType , rightType , contextualType , true ) ;
38183818 if ( ! commonType || ! commonType . isNumericValue ) {
38193819 this . error (
38203820 DiagnosticCode . Operator_0_cannot_be_applied_to_types_1_and_2 ,
@@ -3849,7 +3849,7 @@ export class Compiler extends DiagnosticEmitter {
38493849
38503850 rightExpr = this . compileExpression ( right , leftType ) ;
38513851 rightType = this . currentType ;
3852- commonType = Type . commonDenominator ( leftType , rightType , true ) ;
3852+ commonType = Type . commonType ( leftType , rightType , contextualType , true ) ;
38533853 if ( ! commonType || ! commonType . isNumericValue ) {
38543854 this . error (
38553855 DiagnosticCode . Operator_0_cannot_be_applied_to_types_1_and_2 ,
@@ -3884,7 +3884,7 @@ export class Compiler extends DiagnosticEmitter {
38843884
38853885 rightExpr = this . compileExpression ( right , leftType ) ;
38863886 rightType = this . currentType ;
3887- commonType = Type . commonDenominator ( leftType , rightType , true ) ;
3887+ commonType = Type . commonType ( leftType , rightType , contextualType , true ) ;
38883888 if ( ! commonType || ! commonType . isNumericValue ) {
38893889 this . error (
38903890 DiagnosticCode . Operator_0_cannot_be_applied_to_types_1_and_2 ,
@@ -3921,7 +3921,7 @@ export class Compiler extends DiagnosticEmitter {
39213921
39223922 rightExpr = this . compileExpression ( right , leftType ) ;
39233923 rightType = this . currentType ;
3924- commonType = Type . commonDenominator ( leftType , rightType , false ) ;
3924+ commonType = Type . commonType ( leftType , rightType , contextualType ) ;
39253925 if ( ! commonType ) {
39263926 this . error (
39273927 DiagnosticCode . Operator_0_cannot_be_applied_to_types_1_and_2 ,
@@ -3973,7 +3973,7 @@ export class Compiler extends DiagnosticEmitter {
39733973
39743974 rightExpr = this . compileExpression ( right , leftType ) ;
39753975 rightType = this . currentType ;
3976- commonType = Type . commonDenominator ( leftType , rightType , false ) ;
3976+ commonType = Type . commonType ( leftType , rightType , contextualType ) ;
39773977 if ( ! commonType ) {
39783978 this . error (
39793979 DiagnosticCode . Operator_0_cannot_be_applied_to_types_1_and_2 ,
@@ -4038,7 +4038,7 @@ export class Compiler extends DiagnosticEmitter {
40384038 } else {
40394039 rightExpr = this . compileExpression ( right , leftType ) ;
40404040 rightType = this . currentType ;
4041- commonType = Type . commonDenominator ( leftType , rightType , false ) ;
4041+ commonType = Type . commonType ( leftType , rightType , contextualType ) ;
40424042 if ( ! commonType || ! commonType . isNumericValue ) {
40434043 this . error (
40444044 DiagnosticCode . Operator_0_cannot_be_applied_to_types_1_and_2 ,
@@ -4083,7 +4083,7 @@ export class Compiler extends DiagnosticEmitter {
40834083 } else {
40844084 rightExpr = this . compileExpression ( right , leftType ) ;
40854085 rightType = this . currentType ;
4086- commonType = Type . commonDenominator ( leftType , rightType , false ) ;
4086+ commonType = Type . commonType ( leftType , rightType , contextualType ) ;
40874087 if ( ! commonType || ! leftType . isNumericValue ) {
40884088 this . error (
40894089 DiagnosticCode . Operator_0_cannot_be_applied_to_types_1_and_2 ,
@@ -4128,7 +4128,7 @@ export class Compiler extends DiagnosticEmitter {
41284128 } else {
41294129 rightExpr = this . compileExpression ( right , leftType ) ;
41304130 rightType = this . currentType ;
4131- commonType = Type . commonDenominator ( leftType , rightType , false ) ;
4131+ commonType = Type . commonType ( leftType , rightType , contextualType ) ;
41324132 if ( ! commonType || ! commonType . isNumericValue ) {
41334133 this . error (
41344134 DiagnosticCode . Operator_0_cannot_be_applied_to_types_1_and_2 ,
@@ -4173,7 +4173,7 @@ export class Compiler extends DiagnosticEmitter {
41734173 } else {
41744174 rightExpr = this . compileExpression ( right , leftType ) ;
41754175 rightType = this . currentType ;
4176- commonType = Type . commonDenominator ( leftType , rightType , false ) ;
4176+ commonType = Type . commonType ( leftType , rightType , contextualType ) ;
41774177 if ( ! commonType || ! commonType . isNumericValue ) {
41784178 this . error (
41794179 DiagnosticCode . Operator_0_cannot_be_applied_to_types_1_and_2 ,
@@ -4218,7 +4218,7 @@ export class Compiler extends DiagnosticEmitter {
42184218 } else {
42194219 rightExpr = this . compileExpression ( right , leftType ) ;
42204220 rightType = this . currentType ;
4221- commonType = Type . commonDenominator ( leftType , rightType , false ) ;
4221+ commonType = Type . commonType ( leftType , rightType , contextualType ) ;
42224222 if ( ! commonType || ! commonType . isNumericValue ) {
42234223 this . error (
42244224 DiagnosticCode . Operator_0_cannot_be_applied_to_types_1_and_2 ,
@@ -4263,7 +4263,7 @@ export class Compiler extends DiagnosticEmitter {
42634263 } else {
42644264 rightExpr = this . compileExpression ( right , leftType ) ;
42654265 rightType = this . currentType ;
4266- commonType = Type . commonDenominator ( leftType , rightType , false ) ;
4266+ commonType = Type . commonType ( leftType , rightType , contextualType ) ;
42674267 if ( ! commonType || ! commonType . isNumericValue ) {
42684268 this . error (
42694269 DiagnosticCode . Operator_0_cannot_be_applied_to_types_1_and_2 ,
@@ -4390,7 +4390,7 @@ export class Compiler extends DiagnosticEmitter {
43904390 } else {
43914391 rightExpr = this . compileExpression ( right , leftType ) ;
43924392 rightType = this . currentType ;
4393- commonType = Type . commonDenominator ( leftType , rightType , false ) ;
4393+ commonType = Type . commonType ( leftType , rightType , contextualType ) ;
43944394 if ( ! commonType || ! commonType . isIntegerValue ) {
43954395 this . error (
43964396 DiagnosticCode . Operator_0_cannot_be_applied_to_types_1_and_2 ,
@@ -4435,7 +4435,7 @@ export class Compiler extends DiagnosticEmitter {
44354435 } else {
44364436 rightExpr = this . compileExpression ( right , leftType ) ;
44374437 rightType = this . currentType ;
4438- commonType = Type . commonDenominator ( leftType , rightType , false ) ;
4438+ commonType = Type . commonType ( leftType , rightType , contextualType ) ;
44394439 if ( ! commonType || ! commonType . isIntegerValue ) {
44404440 this . error (
44414441 DiagnosticCode . Operator_0_cannot_be_applied_to_types_1_and_2 ,
@@ -4480,7 +4480,7 @@ export class Compiler extends DiagnosticEmitter {
44804480 } else {
44814481 rightExpr = this . compileExpression ( right , leftType ) ;
44824482 rightType = this . currentType ;
4483- commonType = Type . commonDenominator ( leftType , rightType , false ) ;
4483+ commonType = Type . commonType ( leftType , rightType , contextualType ) ;
44844484 if ( ! commonType || ! commonType . isIntegerValue ) {
44854485 this . error (
44864486 DiagnosticCode . Operator_0_cannot_be_applied_to_types_1_and_2 ,
@@ -4537,8 +4537,21 @@ export class Compiler extends DiagnosticEmitter {
45374537 this . currentType = Type . bool ;
45384538
45394539 } else {
4540- rightExpr = this . compileExpression ( right , leftType , inheritedConstraints | Constraints . ConvImplicit ) ;
4540+ rightExpr = this . compileExpression ( right , leftType , inheritedConstraints ) ;
45414541 rightType = this . currentType ;
4542+ commonType = Type . commonType ( leftType , rightType , contextualType ) ;
4543+ if ( ! commonType ) {
4544+ this . error (
4545+ DiagnosticCode . Operator_0_cannot_be_applied_to_types_1_and_2 ,
4546+ expression . range , "&&" , leftType . toString ( ) , rightType . toString ( )
4547+ ) ;
4548+ this . currentType = contextualType ;
4549+ return module . unreachable ( ) ;
4550+ }
4551+ leftExpr = this . convertExpression ( leftExpr , leftType , commonType , false , left ) ;
4552+ leftType = commonType ;
4553+ rightExpr = this . convertExpression ( rightExpr , rightType , commonType , false , right ) ;
4554+ rightType = commonType ;
45424555
45434556 // simplify if copying left is trivial
45444557 if ( expr = module . tryCopyTrivialExpression ( leftExpr ) ) {
@@ -4562,7 +4575,7 @@ export class Compiler extends DiagnosticEmitter {
45624575 flow . mergeBranch ( rightFlow ) ; // LHS && RHS -> RHS conditionally executes
45634576 flow . noteThen ( expr , rightFlow ) ; // LHS && RHS == true -> RHS always executes
45644577 this . currentFlow = flow ;
4565- this . currentType = leftType ;
4578+ this . currentType = commonType ;
45664579 }
45674580 break ;
45684581 }
@@ -4603,8 +4616,22 @@ export class Compiler extends DiagnosticEmitter {
46034616 this . currentType = Type . bool ;
46044617
46054618 } else {
4606- rightExpr = this . compileExpression ( right , leftType , inheritedConstraints | Constraints . ConvImplicit ) ;
4619+ rightExpr = this . compileExpression ( right , leftType , inheritedConstraints ) ;
46074620 rightType = this . currentType ;
4621+ commonType = Type . commonType ( leftType , rightType , contextualType ) ;
4622+ if ( ! commonType ) {
4623+ this . error (
4624+ DiagnosticCode . Operator_0_cannot_be_applied_to_types_1_and_2 ,
4625+ expression . range , "||" , leftType . toString ( ) , rightType . toString ( )
4626+ ) ;
4627+ this . currentType = contextualType ;
4628+ return module . unreachable ( ) ;
4629+ }
4630+ let possiblyNull = leftType . is ( TypeFlags . Nullable ) && rightType . is ( TypeFlags . Nullable ) ;
4631+ leftExpr = this . convertExpression ( leftExpr , leftType , commonType , false , left ) ;
4632+ leftType = commonType ;
4633+ rightExpr = this . convertExpression ( rightExpr , rightType , commonType , false , right ) ;
4634+ rightType = commonType ;
46084635
46094636 // simplify if copying left is trivial
46104637 if ( expr = module . tryCopyTrivialExpression ( leftExpr ) ) {
@@ -4629,7 +4656,9 @@ export class Compiler extends DiagnosticEmitter {
46294656 flow . mergeBranch ( rightFlow ) ; // LHS || RHS -> RHS conditionally executes
46304657 flow . noteElse ( expr , rightFlow ) ; // LHS || RHS == false -> RHS always executes
46314658 this . currentFlow = flow ;
4632- this . currentType = leftType ;
4659+ this . currentType = possiblyNull
4660+ ? commonType
4661+ : commonType . nonNullableType ;
46334662 }
46344663 break ;
46354664 }
@@ -8945,7 +8974,7 @@ export class Compiler extends DiagnosticEmitter {
89458974
89468975 private compileTernaryExpression (
89478976 expression : TernaryExpression ,
8948- ctxType : Type ,
8977+ contextualType : Type ,
89498978 constraints : Constraints
89508979 ) : ExpressionRef {
89518980 let module = this . module ;
@@ -8958,24 +8987,24 @@ export class Compiler extends DiagnosticEmitter {
89588987 // FIXME: skips common denominator, inconsistently picking branch type
89598988 let condKind = this . evaluateCondition ( condExprTrueish ) ;
89608989 if ( condKind == ConditionKind . True ) {
8961- return module . maybeDropCondition ( condExprTrueish , this . compileExpression ( ifThen , ctxType ) ) ;
8990+ return module . maybeDropCondition ( condExprTrueish , this . compileExpression ( ifThen , contextualType ) ) ;
89628991 }
89638992 if ( condKind == ConditionKind . False ) {
8964- return module . maybeDropCondition ( condExprTrueish , this . compileExpression ( ifElse , ctxType ) ) ;
8993+ return module . maybeDropCondition ( condExprTrueish , this . compileExpression ( ifElse , contextualType ) ) ;
89658994 }
89668995
89678996 let outerFlow = this . currentFlow ;
89688997 let ifThenFlow = outerFlow . forkThen ( condExpr ) ;
89698998 this . currentFlow = ifThenFlow ;
8970- let ifThenExpr = this . compileExpression ( ifThen , ctxType ) ;
8999+ let ifThenExpr = this . compileExpression ( ifThen , contextualType ) ;
89719000 let ifThenType = this . currentType ;
89729001
89739002 let ifElseFlow = outerFlow . forkElse ( condExpr ) ;
89749003 this . currentFlow = ifElseFlow ;
8975- let ifElseExpr = this . compileExpression ( ifElse , ctxType == Type . auto ? ifThenType : ctxType ) ;
9004+ let ifElseExpr = this . compileExpression ( ifElse , contextualType == Type . auto ? ifThenType : contextualType ) ;
89769005 let ifElseType = this . currentType ;
89779006
8978- if ( ctxType == Type . void ) { // values, including type mismatch, are irrelevant
9007+ if ( contextualType == Type . void ) { // values, including type mismatch, are irrelevant
89799008 if ( ifThenType != Type . void ) {
89809009 ifThenExpr = module . drop ( ifThenExpr ) ;
89819010 ifThenType = Type . void ;
@@ -8986,13 +9015,13 @@ export class Compiler extends DiagnosticEmitter {
89869015 }
89879016 this . currentType = Type . void ;
89889017 } else {
8989- let commonType = Type . commonDenominator ( ifThenType , ifElseType , false ) ;
9018+ let commonType = Type . commonType ( ifThenType , ifElseType , contextualType ) ;
89909019 if ( ! commonType ) {
89919020 this . error (
89929021 DiagnosticCode . Type_0_is_not_assignable_to_type_1 ,
89939022 ifElse . range , ifElseType . toString ( ) , ifThenType . toString ( )
89949023 ) ;
8995- this . currentType = ctxType ;
9024+ this . currentType = contextualType ;
89969025 return module . unreachable ( ) ;
89979026 }
89989027 ifThenExpr = this . convertExpression ( ifThenExpr , ifThenType , commonType , false , ifThen ) ;
0 commit comments