]> Cypherpunks.ru repositories - gostls13.git/commitdiff
spec: adjust rules to use core or specific types as necessary
authorRobert Griesemer <gri@golang.org>
Thu, 10 Feb 2022 04:49:17 +0000 (20:49 -0800)
committerRobert Griesemer <gri@golang.org>
Fri, 11 Feb 2022 00:26:18 +0000 (00:26 +0000)
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>
doc/go_spec.html

index 99bedf2671701ffe4500e38432bc78460d670f6c..c7f93c953dc09ce5f13ebfb193dcb5902a33e7b7 100644 (file)
@@ -1754,6 +1754,12 @@ depending on the direction of the directional channels present.
 </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>
@@ -2994,6 +3000,13 @@ non-<a href="#Blank_identifier">blank</a> identifier denoting a
 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
@@ -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>.
 </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>
@@ -3038,8 +3044,7 @@ math.Sin  // denotes the Sin function in package math
 <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>
@@ -3057,11 +3062,12 @@ Element       = Expression | LiteralValue .
 </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.
@@ -3318,6 +3324,8 @@ f.p[i].x()
 
 <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
@@ -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>
 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>
@@ -3722,7 +3729,8 @@ The following rules apply:
 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>
@@ -3844,7 +3852,7 @@ and high bound, and a full form that also specifies a bound on the capacity.
 <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>
@@ -3852,7 +3860,9 @@ a[low : high]
 </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>&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>
 
 <p>
-For an array, pointer to array, or slice <code>a</code> (but not a string), the primary expression
+The primary expression
 </p>
 
 <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
 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>
 
@@ -4044,8 +4056,8 @@ No <a href="#Run_time_panics">run-time panic</a> occurs in this case.
 <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>
@@ -5148,7 +5160,8 @@ var x *int = nil
 <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>&lt;-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.
@@ -5861,7 +5874,8 @@ len("foo")  // illegal if len is the built-in function
 
 <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.
@@ -6407,7 +6421,8 @@ RangeClause = [ ExpressionList "=" | IdentifierList ":=" ] "range" Expression .
 
 <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
@@ -6992,9 +7007,10 @@ they cannot be used as function values.
 <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
@@ -7110,24 +7126,25 @@ of the location.
 
 <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>
 
 
@@ -7169,21 +7186,20 @@ by the arguments overlaps.
 
 <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>
@@ -7211,12 +7227,12 @@ b = append(b, "bar"...)            // append string contents      b == []byte{'b
 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>
 
@@ -7252,6 +7268,12 @@ to the key type of <code>m</code>.
 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.
@@ -7260,6 +7282,8 @@ 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