spec: adjust rules to use core or specific types as necessary

Change-Id: I64280c1bb9608d7781514f237ac70c6abbfde9f6
Reviewed-on: https://go-review.googlesource.com/c/go/+/384754
Trust: Robert Griesemer <gri@golang.org>
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
This commit is contained in:
Robert Griesemer 2022-02-09 20:49:17 -08:00
parent c4b87b8d08
commit 11788aa6e0
1 changed files with 72 additions and 48 deletions

View File

@ -1754,6 +1754,12 @@ depending on the direction of the directional channels present.
</li> </li>
</ol> </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> <p>
Examples of interfaces with core types: Examples of interfaces with core types:
</p> </p>
@ -2994,6 +3000,13 @@ non-<a href="#Blank_identifier">blank</a> identifier denoting a
or a parenthesized expression. or a parenthesized expression.
</p> </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> <p>
An operand name denoting a <a href="#Function_declarations">type-parameterized function</a> 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 may be followed by a list of <a href="#Instantiations">type arguments</a>; the
@ -3005,13 +3018,6 @@ The <a href="#Blank_identifier">blank identifier</a> may appear as an
operand only on the left-hand side of an <a href="#Assignments">assignment</a>. operand only on the left-hand side of an <a href="#Assignments">assignment</a>.
</p> </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> <h3 id="Qualified_identifiers">Qualified identifiers</h3>
<p> <p>
@ -3038,8 +3044,7 @@ math.Sin // denotes the Sin function in package math
<h3 id="Composite_literals">Composite literals</h3> <h3 id="Composite_literals">Composite literals</h3>
<p> <p>
Composite literals construct values for structs, arrays, slices, and maps Composite literals construct new composite values each time they are evaluated.
and create a new value each time they are evaluated.
They consist of the type of the literal followed by a brace-bound list of elements. 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. Each element may optionally be preceded by a corresponding key.
</p> </p>
@ -3057,11 +3062,12 @@ Element = Expression | LiteralValue .
</pre> </pre>
<p> <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 (the grammar enforces this constraint except when the type is given
as a TypeName). as a TypeName).
The types of the elements and keys must be <a href="#Assignability">assignable</a> 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. there is no additional conversion.
The key is interpreted as a field name for struct literals, The key is interpreted as a field name for struct literals,
an index for array and slice literals, and a key for map literals. an index for array and slice literals, and a key for map literals.
@ -3318,6 +3324,8 @@ f.p[i].x()
<h3 id="Selectors">Selectors</h3> <h3 id="Selectors">Selectors</h3>
<!-- This is missing rules for x of type parameter type. -->
<p> <p>
For a <a href="#Primary_expressions">primary expression</a> <code>x</code> For a <a href="#Primary_expressions">primary expression</a> <code>x</code>
that is not a <a href="#Package_clause">package name</a>, the that is not a <a href="#Package_clause">package name</a>, the
@ -3361,8 +3369,7 @@ The following rules apply to selectors:
For a value <code>x</code> of type <code>T</code> or <code>*T</code> 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, where <code>T</code> is not a pointer or interface type,
<code>x.f</code> denotes the field or method at the shallowest depth <code>x.f</code> denotes the field or method at the shallowest depth
in <code>T</code> where there in <code>T</code> where there is such an <code>f</code>.
is such an <code>f</code>.
If there is not exactly <a href="#Uniqueness_of_identifiers">one <code>f</code></a> If there is not exactly <a href="#Uniqueness_of_identifiers">one <code>f</code></a>
with shallowest depth, the selector expression is illegal. with shallowest depth, the selector expression is illegal.
</li> </li>
@ -3722,7 +3729,8 @@ The following rules apply:
If <code>a</code> is not a map: If <code>a</code> is not a map:
</p> </p>
<ul> <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 <li>a constant index must be non-negative and
<a href="#Representability">representable</a> by a value of type <code>int</code></li> <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> <li>a constant index that is untyped is given type <code>int</code></li>
@ -3844,7 +3852,7 @@ and high bound, and a full form that also specifies a bound on the capacity.
<h4>Simple slice expressions</h4> <h4>Simple slice expressions</h4>
<p> <p>
For a string, array, pointer to array, or slice <code>a</code>, the primary expression The primary expression
</p> </p>
<pre> <pre>
@ -3852,7 +3860,9 @@ a[low : high]
</pre> </pre>
<p> <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 <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 in the result. The result has indices starting at 0 and length equal to
<code>high</code>&nbsp;-&nbsp;<code>low</code>. <code>high</code>&nbsp;-&nbsp;<code>low</code>.
@ -3928,7 +3938,7 @@ s2[1] = 42 // s2[1] == s1[2] == a[5] == 42; they all refer to the same under
<h4>Full slice expressions</h4> <h4>Full slice expressions</h4>
<p> <p>
For an array, pointer to array, or slice <code>a</code> (but not a string), the primary expression The primary expression
</p> </p>
<pre> <pre>
@ -3939,6 +3949,8 @@ a[low : high : max]
constructs a slice of the same type, and with the same length and elements as the simple slice 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 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. 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> After slicing the array <code>a</code>
</p> </p>
@ -4044,8 +4056,8 @@ No <a href="#Run_time_panics">run-time panic</a> occurs in this case.
<h3 id="Calls">Calls</h3> <h3 id="Calls">Calls</h3>
<p> <p>
Given an expression <code>f</code> of function type Given an expression <code>f</code> with a <a href="#Core_types">core type</a>
<code>F</code>, <code>F</code> of <a href="#Function_types">function type</a>,
</p> </p>
<pre> <pre>
@ -5148,7 +5160,8 @@ var x *int = nil
<h3 id="Receive_operator">Receive operator</h3> <h3 id="Receive_operator">Receive operator</h3>
<p> <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>&lt;-ch</code> is the value received the value of the receive operation <code>&lt;-ch</code> is the value received
from the channel <code>ch</code>. The channel direction must permit receive operations, 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. and the type of the receive operation is the element type of the channel.
@ -5861,7 +5874,8 @@ len("foo") // illegal if len is the built-in function
<p> <p>
A send statement sends a value on a channel. 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, the channel direction must permit send operations,
and the type of the value to be sent must be <a href="#Assignability">assignable</a> and the type of the value to be sent must be <a href="#Assignability">assignable</a>
to the channel's element type. to the channel's element type.
@ -6407,7 +6421,8 @@ RangeClause = [ ExpressionList "=" | IdentifierList ":=" ] "range" Expression .
<p> <p>
The expression on the right in the "range" clause is called the <i>range expression</i>, 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>. <a href="#Receive_operator">receive operations</a>.
As with an assignment, if present the operands on the left must be As with an assignment, if present the operands on the left must be
<a href="#Address_operators">addressable</a> or map index expressions; they <a href="#Address_operators">addressable</a> or map index expressions; they
@ -6992,9 +7007,10 @@ they cannot be used as function values.
<h3 id="Close">Close</h3> <h3 id="Close">Close</h3>
<p> <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. 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>. 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>. 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 After calling <code>close</code>, and after any previously
@ -7110,24 +7126,25 @@ of the location.
<p> <p>
The built-in function <code>make</code> takes a type <code>T</code>, 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. 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>). It returns a value of type <code>T</code> (not <code>*T</code>).
The memory is initialized as described in the section on The memory is initialized as described in the section on
<a href="#The_zero_value">initial values</a>. <a href="#The_zero_value">initial values</a>.
</p> </p>
<pre class="grammar"> <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) 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, m) slice slice of type T with length n and capacity m
make(T) map map of type T make(T) map map of type T
make(T, n) map map of type T with initial space for approximately n elements 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) channel unbuffered channel of type T
make(T, n) channel buffered channel of type T, buffer size n make(T, n) channel buffered channel of type T, buffer size n
</pre> </pre>
@ -7169,21 +7186,20 @@ by the arguments overlaps.
<p> <p>
The <a href="#Function_types">variadic</a> function <code>append</code> The <a href="#Function_types">variadic</a> function <code>append</code>
appends zero or more values <code>x</code> appends zero or more values <code>x</code> to a slice <code>s</code>
to <code>s</code> of type <code>S</code>, which must be a slice type, and and returns the resulting slice.
returns the resulting slice, also of type <code>S</code>. The <a href="#Core_types">core type</a> of <code>s</code> must be a slice
The values <code>x</code> are passed to a parameter of type <code>...T</code> of the form <code>[]E</code>.
where <code>T</code> is the <a href="#Slice_types">element type</a> of The values <code>x</code> are passed to a parameter of type <code>...E</code>
<code>S</code> and the respective and the respective <a href="#Passing_arguments_to_..._parameters">parameter
<a href="#Passing_arguments_to_..._parameters">parameter passing rules</a> apply. passing rules</a> apply.
As a special case, <code>append</code> also accepts a first argument As a special case, if the core type of <code>s</code> is <code>[]byte</code>,
assignable to type <code>[]byte</code> with a second argument of <code>append</code> also accepts a second argument with core type <code>string</code>
string type followed by <code>...</code>. This form appends the followed by <code>...</code>. This form appends the bytes of the string.
bytes of the string.
</p> </p>
<pre class="grammar"> <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> </pre>
<p> <p>
@ -7211,12 +7227,12 @@ b = append(b, "bar"...) // append string contents b == []byte{'b
The function <code>copy</code> copies slice elements from The function <code>copy</code> copies slice elements from
a source <code>src</code> to a destination <code>dst</code> and returns the a source <code>src</code> to a destination <code>dst</code> and returns the
number of elements copied. number of elements copied.
Both arguments must have <a href="#Type_identity">identical</a> element type <code>T</code> and must be The <a href="#Core_types">core types</a> of both arguments must be slices
<a href="#Assignability">assignable</a> to a slice of type <code>[]T</code>. with <a href="#Type_identity">identical</a> element type.
The number of elements copied is the minimum of The number of elements copied is the minimum of
<code>len(src)</code> and <code>len(dst)</code>. <code>len(src)</code> and <code>len(dst)</code>.
As a special case, <code>copy</code> also accepts a destination argument assignable As a special case, if the destination's core type is <code>[]byte</code>,
to type <code>[]byte</code> with a source argument of a string type. <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. This form copies the bytes from the string into the byte slice.
</p> </p>
@ -7252,6 +7268,12 @@ to the key type of <code>m</code>.
delete(m, k) // remove element m[k] from map m delete(m, k) // remove element m[k] from map m
</pre> </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> <p>
If the map <code>m</code> is <code>nil</code> or the element <code>m[k]</code> 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. does not exist, <code>delete</code> is a no-op.
@ -7260,6 +7282,8 @@ does not exist, <code>delete</code> is a no-op.
<h3 id="Complex_numbers">Manipulating complex numbers</h3> <h3 id="Complex_numbers">Manipulating complex numbers</h3>
<!-- We don't support generic arguments for these operations yet. -->
<p> <p>
Three functions assemble and disassemble complex numbers. Three functions assemble and disassemble complex numbers.
The built-in function <code>complex</code> constructs a complex The built-in function <code>complex</code> constructs a complex