If e != nil, it must be the binary expression; it may be nil for non-constant expressions (when invoked for an assignment operation where the binary expression is implicit).
(x *operand, e Expr, lhs, rhs Expr, op Operator)
| 1081 | // If e != nil, it must be the binary expression; it may be nil for non-constant expressions |
| 1082 | // (when invoked for an assignment operation where the binary expression is implicit). |
| 1083 | func (check *Checker) binary(x *operand, e Expr, lhs, rhs Expr, op Operator) { |
| 1084 | var y operand |
| 1085 | |
| 1086 | check.expr(x, lhs) |
| 1087 | check.expr(&y, rhs) |
| 1088 | |
| 1089 | if x.mode == invalid { |
| 1090 | return |
| 1091 | } |
| 1092 | if y.mode == invalid { |
| 1093 | x.mode = invalid |
| 1094 | x.expr = y.expr |
| 1095 | return |
| 1096 | } |
| 1097 | |
| 1098 | if isShift(op) { |
| 1099 | check.shift(x, &y, e, op) |
| 1100 | return |
| 1101 | } |
| 1102 | |
| 1103 | // TODO(gri) make canMix more efficient - called for each binary operation |
| 1104 | canMix := func(x, y *operand) bool { |
| 1105 | if isNonTypeParamInterface(x.typ) || isNonTypeParamInterface(y.typ) { |
| 1106 | return true |
| 1107 | } |
| 1108 | if allBoolean(x.typ) != allBoolean(y.typ) { |
| 1109 | return false |
| 1110 | } |
| 1111 | if allString(x.typ) != allString(y.typ) { |
| 1112 | return false |
| 1113 | } |
| 1114 | if x.isNil() && !hasNil(y.typ) { |
| 1115 | return false |
| 1116 | } |
| 1117 | if y.isNil() && !hasNil(x.typ) { |
| 1118 | return false |
| 1119 | } |
| 1120 | return true |
| 1121 | } |
| 1122 | if canMix(x, &y) { |
| 1123 | check.convertUntyped(x, y.typ) |
| 1124 | if x.mode == invalid { |
| 1125 | return |
| 1126 | } |
| 1127 | check.convertUntyped(&y, x.typ) |
| 1128 | if y.mode == invalid { |
| 1129 | x.mode = invalid |
| 1130 | return |
| 1131 | } |
| 1132 | } |
| 1133 | |
| 1134 | if isComparison(op) { |
| 1135 | check.comparison(x, &y, op, false) |
| 1136 | return |
| 1137 | } |
| 1138 | |
| 1139 | if !Identical(x.typ, y.typ) { |
| 1140 | // only report an error if we have valid types |
no test coverage detected