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
var foo func(int)
const k = 4.0
_ = 1 << k
foo(k)
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 in vet doesn't defensively use ToInt before using Uint64Val
Summarizing, I'd like to see documentation that at least
- mentions that constant kinds aren't directly related to concrete types
- explains which simplifying guarantees go/types makes, if any
- states how defensively code has to be written in practice
/cc @griesemer
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
kas 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 invetdoesn't defensively use ToInt before using Uint64ValSummarizing, I'd like to see documentation that at least
/cc @griesemer