-
Notifications
You must be signed in to change notification settings - Fork 18.8k
Description
Per the spec, the following rule holds for shifts:
The right operand in a shift expression must have integer type [Go 1.13] or be an untyped constant representable by a value of type uint.
The following shift expression is permitted and doesn't follow this rule:
var s int = 100
var x = 1 << (1 << s)The RHS of the (outer) shift expression is (1 << s). It does not have integer type because the type of 1 depends on context and the RHS of a shift doesn't imply a type (only that its value be representable as a uint). The RHS is also not constant because s is not constant. And finally, 1 << s for s == 100 does not fit into a uint value. There is no run-time panic in this case: 1 << s silently overflows to 0 and then the value of x is 1 (playground).
A non-constant RHS of a shift expression may itself be untyped as is the case here. In short, untyped values (not just constants) of integer kind may appear "transiently" when evaluating shifts at runtime. (The only other non-constant untyped values that are possible are boolean results of comparisons).
The prose in the spec needs to be adjusted to accommodate for these cases.