// ok; can appear in type switch case clauses
// TODO(mdempsky): Handle as part of type switches instead?
case types2.UntypedInt, types2.UntypedFloat, types2.UntypedComplex:
- // Untyped rhs of non-constant shift, e.g. x << 1.0.
- // If we have a constant value, it must be an int >= 0.
+ typ = types2.Typ[types2.Uint]
if tv.Value != nil {
s := constant.ToInt(tv.Value)
- assert(s.Kind() == constant.Int && constant.Sign(s) >= 0)
+ assert(s.Kind() == constant.Int)
+ if constant.Sign(s) < 0 {
+ typ = types2.Typ[types2.Int]
+ }
}
- typ = types2.Typ[types2.Uint]
case types2.UntypedBool:
typ = types2.Typ[types2.Bool] // expression in "if" or "for" condition
case types2.UntypedString:
switch op {
case ir.OANDAND, ir.OOROR:
return typecheck.Expr(ir.NewLogicalExpr(pos, op, x, y))
+ case ir.OLSH, ir.ORSH:
+ // Untyped rhs of non-constant shift, e.g. x << 1.0.
+ // If we have a constant value, it must be an int >= 0.
+ if ir.IsConstNode(y) {
+ val := constant.ToInt(y.Val())
+ assert(val.Kind() == constant.Int && constant.Sign(val) >= 0)
+ }
}
return typecheck.Expr(ir.NewBinaryExpr(pos, op, x, y))