Open dominikh opened 3 years ago
Regarding the specific example above: The k
is defined as 4.0
which is of kind constant.Float
(not constant.Int
). It happens to be representable as an integer value without loss of precision, so the shift 1 << k
is valid. And the result of that shift is another constant, of kind constant.Int
(because shift results are always integers). In general, the kind associated with a constant literal must be the kind implied by its notation, which in turn explains what its default type would be, if it came into play (otherwise the default type couldn't be correctly computed).
In general, constant.Kind
's of constants referring to constant literals don't change. And the constant.Kind
of a constant expression depends on the expression. For instance, for the above k
, 1 + k
has kind constant.Float
but int(1) + k
has kind constant.Int
.
In general, constant.Kind's of constants referring to constant literals don't change
Am I understanding correctly that you mean to say that in 1 << k
, the constant.Kind
of k
won't be constant.Int
? Because that's not what I am seeing. The Kind changes based on the specific use of k
: https://play.golang.org/p/31JgWHr91-o
Sorry, I was not precise: The constant.Kind
of an identifier (which is an expression) depends on context, so if we have a shift and the constant (k
) is acceptable as shift count (in this case because it's representable as an integer), then the constant.Kind
for that identifier is constant.Int
. But the constant.Kind
of the value associated with the k
Const
object will reflect the syntax of that constant and won't change (example) - in fact it can't change otherwise we'd lose the information about the literal representation. Hopefully that makes things a bit clearer.
It does, thank you.
ISTM that go/types and go/constant don't currently do a good job at explaining which constant.Kind can be encountered in which contexts. For example, before seeing #43891 I wasn't aware that a floating point constant may have Kind() == Int.
And while that issue explains that go/constant may use a more efficient representation, it doesn't mention if it may use a less efficient representation, especially in relationship with the type checker. For example, in the following example
it is not clear to me whether the types.TypeAndValue for the ast.Ident
k
as used in the bit shift and function call are guaranteed to be a constant.Int or not. It currently seems to be, and existing code invet
doesn't defensively use ToInt before using Uint64ValSummarizing, I'd like to see documentation that at least
/cc @griesemer