Open ainar-g opened 3 years ago
I wonder why go/types
would report 1 << n
type as uint64
in that context.
I would expect it to be untyped int
since the left operand is an untyped constant 1
.
It should be fixed on the ruleguard side. The rule itself looks fine. It might be some corner case that needs to be worked around to get the desired result. (Although I need to read spec a little more on that to be sure.)
It might be related to this: https://github.com/golang/go/issues/13061 See also: https://github.com/mdempsky/unconvert/blob/95ecdbfc0b5f3e65790c43c77874ee5357ad8a8f/unconvert.go#L570
@quasilyte, I think it's consistent with the Go Spec:
The right operand in a shift expression must have integer type or be an untyped constant representable by a value of type
uint
. If the left operand of a non-constant shift expression is an untyped constant, it is first implicitly converted to the type it would assume if the shift expression were replaced by its left operand alone.
In fact, the Spec even gives an example of this exact behaviour:
var s uint = 33 // … var k = uint64(1<<s) // 1 has type uint64; k == 1<<33
Consider this code:
Currently,
ruleguard
complains:But the conversion is necessary here, because
mask
is a new variable, which the developer wants to be auint64
. I think such rules should consider if the left-hand-side variable is new or not.