<a href="#Assignments">assignment</a> or as an
operand in an <a href="#Expressions">expression</a>.
It is an error if the constant value
-cannot be represented as a value of the respective type.
-For instance, <code>3.0</code> can be given any integer or any
-floating-point type, while <code>2147483648.0</code> (equal to <code>1<<31</code>)
-can be given the types <code>float32</code>, <code>float64</code>, or <code>uint32</code> but
-not <code>int32</code> or <code>string</code>.
+cannot be <a href="#Representability">represented</a> as a value of the respective type.
</p>
<p>
<p>
The length is part of the array's type; it must evaluate to a
-non-negative <a href="#Constants">constant</a> representable by a value
+non-negative <a href="#Constants">constant</a>
+<a href="#Representability">representable</a> by a value
of type <code>int</code>.
The length of array <code>a</code> can be discovered
using the built-in function <a href="#Length_and_capacity"><code>len</code></a>.
<p>
A value <code>x</code> is <i>assignable</i> to a <a href="#Variables">variable</a> of type <code>T</code>
-("<code>x</code> is assignable to <code>T</code>") in any of these cases:
+("<code>x</code> is assignable to <code>T</code>") if one of the following conditions applies:
</p>
<ul>
is a pointer, function, slice, map, channel, or interface type.
</li>
<li>
-<code>x</code> is an untyped <a href="#Constants">constant</a> representable
+<code>x</code> is an untyped <a href="#Constants">constant</a>
+<a href="#Representability">representable</a>
by a value of type <code>T</code>.
</li>
</ul>
+<h3 id="Representability">Representability</h3>
+
+<p>
+A <a href="#Constants">constant</a> <code>x</code> is <i>representable</i>
+by a value of type <code>T</code> if one of the following conditions applies:
+</p>
+
+<ul>
+<li>
+<code>x</code> is in the set of values <a href="#Types">determined</a> by <code>T</code>.
+</li>
+
+<li>
+<code>T</code> is a floating-point type and <code>x</code> can be rounded to <code>T</code>'s
+precision without overflow. Rounding uses IEEE 754 round-to-even rules but with an IEEE
+negative zero further simplified to an unsigned zero. Note that constant values never result
+in an IEEE negative zero, NaN, or infinity.
+</li>
+
+<li>
+<code>T</code> is a complex type, and <code>x</code>'s
+<a href="#Complex_numbers">components</a> <code>real(x)</code> and <code>imag(x)</code>
+are representable by values of <code>T</code>'s component type (<code>float32</code> or
+<code>float64</code>).
+</li>
+</ul>
+
+<pre>
+x T x is representable by a value of T because
+
+'a' byte 97 is in the set of byte values
+97 rune rune is an alias for int32, and 97 is in the set of 32-bit integers
+"foo" string "foo" is in the set of string values
+1024 int16 1024 is in the set of 16-bit integers
+42.0 byte 42 is in the set of unsigned 8-bit integers
+1e10 uint64 10000000000 is in the set of unsigned 64-bit integers
+2.718281828459045 float32 2.718281828459045 rounds to 2.7182817 which is in the set of float32 values
+-1e-1000 float64 -1e-1000 rounds to IEEE -0.0 which is further simplified to 0.0
+0i int 0 is an integer value
+(42 + 0i) float32 42.0 (with zero imaginary part) is in the set of float32 values
+</pre>
+
+<pre>
+x T x is not representable by a value of T because
+
+0 bool 0 is not in the set of boolean values
+'a' string 'a' is a rune, it is not in the set of string values
+1024 byte 1024 is not in the set of unsigned 8-bit integers
+-1 uint16 -1 is not in the set of unsigned 16-bit integers
+1.1 int 1.1 is not an integer value
+42i float32 (0 + 42i) is not in the set of float32 values
+1e1000 float64 1e1000 overflows to IEEE +Inf after rounding
+</pre>
+
+
<h2 id="Blocks">Blocks</h2>
<p>
its position in the array.
</li>
<li>An element with a key uses the key as its index. The
- key must be a non-negative constant representable by
+ key must be a non-negative constant
+ <a href="#Representability">representable</a> by
a value of type <code>int</code>; and if it is typed
it must be of integer type.
</li>
it is <i>in range</i> if <code>0 <= x < len(a)</code>,
otherwise it is <i>out of range</i></li>
<li>a <a href="#Constants">constant</a> index must be non-negative
- and representable by a value of type <code>int</code>
+ and <a href="#Representability">representable</a> by a value
+ of type <code>int</code></li>
</ul>
<p>
<code>0</code> <= <code>low</code> <= <code>high</code> <= <code>len(a)</code>,
otherwise they are <i>out of range</i>.
For slices, the upper index bound is the slice capacity <code>cap(a)</code> rather than the length.
-A <a href="#Constants">constant</a> index must be non-negative and representable by a value of type
+A <a href="#Constants">constant</a> index must be non-negative and
+<a href="#Representability">representable</a> by a value of type
<code>int</code>; for arrays or constant strings, constant indices must also be in range.
If both indices are constant, they must satisfy <code>low <= high</code>.
If the indices are out of range at run time, a <a href="#Run_time_panics">run-time panic</a> occurs.
<p>
The indices are <i>in range</i> if <code>0 <= low <= high <= max <= cap(a)</code>,
otherwise they are <i>out of range</i>.
-A <a href="#Constants">constant</a> index must be non-negative and representable by a value of type
+A <a href="#Constants">constant</a> index must be non-negative and
+<a href="#Representability">representable</a> by a value of type
<code>int</code>; for arrays, constant indices must also be in range.
If multiple indices are constant, the constants that are present must be in range relative to each
other.
<p>
The right operand in a shift expression must have unsigned integer type
-or be an untyped constant representable by a value of type <code>uint</code>.
+or be an untyped constant <a href="#Representability">representable</a> by a
+value of type <code>uint</code>.
If the left operand of a non-constant shift expression is an untyped constant,
it is first converted to the type it would assume if the shift expression were
replaced by its left operand alone.
<p>
A <a href="#Constants">constant</a> value <code>x</code> can be converted to
-type <code>T</code> in any of these cases:
+type <code>T</code> if <code>x</code> is <a href="#Representability">representable</a>
+by a value of <code>T</code>.
+As a special case, an integer constant <code>x</code> can be converted to a
+<a href="#String_types">string type</a> using the
+<a href="#Conversions_to_and_from_a_string_type">same rule</a>
+as for non-constant <code>x</code>.
</p>
-<ul>
- <li>
- <code>x</code> is representable by a value of type <code>T</code>.
- </li>
- <li>
- <code>x</code> is a floating-point constant,
- <code>T</code> is a floating-point type,
- and <code>x</code> is representable by a value
- of type <code>T</code> after rounding using
- IEEE 754 round-to-even rules, but with an IEEE <code>-0.0</code>
- further rounded to an unsigned <code>0.0</code>.
- The constant <code>T(x)</code> is the rounded value.
- </li>
- <li>
- <code>x</code> is an integer constant and <code>T</code> is a
- <a href="#String_types">string type</a>.
- The <a href="#Conversions_to_and_from_a_string_type">same rule</a>
- as for non-constant <code>x</code> applies in this case.
- </li>
-</ul>
-
<p>
Converting a constant yields a typed constant as result.
</p>
</pre>
<p>
-The values of <i>typed</i> constants must always be accurately representable as values
+The values of <i>typed</i> constants must always be accurately
+<a href="#Representability">representable</a> by values
of the constant type. The following constant expressions are illegal:
</p>
<p>
The size arguments <code>n</code> and <code>m</code> must be of integer type or untyped.
A <a href="#Constants">constant</a> size argument must be non-negative and
-representable by a value of type <code>int</code>.
+<a href="#Representability">representable</a> by a value of type <code>int</code>.
If both <code>n</code> and <code>m</code> are provided and are constant, then
<code>n</code> must be no larger than <code>m</code>.
If <code>n</code> is negative or larger than <code>m</code> at run time,