</li>
</ol>
+<p>
+By definition, a core type is never a <a href="#Type_definitions">defined type</a>,
+<a href="#Type_parameters">type parameter</a>, or
+<a href="#Interface_types">interface type</a>.
+</p>
+
<p>
Examples of interfaces with core types:
</p>
or a parenthesized expression.
</p>
+<pre class="ebnf">
+Operand = Literal | OperandName [ TypeArgs ] | "(" Expression ")" .
+Literal = BasicLit | CompositeLit | FunctionLit .
+BasicLit = int_lit | float_lit | imaginary_lit | rune_lit | string_lit .
+OperandName = identifier | QualifiedIdent .
+</pre>
+
<p>
An operand name denoting a <a href="#Function_declarations">type-parameterized function</a>
may be followed by a list of <a href="#Instantiations">type arguments</a>; the
operand only on the left-hand side of an <a href="#Assignments">assignment</a>.
</p>
-<pre class="ebnf">
-Operand = Literal | OperandName [ TypeArgs ] | "(" Expression ")" .
-Literal = BasicLit | CompositeLit | FunctionLit .
-BasicLit = int_lit | float_lit | imaginary_lit | rune_lit | string_lit .
-OperandName = identifier | QualifiedIdent .
-</pre>
-
<h3 id="Qualified_identifiers">Qualified identifiers</h3>
<p>
<h3 id="Composite_literals">Composite literals</h3>
<p>
-Composite literals construct values for structs, arrays, slices, and maps
-and create a new value each time they are evaluated.
+Composite literals construct new composite values each time they are evaluated.
They consist of the type of the literal followed by a brace-bound list of elements.
Each element may optionally be preceded by a corresponding key.
</p>
</pre>
<p>
-The LiteralType's underlying type must be a struct, array, slice, or map type
+The LiteralType's <a href="#Core_types">core type</a> <code>T</code>
+must be a struct, array, slice, or map type
(the grammar enforces this constraint except when the type is given
as a TypeName).
The types of the elements and keys must be <a href="#Assignability">assignable</a>
-to the respective field, element, and key types of the literal type;
+to the respective field, element, and key types of type <code>T</code>;
there is no additional conversion.
The key is interpreted as a field name for struct literals,
an index for array and slice literals, and a key for map literals.
<h3 id="Selectors">Selectors</h3>
+<!-- This is missing rules for x of type parameter type. -->
+
<p>
For a <a href="#Primary_expressions">primary expression</a> <code>x</code>
that is not a <a href="#Package_clause">package name</a>, the
For a value <code>x</code> of type <code>T</code> or <code>*T</code>
where <code>T</code> is not a pointer or interface type,
<code>x.f</code> denotes the field or method at the shallowest depth
-in <code>T</code> where there
-is such an <code>f</code>.
+in <code>T</code> where there is such an <code>f</code>.
If there is not exactly <a href="#Uniqueness_of_identifiers">one <code>f</code></a>
with shallowest depth, the selector expression is illegal.
</li>
If <code>a</code> is not a map:
</p>
<ul>
- <li>the index <code>x</code> must be of <a href="#Numeric_types">integer type</a> or an untyped constant</li>
+ <li>the index <code>x</code> must be an untyped constant or its
+ <a href="#Core_types">core type</a> must be an <a href="#Numeric_types">integer</a></li>
<li>a constant index must be non-negative and
<a href="#Representability">representable</a> by a value of type <code>int</code></li>
<li>a constant index that is untyped is given type <code>int</code></li>
<h4>Simple slice expressions</h4>
<p>
-For a string, array, pointer to array, or slice <code>a</code>, the primary expression
+The primary expression
</p>
<pre>
</pre>
<p>
-constructs a substring or slice. The <i>indices</i> <code>low</code> and
+constructs a substring or slice. The <a href="#Core_types">core type</a> of
+<code>a</code> must be a string, array, pointer to array, or slice.
+The <i>indices</i> <code>low</code> and
<code>high</code> select which elements of operand <code>a</code> appear
in the result. The result has indices starting at 0 and length equal to
<code>high</code> - <code>low</code>.
<h4>Full slice expressions</h4>
<p>
-For an array, pointer to array, or slice <code>a</code> (but not a string), the primary expression
+The primary expression
</p>
<pre>
constructs a slice of the same type, and with the same length and elements as the simple slice
expression <code>a[low : high]</code>. Additionally, it controls the resulting slice's capacity
by setting it to <code>max - low</code>. Only the first index may be omitted; it defaults to 0.
+The <a href="#Core_types">core type</a> of <code>a</code> must be an array, pointer to array,
+or slice (but not a string).
After slicing the array <code>a</code>
</p>
<h3 id="Calls">Calls</h3>
<p>
-Given an expression <code>f</code> of function type
-<code>F</code>,
+Given an expression <code>f</code> with a <a href="#Core_types">core type</a>
+<code>F</code> of <a href="#Function_types">function type</a>,
</p>
<pre>
<h3 id="Receive_operator">Receive operator</h3>
<p>
-For an operand <code>ch</code> of <a href="#Channel_types">channel type</a>,
+For an operand <code>ch</code> whose <a href="#Core_types">core type</a> is a
+<a href="#Channel_types">channel</a>,
the value of the receive operation <code><-ch</code> is the value received
from the channel <code>ch</code>. The channel direction must permit receive operations,
and the type of the receive operation is the element type of the channel.
<p>
A send statement sends a value on a channel.
-The channel expression must be of <a href="#Channel_types">channel type</a>,
+The channel expression's <a href="#Core_types">core type</a>
+must be a <a href="#Channel_types">channel</a>,
the channel direction must permit send operations,
and the type of the value to be sent must be <a href="#Assignability">assignable</a>
to the channel's element type.
<p>
The expression on the right in the "range" clause is called the <i>range expression</i>,
-which may be an array, pointer to an array, slice, string, map, or channel permitting
+its <a href="#Core_types">core type</a> must be
+an array, pointer to an array, slice, string, map, or channel permitting
<a href="#Receive_operator">receive operations</a>.
As with an assignment, if present the operands on the left must be
<a href="#Address_operators">addressable</a> or map index expressions; they
<h3 id="Close">Close</h3>
<p>
-For a channel <code>c</code>, the built-in function <code>close(c)</code>
+For an argument <code>ch</code> with a <a href="#Core_types">core type</a>
+that is a <a href="#Channel_types">channel</a>, the built-in function <code>close</code>
records that no more values will be sent on the channel.
-It is an error if <code>c</code> is a receive-only channel.
+It is an error if <code>ch</code> is a receive-only channel.
Sending to or closing a closed channel causes a <a href="#Run_time_panics">run-time panic</a>.
Closing the nil channel also causes a <a href="#Run_time_panics">run-time panic</a>.
After calling <code>close</code>, and after any previously
<p>
The built-in function <code>make</code> takes a type <code>T</code>,
-which must be a slice, map or channel type,
optionally followed by a type-specific list of expressions.
+The <a href="#Core_types">core type</a> of <code>T</code> must
+be a slice, map or channel.
It returns a value of type <code>T</code> (not <code>*T</code>).
The memory is initialized as described in the section on
<a href="#The_zero_value">initial values</a>.
</p>
<pre class="grammar">
-Call Type T Result
+Call Core type Result
-make(T, n) slice slice of type T with length n and capacity n
-make(T, n, m) slice slice of type T with length n and capacity m
+make(T, n) slice slice of type T with length n and capacity n
+make(T, n, m) slice slice of type T with length n and capacity m
-make(T) map map of type T
-make(T, n) map map of type T with initial space for approximately n elements
+make(T) map map of type T
+make(T, n) map map of type T with initial space for approximately n elements
-make(T) channel unbuffered channel of type T
-make(T, n) channel buffered channel of type T, buffer size n
+make(T) channel unbuffered channel of type T
+make(T, n) channel buffered channel of type T, buffer size n
</pre>
<p>
The <a href="#Function_types">variadic</a> function <code>append</code>
-appends zero or more values <code>x</code>
-to <code>s</code> of type <code>S</code>, which must be a slice type, and
-returns the resulting slice, also of type <code>S</code>.
-The values <code>x</code> are passed to a parameter of type <code>...T</code>
-where <code>T</code> is the <a href="#Slice_types">element type</a> of
-<code>S</code> and the respective
-<a href="#Passing_arguments_to_..._parameters">parameter passing rules</a> apply.
-As a special case, <code>append</code> also accepts a first argument
-assignable to type <code>[]byte</code> with a second argument of
-string type followed by <code>...</code>. This form appends the
-bytes of the string.
+appends zero or more values <code>x</code> to a slice <code>s</code>
+and returns the resulting slice.
+The <a href="#Core_types">core type</a> of <code>s</code> must be a slice
+of the form <code>[]E</code>.
+The values <code>x</code> are passed to a parameter of type <code>...E</code>
+and the respective <a href="#Passing_arguments_to_..._parameters">parameter
+passing rules</a> apply.
+As a special case, if the core type of <code>s</code> is <code>[]byte</code>,
+<code>append</code> also accepts a second argument with core type <code>string</code>
+followed by <code>...</code>. This form appends the bytes of the string.
</p>
<pre class="grammar">
-append(s S, x ...T) S // T is the element type of S
+append(s S, x ...E) S // E is the element type of the core type of S
</pre>
<p>
The function <code>copy</code> copies slice elements from
a source <code>src</code> to a destination <code>dst</code> and returns the
number of elements copied.
-Both arguments must have <a href="#Type_identity">identical</a> element type <code>T</code> and must be
-<a href="#Assignability">assignable</a> to a slice of type <code>[]T</code>.
+The <a href="#Core_types">core types</a> of both arguments must be slices
+with <a href="#Type_identity">identical</a> element type.
The number of elements copied is the minimum of
<code>len(src)</code> and <code>len(dst)</code>.
-As a special case, <code>copy</code> also accepts a destination argument assignable
-to type <code>[]byte</code> with a source argument of a string type.
+As a special case, if the destination's core type is <code>[]byte</code>,
+<code>copy</code> also accepts a source argument with core type <code>string</code>.
This form copies the bytes from the string into the byte slice.
</p>
delete(m, k) // remove element m[k] from map m
</pre>
+<p>
+If the type of <code>m</code> is a <a href="#Type_parameters">type parameter</a>,
+it must have <a href="#Specific_types">specific types</a>, all specific types
+must be maps, and they must all have identical key types.
+</p>
+
<p>
If the map <code>m</code> is <code>nil</code> or the element <code>m[k]</code>
does not exist, <code>delete</code> is a no-op.
<h3 id="Complex_numbers">Manipulating complex numbers</h3>
+<!-- We don't support generic arguments for these operations yet. -->
+
<p>
Three functions assemble and disassemble complex numbers.
The built-in function <code>complex</code> constructs a complex