[release-branch.go1.18] doc: update go_spec.html with latest changes

Generated at 2022-03-14 14:50 (EDT) with:

	git fetch
	git checkout origin/master -- doc/go_spec.html

This includes spec changes up to CL 391754.

Fixes #51532.

Change-Id: I2c23d764ffa33f24647cd2a4060268c1500f6f99
Reviewed-on: https://go-review.googlesource.com/c/go/+/392674
Trust: Dmitri Shuralyov <dmitshur@golang.org>
Run-TryBot: Dmitri Shuralyov <dmitshur@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Heschi Kreinick <heschi@google.com>
This commit is contained in:
Dmitri Shuralyov 2022-03-14 13:49:14 -04:00
parent 4b9b25a21d
commit 428533fab4

View File

@ -1,26 +1,16 @@
<!--{ <!--{
"Title": "The Go Programming Language Specification - Go 1.18 Draft", "Title": "The Go Programming Language Specification",
"Subtitle": "Version of Feb 28, 2022", "Subtitle": "Version of March 10, 2022",
"Path": "/ref/spec" "Path": "/ref/spec"
}--> }-->
<h2>Earlier version</h2>
<p>
For the pre-Go1.18 specification without generics support see
<a href="/doc/go1.17_spec.html">The Go Programming Language Specification</a>.
</p>
<!-- TODO(gri) remove this before the final release -->
<p><b>
[For reviewers: Sections where we know of missing prose are marked like this. The markers will be removed before the release.]
</b></p>
<h2 id="Introduction">Introduction</h2> <h2 id="Introduction">Introduction</h2>
<p> <p>
This is a reference manual for the Go programming language. For This is the reference manual for the Go programming language.
more information and other documents, see <a href="/">golang.org</a>. The pre-Go1.18 version, without generics, can be found
<a href="/doc/go1.17_spec.html">here</a>.
For more information and other documents, see <a href="/">golang.org</a>.
</p> </p>
<p> <p>
@ -766,7 +756,7 @@ type given in its declaration, the type provided in the
<code>new</code> call or composite literal, or the type of <code>new</code> call or composite literal, or the type of
an element of a structured variable. an element of a structured variable.
Variables of interface type also have a distinct <i>dynamic type</i>, Variables of interface type also have a distinct <i>dynamic type</i>,
which is the concrete type of the value assigned to the variable at run time which is the (non-interface) type of the value assigned to the variable at run time
(unless the value is the predeclared identifier <code>nil</code>, (unless the value is the predeclared identifier <code>nil</code>,
which has no type). which has no type).
The dynamic type may vary during execution but values stored in interface The dynamic type may vary during execution but values stored in interface
@ -812,7 +802,7 @@ TypeLit = ArrayType | StructType | PointerType | FunctionType | InterfaceType
<p> <p>
The language <a href="#Predeclared_identifiers">predeclares</a> certain type names. The language <a href="#Predeclared_identifiers">predeclares</a> certain type names.
Others are introduced with <a href="#Type_declarations">type declarations</a> Others are introduced with <a href="#Type_declarations">type declarations</a>
or <a href="#Type_parameter_lists">type parameter lists</a>. or <a href="#Type_parameter_declarations">type parameter lists</a>.
<i>Composite types</i>&mdash;array, struct, pointer, function, <i>Composite types</i>&mdash;array, struct, pointer, function,
interface, slice, map, and channel types&mdash;may be constructed using interface, slice, map, and channel types&mdash;may be constructed using
type literals. type literals.
@ -987,7 +977,7 @@ built-in function <a href="#Length_and_capacity"><code>cap(a)</code></a>.
</p> </p>
<p> <p>
A new, initialized slice value for a given element type <code>T</code> is A new, initialized slice value for a given element type <code>T</code> may be
made using the built-in function made using the built-in function
<a href="#Making_slices_maps_and_channels"><code>make</code></a>, <a href="#Making_slices_maps_and_channels"><code>make</code></a>,
which takes a slice type which takes a slice type
@ -1422,7 +1412,7 @@ interface {
~int ~int
} }
// An interface representing all types with underlying type int which implement the String method. // An interface representing all types with underlying type int that implement the String method.
interface { interface {
~int ~int
String() string String() string
@ -1455,32 +1445,32 @@ Union elements denote unions of type sets:
</p> </p>
<pre> <pre>
// The Floats interface represents all floating-point types // The Float interface represents all floating-point types
// (including any named types whose underlying types are // (including any named types whose underlying types are
// either float32 or float64). // either float32 or float64).
type Floats interface { type Float interface {
~float32 | ~float64 ~float32 | ~float64
} }
</pre> </pre>
<p> <p>
In a union, a term cannot be a type parameter, and the type sets of all In a union, a term cannot be a <a href="#Type_parameter_declarations">type parameter</a>, and the type sets of all
non-interface terms must be pairwise disjoint (the pairwise intersection of the type sets must be empty). non-interface terms must be pairwise disjoint (the pairwise intersection of the type sets must be empty).
Given a type parameter <code>P</code>: Given a type parameter <code>P</code>:
</p> </p>
<pre> <pre>
interface { interface {
P // illegal: the term P is a type parameter P // illegal: P is a type parameter
int | P // illegal: the term P is a type parameter int | P // illegal: P is a type parameter
~int | MyInt // illegal: the type sets for ~int and MyInt are not disjoint (~int includes MyInt) ~int | MyInt // illegal: the type sets for ~int and MyInt are not disjoint (~int includes MyInt)
float32 | Floats // overlapping type sets but Floats is an interface float32 | Float // overlapping type sets but Float is an interface
} }
</pre> </pre>
<p> <p>
Implementation restriction: Implementation restriction:
A union with more than one term cannot contain the A union (with more than one term) cannot contain the
<a href="#Predeclared_identifiers">predeclared identifier</a> <code>comparable</code> <a href="#Predeclared_identifiers">predeclared identifier</a> <code>comparable</code>
or interfaces that specify methods, or embed <code>comparable</code> or interfaces or interfaces that specify methods, or embed <code>comparable</code> or interfaces
that specify methods. that specify methods.
@ -1494,12 +1484,12 @@ non-interface types.
</p> </p>
<pre> <pre>
var x Floats // illegal: Floats is not a basic interface var x Float // illegal: Float is not a basic interface
var x interface{} = Floats(nil) // illegal var x interface{} = Float(nil) // illegal
type Floatish struct { type Floatish struct {
f Floats // illegal f Float // illegal
} }
</pre> </pre>
@ -1545,7 +1535,7 @@ A type <code>T</code> implements an interface <code>I</code> if
</ul> </ul>
<p> <p>
A value <code>x</code> of type <code>T</code> implements an interface if <code>T</code> A value of type <code>T</code> implements an interface if <code>T</code>
implements the interface. implements the interface.
</p> </p>
@ -1701,10 +1691,9 @@ Each type <code>T</code> has an <i>underlying type</i>: If <code>T</code>
is one of the predeclared boolean, numeric, or string types, or a type literal, is one of the predeclared boolean, numeric, or string types, or a type literal,
the corresponding underlying type is <code>T</code> itself. the corresponding underlying type is <code>T</code> itself.
Otherwise, <code>T</code>'s underlying type is the underlying type of the Otherwise, <code>T</code>'s underlying type is the underlying type of the
type to which <code>T</code> refers in its <a href="#Type_declarations">type type to which <code>T</code> refers in its declaration.
declaration</a>. The underlying type of a type parameter is the For a type parameter that is the underlying type of its
underlying type of its <a href="#Type_constraints">type constraint</a>, which <a href="#Type_constraints">type constraint</a>, which is always an interface.
is always an interface.
</p> </p>
<pre> <pre>
@ -1755,7 +1744,7 @@ direction.
</ol> </ol>
<p> <p>
All other interfaces don't have a core type. No other interfaces have a core type.
</p> </p>
<p> <p>
@ -1775,7 +1764,7 @@ depending on the direction of the directional channels present.
<p> <p>
By definition, a core type is never a <a href="#Type_definitions">defined type</a>, By definition, a core type is never a <a href="#Type_definitions">defined type</a>,
<a href="#Type_parameter_lists">type parameter</a>, or <a href="#Type_parameter_declarations">type parameter</a>, or
<a href="#Interface_types">interface type</a>. <a href="#Interface_types">interface type</a>.
</p> </p>
@ -1795,7 +1784,7 @@ interface{ ~[]*data; String() string } // []*data
</pre> </pre>
<p> <p>
Examples of interfaces whithout core types: Examples of interfaces without core types:
</p> </p>
<pre> <pre>
@ -1805,70 +1794,6 @@ interface{ chan int | chan&lt;- string } // channels have different element
interface{ &lt;-chan int | chan&lt;- int } // directional channels have different directions interface{ &lt;-chan int | chan&lt;- int } // directional channels have different directions
</pre> </pre>
<h3 id="Specific_types">Specific types</h3>
<p><b>
[The definition of specific types is not quite correct yet.]
</b></p>
<p>
An interface specification that contains <a href="#Interface_types">type elements</a>
defines a (possibly empty) set of <i>specific types</i>.
Loosely speaking, these are the types <code>T</code> that appear in the
interface definition in terms of the form <code>T</code>, <code>~T</code>,
or in unions of such terms.
</p>
<p>
More precisely, for a given interface, the set of specific types corresponds to
the set 𝑅 of representative types of the interface, if 𝑅 is non-empty and finite.
Otherwise, if 𝑅 is empty or infinite, the interface has <i>no specific types</i>.
</p>
<p>
For a given interface, type element or type term, the set 𝑅 of representative types is defined as follows:
</p>
<ul>
<li>For an interface with no type elements, 𝑅 is the (infinite) set of all types.
</li>
<li>For an interface with type elements,
𝑅 is the intersection of the representative types of its type elements.
</li>
<li>For a non-interface type term <code>T</code> or a term of the form <code>~T</code>,
𝑅 is the set consisting of the type <code>T</code>.
</li>
<li>For a <i>union</i> of terms
<code>t<sub>1</sub>|t<sub>2</sub>|…|t<sub>n</sub></code>,
𝑅 is the union of the representative types of the terms.
</li>
</ul>
<p>
An interface may have specific types even if its <a href="#Interface_types">type set</a>
is empty.
</p>
<p>
Examples of interfaces with their specific types:
</p>
<pre>
interface{} // no specific types
interface{ int } // int
interface{ ~string } // string
interface{ int|~string } // int, string
interface{ Celsius|Kelvin } // Celsius, Kelvin
interface{ float64|any } // no specific types (union is all types)
interface{ int; m() } // int (but type set is empty because int has no method m)
interface{ ~int; m() } // int (but type set is infinite because many integer types have a method m)
interface{ int; any } // int
interface{ int; string } // no specific types (intersection is empty)
</pre>
<h3 id="Type_identity">Type identity</h3> <h3 id="Type_identity">Type identity</h3>
<p> <p>
@ -1973,21 +1898,21 @@ defined type while the latter is a type literal
<h3 id="Assignability">Assignability</h3> <h3 id="Assignability">Assignability</h3>
<p> <p>
A value <code>x</code> is <i>assignable</i> to a <a href="#Variables">variable</a> of type <code>T</code> A value <code>x</code> of type <code>V</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>") if one of the following conditions applies: ("<code>x</code> is assignable to <code>T</code>") if one of the following conditions applies:
</p> </p>
<ul> <ul>
<li> <li>
<code>x</code>'s type is identical to <code>T</code>. <code>V</code> and <code>T</code> are identical.
</li> </li>
<li> <li>
<code>x</code>'s type <code>V</code> and <code>T</code> have identical <code>V</code> and <code>T</code> have identical
<a href="#Underlying_types">underlying types</a> and at least one of <code>V</code> <a href="#Underlying_types">underlying types</a> and at least one of <code>V</code>
or <code>T</code> is not a <a href="#Types">named type</a>. or <code>T</code> is not a <a href="#Types">named type</a>.
</li> </li>
<li> <li>
<code>x</code>'s type <code>V</code> and <code>T</code> are channel types with <code>V</code> and <code>T</code> are channel types with
identical element types, <code>V</code> is a bidirectional channel, identical element types, <code>V</code> is a bidirectional channel,
and at least one of <code>V</code> or <code>T</code> is not a <a href="#Types">named type</a>. and at least one of <code>V</code> or <code>T</code> is not a <a href="#Types">named type</a>.
</li> </li>
@ -2008,25 +1933,24 @@ by a value of type <code>T</code>.
</ul> </ul>
<p> <p>
Additionally, if <code>x</code>'s type <code>V</code> or <code>T</code> are type parameters Additionally, if <code>x</code>'s type <code>V</code> or <code>T</code> are type parameters, <code>x</code>
with <a href="#Specific_types">specific types</a>, <code>x</code>
is assignable to a variable of type <code>T</code> if one of the following conditions applies: is assignable to a variable of type <code>T</code> if one of the following conditions applies:
</p> </p>
<ul> <ul>
<li> <li>
<code>x</code> is the predeclared identifier <code>nil</code>, <code>T</code> is <code>x</code> is the predeclared identifier <code>nil</code>, <code>T</code> is
a type parameter, and <code>x</code> is assignable to each specific type of a type parameter, and <code>x</code> is assignable to each type in
<code>T</code>. <code>T</code>'s type set.
</li> </li>
<li> <li>
<code>V</code> is not a <a href="#Types">named type</a>, <code>T</code> is <code>V</code> is not a <a href="#Types">named type</a>, <code>T</code> is
a type parameter, and <code>x</code> is assignable to each specific type of a type parameter, and <code>x</code> is assignable to each type in
<code>T</code>. <code>T</code>'s type set.
</li> </li>
<li> <li>
<code>V</code> is a type parameter and <code>T</code> is not a named type, <code>V</code> is a type parameter and <code>T</code> is not a named type,
and values of each specific type of <code>V</code> are assignable and values of each type in <code>V</code>'s type set are assignable
to <code>T</code>. to <code>T</code>.
</li> </li>
</ul> </ul>
@ -2036,7 +1960,7 @@ to <code>T</code>.
<p> <p>
A <a href="#Constants">constant</a> <code>x</code> is <i>representable</i> A <a href="#Constants">constant</a> <code>x</code> is <i>representable</i>
by a value of type <code>T</code>, by a value of type <code>T</code>,
where <code>T</code> is not a <a href="#Type_parameter_lists">type parameter</a>, where <code>T</code> is not a <a href="#Type_parameter_declarations">type parameter</a>,
if one of the following conditions applies: if one of the following conditions applies:
</p> </p>
@ -2061,9 +1985,9 @@ are representable by values of <code>T</code>'s component type (<code>float32</c
</ul> </ul>
<p> <p>
If <code>T</code> is a type parameter with <a href="#Specific_types">specific types</a>, If <code>T</code> is a type parameter,
<code>x</code> is representable by a value of type <code>T</code> if <code>x</code> is representable <code>x</code> is representable by a value of type <code>T</code> if <code>x</code> is representable
by a value of each specific type of <code>T</code>. by a value of each type in <code>T</code>'s type set.
</p> </p>
<pre> <pre>
@ -2176,6 +2100,7 @@ Blocks nest and influence <a href="#Declarations_and_scope">scoping</a>.
A <i>declaration</i> binds a non-<a href="#Blank_identifier">blank</a> identifier to a A <i>declaration</i> binds a non-<a href="#Blank_identifier">blank</a> identifier to a
<a href="#Constant_declarations">constant</a>, <a href="#Constant_declarations">constant</a>,
<a href="#Type_declarations">type</a>, <a href="#Type_declarations">type</a>,
<a href="#Type_parameter_declarations">type parameter</a>,
<a href="#Variable_declarations">variable</a>, <a href="#Variable_declarations">variable</a>,
<a href="#Function_declarations">function</a>, <a href="#Function_declarations">function</a>,
<a href="#Labeled_statements">label</a>, or <a href="#Labeled_statements">label</a>, or
@ -2220,13 +2145,13 @@ Go is lexically scoped using <a href="#Blocks">blocks</a>:
<li>The scope of an identifier denoting a method receiver, function parameter, <li>The scope of an identifier denoting a method receiver, function parameter,
or result variable is the function body.</li> or result variable is the function body.</li>
<li>The scope of an identifier denoting a type parameter of a generic function <li>The scope of an identifier denoting a type parameter of a function
or declared by a method receiver is the function body and all parameter lists of the or declared by a method receiver is the function body and all parameter lists of the
function. function.
</li> </li>
<li>The scope of an identifier denoting a type parameter of a generic type <li>The scope of an identifier denoting a type parameter of a type
begins after the name of the generic type and ends at the end begins after the name of the type and ends at the end
of the TypeSpec.</li> of the TypeSpec.</li>
<li>The scope of a constant or variable identifier declared <li>The scope of a constant or variable identifier declared
@ -2512,7 +2437,7 @@ type (
type TreeNode struct { type TreeNode struct {
left, right *TreeNode left, right *TreeNode
value *Comparable value any
} }
type Block interface { type Block interface {
@ -2573,7 +2498,7 @@ func (tz TimeZone) String() string {
</pre> </pre>
<p> <p>
If the type definition specifies <a href="#Type_parameter_lists">type parameters</a>, If the type definition specifies <a href="#Type_parameter_declarations">type parameters</a>,
the type name denotes a <i>generic type</i>. the type name denotes a <i>generic type</i>.
Generic types must be <a href="#Instantiations">instantiated</a> when they Generic types must be <a href="#Instantiations">instantiated</a> when they
are used. are used.
@ -2584,15 +2509,10 @@ type List[T any] struct {
next *List[T] next *List[T]
value T value T
} }
type Tree[T constraints.Ordered] struct {
left, right *Tree[T]
value T
}
</pre> </pre>
<p> <p>
The given type cannot be a type parameter in a type definition. In a type definition the given type cannot be a type parameter.
</p> </p>
<pre> <pre>
@ -2604,8 +2524,8 @@ func f[T any]() {
</pre> </pre>
<p> <p>
A generic type may also have methods associated with it. In this case, A generic type may also have <a href="#Method_declarations">methods</a> associated with it.
the method receivers must declare the same number of type parameters as In this case, the method receivers must declare the same number of type parameters as
present in the generic type definition. present in the generic type definition.
</p> </p>
@ -2614,7 +2534,7 @@ present in the generic type definition.
func (l *List[T]) Len() int { … } func (l *List[T]) Len() int { … }
</pre> </pre>
<h3 id="Type_parameter_lists">Type parameter lists</h3> <h3 id="Type_parameter_declarations">Type parameter declarations</h3>
<p> <p>
A type parameter list declares the <i>type parameters</i> of a generic function or type declaration. A type parameter list declares the <i>type parameters</i> of a generic function or type declaration.
@ -2653,22 +2573,22 @@ has a corresponding (meta-)type which is called its
<p> <p>
A parsing ambiguity arises when the type parameter list for a generic type A parsing ambiguity arises when the type parameter list for a generic type
declares a single type parameter with a type constraint of the form <code>*C</code> declares a single type parameter <code>P</code> with a constraint <code>C</code>
or <code>(C)</code> where <code>C</code> is not a (possibly parenthesized) such that the text <code>P C</code> forms a valid expression:
<a href="#Types">type literal</a>:
</p> </p>
<pre> <pre>
type T[P *C] … type T[P *C] …
type T[P (C)] … type T[P (C)] …
type T[P *C|Q] …
</pre> </pre>
<p> <p>
In these rare cases, the type parameter declaration is indistinguishable from In these rare cases, the type parameter list is indistinguishable from an
the expressions <code>P*C</code> or <code>P(C)</code> and the type declaration expression and the type declaration is parsed as an array type declaration.
is parsed as an array type declaration. To resolve the ambiguity, embed the constraint in an
To resolve the ambiguity, embed the constraint in an interface or use a trailing <a href="#Interface_types">interface</a> or use a trailing comma:
comma:
</p> </p>
<pre> <pre>
@ -2682,6 +2602,11 @@ of a <a href="#Method_declarations">method declaration</a> associated
with a generic type. with a generic type.
</p> </p>
<!--
This section needs to explain if and what kind of cycles are permitted
using type parameters in a type parameter list.
-->
<h4 id="Type_constraints">Type constraints</h4> <h4 id="Type_constraints">Type constraints</h4>
<p> <p>
@ -2701,10 +2626,10 @@ the enclosing <code>interface{ … }</code> may be omitted for convenience:
</p> </p>
<pre> <pre>
[T *P] // = [T interface{*P}] [T []P] // = [T interface{[]P}]
[T ~int] // = [T interface{~int}] [T ~int] // = [T interface{~int}]
[T int|string] // = [T interface{int|string}] [T int|string] // = [T interface{int|string}]
type Constraint ~int // illegal: ~int is not inside a type parameter list type Constraint ~int // illegal: ~int is not inside a type parameter list
</pre> </pre>
<!-- <!--
@ -2716,7 +2641,7 @@ other interfaces based on their type sets. But this should get us going for now.
<p> <p>
The <a href="#Predeclared_identifiers">predeclared</a> The <a href="#Predeclared_identifiers">predeclared</a>
<a href="#Interface_types">interface type</a> <code>comparable</code> <a href="#Interface_types">interface type</a> <code>comparable</code>
denotes the set of all concrete (non-interface) types that are denotes the set of all non-interface types that are
<a href="#Comparison_operators">comparable</a>. Specifically, <a href="#Comparison_operators">comparable</a>. Specifically,
a type <code>T</code> implements <code>comparable</code> if: a type <code>T</code> implements <code>comparable</code> if:
</p> </p>
@ -2897,14 +2822,14 @@ func IndexRune(s string, r rune) int {
</pre> </pre>
<p> <p>
If the function declaration specifies <a href="#Type_parameter_lists">type parameters</a>, If the function declaration specifies <a href="#Type_parameter_declarations">type parameters</a>,
the function name denotes a <i>generic function</i>. the function name denotes a <i>generic function</i>.
Generic functions must be <a href="#Instantiations">instantiated</a> when they A generic function must be <a href="#Instantiations">instantiated</a> before it can be
are used. called or used as a value.
</p> </p>
<pre> <pre>
func min[T constraints.Ordered](x, y T) T { func min[T ~int|~float64](x, y T) T {
if x &lt; y { if x &lt; y {
return x return x
} }
@ -2963,7 +2888,7 @@ the non-blank method and field names must be distinct.
</p> </p>
<p> <p>
Given defined type <code>Point</code>, the declarations Given defined type <code>Point</code> the declarations
</p> </p>
<pre> <pre>
@ -2987,13 +2912,10 @@ to the base type <code>Point</code>.
If the receiver base type is a <a href="#Type_declarations">generic type</a>, the If the receiver base type is a <a href="#Type_declarations">generic type</a>, the
receiver specification must declare corresponding type parameters for the method receiver specification must declare corresponding type parameters for the method
to use. This makes the receiver type parameters available to the method. to use. This makes the receiver type parameters available to the method.
</p>
<p>
Syntactically, this type parameter declaration looks like an Syntactically, this type parameter declaration looks like an
<a href="#Instantiations">instantiation</a> of the receiver base type, except that <a href="#Instantiations">instantiation</a> of the receiver base type: the type
the type arguments are the type parameters being declared, one for each type parameter arguments must be identifiers denoting the type parameters being declared, one
of the receiver base type. for each type parameter of the receiver base type.
The type parameter names do not need to match their corresponding parameter names in the The type parameter names do not need to match their corresponding parameter names in the
receiver base type definition, and all non-blank parameter names must be unique in the receiver base type definition, and all non-blank parameter names must be unique in the
receiver parameter section and the method signature. receiver parameter section and the method signature.
@ -3007,8 +2929,8 @@ type Pair[A, B any] struct {
b B b B
} }
func (p Pair[A, B]) Swap() Pair[B, A] { return Pair[B, A]{p.b, p.a} } func (p Pair[A, B]) Swap() Pair[B, A] { … } // receiver declares A, B
func (p Pair[First, _]) First() First { return p.a } func (p Pair[First, _]) First() First { … } // receiver declares First, corresponds to A in Pair
</pre> </pre>
<h2 id="Expressions">Expressions</h2> <h2 id="Expressions">Expressions</h2>
@ -3048,6 +2970,14 @@ 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>
<p>
Implementation restriction: A compiler need not report an error if an operand's
type is a <a href="#Type_parameter_declarations">type parameter</a> with an empty
<a href="#Interface_types">type set</a>. Functions with such type parameters
cannot be <a href="#Instantiations">instantiated</a>; any attempt will lead
to an error at the instantiation site.
</p>
<h3 id="Qualified_identifiers">Qualified identifiers</h3> <h3 id="Qualified_identifiers">Qualified identifiers</h3>
<p> <p>
@ -3354,10 +3284,6 @@ f.p[i].x()
<h3 id="Selectors">Selectors</h3> <h3 id="Selectors">Selectors</h3>
<p><b>
[This section is missing rules for x.f where x's type is a type parameter and f is a field.]
</b></p>
<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
@ -3758,7 +3684,7 @@ The following rules apply:
</p> </p>
<p> <p>
If <code>a</code> is not a map: If <code>a</code> is neither a map nor a type parameter:
</p> </p>
<ul> <ul>
<li>the index <code>x</code> must be an untyped constant or its <li>the index <code>x</code> must be an untyped constant or its
@ -3827,23 +3753,22 @@ For <code>a</code> of <a href="#Map_types">map type</a> <code>M</code>:
</ul> </ul>
<p> <p>
For <code>a</code> of <a href="#Type_parameter_lists">type parameter type</a> <code>P</code>: For <code>a</code> of <a href="#Type_parameter_declarations">type parameter type</a> <code>P</code>:
</p> </p>
<ul> <ul>
<li><code>P</code> must have <a href="#Specific_types">specific types</a>.</li>
<li>The index expression <code>a[x]</code> must be valid for values <li>The index expression <code>a[x]</code> must be valid for values
of all specific types of <code>P</code>.</li> of all types in <code>P</code>'s type set.</li>
<li>The element types of all specific types of <code>P</code> must be identical. <li>The element types of all types in <code>P</code>'s type set must be identical.
In this context, the element type of a string type is <code>byte</code>.</li> In this context, the element type of a string type is <code>byte</code>.</li>
<li>If there is a map type among the specific types of <code>P</code>, <li>If there is a map type in the type set of <code>P</code>,
all specific types must be map types, and the respective key types all types in that type set must be map types, and the respective key types
must be all identical.</li> must be all identical.</li>
<li><code>a[x]</code> is the array, slice, or string element at index <code>x</code>, <li><code>a[x]</code> is the array, slice, or string element at index <code>x</code>,
or the map element with key <code>x</code> of the type argument or the map element with key <code>x</code> of the type argument
that <code>P</code> is instantiated with, and the type of <code>a[x]</code> is that <code>P</code> is instantiated with, and the type of <code>a[x]</code> is
the type of the (identical) element types.</li> the type of the (identical) element types.</li>
<li><code>a[x]</code> may not be assigned to if the specific types of <code>P</code> <li><code>a[x]</code> may not be assigned to if <code>P</code>'s type set
include string types. includes string types.
</ul> </ul>
<p> <p>
@ -4021,7 +3946,7 @@ If the indices are out of range at run time, a <a href="#Run_time_panics">run-ti
<p> <p>
For an expression <code>x</code> of <a href="#Interface_types">interface type</a>, For an expression <code>x</code> of <a href="#Interface_types">interface type</a>,
but not a <a href="#Type_parameter_lists">type parameter</a>, and a type <code>T</code>, but not a <a href="#Type_parameter_declarations">type parameter</a>, and a type <code>T</code>,
the primary expression the primary expression
</p> </p>
@ -4236,7 +4161,7 @@ with the same underlying array.
<p> <p>
A generic function or type is <i>instantiated</i> by substituting <i>type arguments</i> A generic function or type is <i>instantiated</i> by substituting <i>type arguments</i>
for the type parameters. for the type parameters.
Instantiation proceeds in two phases: Instantiation proceeds in two steps:
</p> </p>
<ol> <ol>
@ -4249,7 +4174,7 @@ including the type parameter list itself and any types in that list.
<li> <li>
After substitution, each type argument must <a href="#Interface_types">implement</a> After substitution, each type argument must <a href="#Interface_types">implement</a>
the <a href="#Type_parameter_lists">constraint</a> (instantiated, if necessary) the <a href="#Type_parameter_declarations">constraint</a> (instantiated, if necessary)
of the corresponding type parameter. Otherwise instantiation fails. of the corresponding type parameter. Otherwise instantiation fails.
</li> </li>
</ol> </ol>
@ -4262,55 +4187,57 @@ instantiating a function produces a new non-generic function.
<pre> <pre>
type parameter list type arguments after substitution type parameter list type arguments after substitution
[P any] int [int any] [P any] int int implements any
[S ~[]E, E any] []int, int [[]int ~[]int, int any] [S ~[]E, E any] []int, int []int implements ~[]int, int implements any
[P io.Writer] string [string io.Writer] // illegal: string doesn't implement io.Writer [P io.Writer] string illegal: string doesn't implement io.Writer
</pre> </pre>
<p> <p>
Type arguments may be provided explicitly, or they may be partially or completely For a generic function, type arguments may be provided explicitly, or they
<a href="#Type_inference">inferred</a>. may be partially or completely <a href="#Type_inference">inferred</a>.
A partially provided type argument list cannot be empty; there must be at least the A generic function that is is <i>not</i> <a href="#Calls">called</a> requires a
first argument. type argument list for instantiation; if the list is partial, all
</p>
<pre>
type T[P1 ~int, P2 ~[]P1] struct{ … }
T[] // illegal: at least the first type argument must be present, even if it could be inferred
T[int] // argument for P1 explicitly provided, argument for P2 inferred
T[int, []int] // both arguments explicitly provided
</pre>
<p>
A partial type argument list specifies a prefix of the full list of type arguments, leaving
the remaining arguments to be inferred. Loosely speaking, type arguments may be omitted from
"right to left".
</p>
<p>
Generic types, and generic functions that are not <a href="#Calls">called</a>,
require a type argument list for instantiation; if the list is partial, all
remaining type arguments must be inferrable. remaining type arguments must be inferrable.
Calls to generic functions may provide a (possibly partial) type A generic function that is called may provide a (possibly partial) type
argument list, or may omit it entirely if the omitted type arguments are argument list, or may omit it entirely if the omitted type arguments are
inferrable from the ordinary (non-type) function arguments. inferrable from the ordinary (non-type) function arguments.
</p> </p>
<pre> <pre>
func min[T constraints.Ordered](x, y T) T { … } func min[T ~int|~float64](x, y T) T { … }
f := min // illegal: min must be instantiated when used without being called f := min // illegal: min must be instantiated with type arguments when used without being called
minInt := min[int] // minInt has type func(x, y int) int minInt := min[int] // minInt has type func(x, y int) int
a := minInt(2, 3) // a has value 2 of type int a := minInt(2, 3) // a has value 2 of type int
b := min[float64](2.0, 3) // b has value 2.0 of type float64 b := min[float64](2.0, 3) // b has value 2.0 of type float64
c := min(b, -1) // c has value -1.0 of type float64 c := min(b, -1) // c has value -1.0 of type float64
</pre> </pre>
<p>
A partial type argument list cannot be empty; at least the first argument must be present.
The list is a prefix of the full list of type arguments, leaving the remaining arguments
to be inferred. Loosely speaking, type arguments may be omitted from "right to left".
</p>
<pre>
func apply[S ~[]E, E any](s S, f(E) E) S { … }
f0 := apply[] // illegal: type argument list cannot be empty
f1 := apply[[]int] // type argument for S explicitly provided, type argument for E inferred
f2 := apply[[]string, string] // both type arguments explicitly provided
var bytes []byte
r := apply(bytes, func(byte) byte { … }) // both type arguments inferred from the function arguments
</pre>
<p>
For a generic type, all type arguments must always be provided explicitly.
</p>
<h3 id="Type_inference">Type inference</h3> <h3 id="Type_inference">Type inference</h3>
<p> <p>
Missing type arguments may be <i>inferred</i> by a series of steps, described below. Missing function type arguments may be <i>inferred</i> by a series of steps, described below.
Each step attempts to use known information to infer additional type arguments. Each step attempts to use known information to infer additional type arguments.
Type inference stops as soon as all type arguments are known. Type inference stops as soon as all type arguments are known.
After type inference is complete, it is still necessary to substitute all type arguments After type inference is complete, it is still necessary to substitute all type arguments
@ -4326,7 +4253,7 @@ Type inference is based on
<ul> <ul>
<li> <li>
a <a href="#Type_parameter_lists">type parameter list</a> a <a href="#Type_parameter_declarations">type parameter list</a>
</li> </li>
<li> <li>
a substitution map <i>M</i> initialized with the known type arguments, if any a substitution map <i>M</i> initialized with the known type arguments, if any
@ -4491,9 +4418,8 @@ unresolved type parameters left.
</p> </p>
<p> <p>
Function argument type inference can be used when the function has ordinary parameters Inference happens in two separate phases; each phase operates on a specific list of
whose types are defined using the function's type parameters. Inference happens in two (parameter, argument) pairs:
separate phases; each phase operates on a specific list of (parameter, argument) pairs:
</p> </p>
<ol> <ol>
@ -4550,7 +4476,7 @@ Example:
</p> </p>
<pre> <pre>
func min[T constraints.Ordered](x, y T) T func min[T ~int|~float64](x, y T) T
var x int var x int
min(x, 2.0) // T is int, inferred from typed argument x; 2.0 is assignable to int min(x, 2.0) // T is int, inferred from typed argument x; 2.0 is assignable to int
@ -4841,9 +4767,8 @@ The bitwise logical and shift operators apply to integers only.
</pre> </pre>
<p> <p>
Excluding shifts, if the operand type is a <a href="#Type_parameter_lists">type parameter</a>, If the operand type is a <a href="#Type_parameter_declarations">type parameter</a>,
it must have <a href="#Specific_types">specific types</a>, and the operator must the operator must apply to each type in that type set.
apply to each specific type.
The operands are represented as values of the type argument that the type parameter The operands are represented as values of the type argument that the type parameter
is <a href="#Instantiations">instantiated</a> with, and the operation is computed is <a href="#Instantiations">instantiated</a> with, and the operation is computed
with the precision of that type argument. For example, given the function: with the precision of that type argument. For example, given the function:
@ -4866,11 +4791,6 @@ are computed with <code>float32</code> or <code>float64</code> precision,
respectively, depending on the type argument for <code>F</code>. respectively, depending on the type argument for <code>F</code>.
</p> </p>
<p>
For shifts, the <a href="#Core_types">core type</a> of both operands must be
an integer.
</p>
<h4 id="Integer_operators">Integer operators</h4> <h4 id="Integer_operators">Integer operators</h4>
<p> <p>
@ -5296,7 +5216,7 @@ as for non-constant <code>x</code>.
</p> </p>
<p> <p>
Converting a constant to a type that is not a <a href="#Type_parameter_lists">type parameter</a> Converting a constant to a type that is not a <a href="#Type_parameter_declarations">type parameter</a>
yields a typed constant. yields a typed constant.
</p> </p>
@ -5351,7 +5271,7 @@ in any of these cases:
<li> <li>
ignoring struct tags (see below), ignoring struct tags (see below),
<code>x</code>'s type and <code>T</code> are not <code>x</code>'s type and <code>T</code> are not
<a href="#Type_parameter_lists">type parameters</a> but have <a href="#Type_parameter_declarations">type parameters</a> but have
<a href="#Type_identity">identical</a> <a href="#Types">underlying types</a>. <a href="#Type_identity">identical</a> <a href="#Types">underlying types</a>.
</li> </li>
<li> <li>
@ -5383,23 +5303,23 @@ in any of these cases:
<p> <p>
Additionally, if <code>T</code> or <code>x</code>'s type <code>V</code> are type Additionally, if <code>T</code> or <code>x</code>'s type <code>V</code> are type
parameters with <a href="#Specific_types">specific types</a>, <code>x</code> parameters, <code>x</code>
can also be converted to type <code>T</code> if one of the following conditions applies: can also be converted to type <code>T</code> if one of the following conditions applies:
</p> </p>
<ul> <ul>
<li> <li>
Both <code>V</code> and <code>T</code> are type parameters and a value of each Both <code>V</code> and <code>T</code> are type parameters and a value of each
specific type of <code>V</code> can be converted to each specific type type in <code>V</code>'s type set can be converted to each type in <code>T</code>'s
of <code>T</code>. type set.
</li> </li>
<li> <li>
Only <code>V</code> is a type parameter and a value of each Only <code>V</code> is a type parameter and a value of each
specific type of <code>V</code> can be converted to <code>T</code>. type in <code>V</code>'s type set can be converted to <code>T</code>.
</li> </li>
<li> <li>
Only <code>T</code> is a type parameter and <code>x</code> can be converted to each Only <code>T</code> is a type parameter and <code>x</code> can be converted to each
specific type of <code>T</code>. type in <code>T</code>'s type set.
</li> </li>
</ul> </ul>
@ -6270,7 +6190,7 @@ switch x.(type) {
Cases then match actual types <code>T</code> against the dynamic type of the Cases then match actual types <code>T</code> against the dynamic type of the
expression <code>x</code>. As with type assertions, <code>x</code> must be of expression <code>x</code>. As with type assertions, <code>x</code> must be of
<a href="#Interface_types">interface type</a>, but not a <a href="#Interface_types">interface type</a>, but not a
<a href="#Type_parameter_lists">type parameter</a>, and each non-interface type <a href="#Type_parameter_declarations">type parameter</a>, and each non-interface type
<code>T</code> listed in a case must implement the type of <code>x</code>. <code>T</code> listed in a case must implement the type of <code>x</code>.
The types listed in the cases of a type switch must all be The types listed in the cases of a type switch must all be
<a href="#Type_identity">different</a>. <a href="#Type_identity">different</a>.
@ -6352,7 +6272,7 @@ if v == nil {
</pre> </pre>
<p> <p>
A <a href="#Type_parameter_lists">type parameter</a> or a <a href="#Type_declarations">generic type</a> A <a href="#Type_parameter_declarations">type parameter</a> or a <a href="#Type_declarations">generic type</a>
may be used as a type in a case. If upon <a href="#Instantiations">instantiation</a> that type turns may be used as a type in a case. If upon <a href="#Instantiations">instantiation</a> that type turns
out to duplicate another entry in the switch, the first matching case is chosen. out to duplicate another entry in the switch, the first matching case is chosen.
</p> </p>
@ -7093,10 +7013,9 @@ cap(s) [n]T, *[n]T array length (== n)
</pre> </pre>
<p> <p>
If the argument type is a <a href="#Type_parameter_lists">type parameter</a> <code>P</code>, If the argument type is a <a href="#Type_parameter_declarations">type parameter</a> <code>P</code>,
<code>P</code> must have <a href="#Specific_types">specific types</a>, and
the call <code>len(e)</code> (or <code>cap(e)</code> respectively) must be valid for the call <code>len(e)</code> (or <code>cap(e)</code> respectively) must be valid for
each specific type of <code>P</code>. each type in <code>P</code>'s type set.
The result is the length (or capacity, respectively) of the argument whose type The result is the length (or capacity, respectively) of the argument whose type
corresponds to the type argument with which <code>P</code> was corresponds to the type argument with which <code>P</code> was
<a href="#Instantiations">instantiated</a>. <a href="#Instantiations">instantiated</a>.
@ -7197,8 +7116,9 @@ make(T, n) channel buffered channel of type T, buffer size n
<p> <p>
Each of the size arguments <code>n</code> and <code>m</code> must be of <a href="#Numeric_types">integer type</a> Each of the size arguments <code>n</code> and <code>m</code> must be of <a href="#Numeric_types">integer type</a>,
or an untyped <a href="#Constants">constant</a>. have a <a href="#Interface_types">type set</a> containing only integer types,
or be an untyped <a href="#Constants">constant</a>.
A constant size argument must be non-negative and <a href="#Representability">representable</a> A constant size argument must be non-negative and <a href="#Representability">representable</a>
by a value of type <code>int</code>; if it is an untyped constant it is given type <code>int</code>. by a value of type <code>int</code>; if it is an untyped constant it is given type <code>int</code>.
If both <code>n</code> and <code>m</code> are provided and are constant, then If both <code>n</code> and <code>m</code> are provided and are constant, then
@ -7235,9 +7155,9 @@ 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> to a slice <code>s</code> appends zero or more values <code>x</code> to a slice <code>s</code>
and returns the resulting slice. and returns the resulting slice of the same type as <code>s</code>.
The <a href="#Core_types">core type</a> of <code>s</code> must be a slice The <a href="#Core_types">core type</a> of <code>s</code> must be a slice
of the form <code>[]E</code>. of type <code>[]E</code>.
The values <code>x</code> are passed to a parameter of type <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 and the respective <a href="#Passing_arguments_to_..._parameters">parameter
passing rules</a> apply. passing rules</a> apply.
@ -7247,7 +7167,7 @@ followed by <code>...</code>. This form appends the bytes of the string.
</p> </p>
<pre class="grammar"> <pre class="grammar">
append(s S, x ...E) S // E is the element type of the core type of S append(s S, x ...E) S // core type of S is []E
</pre> </pre>
<p> <p>
@ -7317,9 +7237,8 @@ delete(m, k) // remove element m[k] from map m
</pre> </pre>
<p> <p>
If the type of <code>m</code> is a <a href="#Type_parameter_lists">type parameter</a>, If the type of <code>m</code> is a <a href="#Type_parameter_declarations">type parameter</a>,
it must have <a href="#Specific_types">specific types</a>, all specific types all types in that type set must be maps, and they must all have identical key types.
must be maps, and they must all have identical key types.
</p> </p>
<p> <p>
@ -7330,10 +7249,6 @@ 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>
<p><b>
[We don't support generic arguments for these built-ins for Go 1.18.]
</b></p>
<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
@ -7396,6 +7311,10 @@ const c = imag(b) // untyped constant -1.4
_ = imag(3 &lt;&lt; s) // illegal: 3 assumes complex type, cannot shift _ = imag(3 &lt;&lt; s) // illegal: 3 assumes complex type, cannot shift
</pre> </pre>
<p>
Arguments of type parameter type are not permitted.
</p>
<h3 id="Handling_panics">Handling panics</h3> <h3 id="Handling_panics">Handling panics</h3>
<p> Two built-in functions, <code>panic</code> and <code>recover</code>, <p> Two built-in functions, <code>panic</code> and <code>recover</code>,
@ -8004,11 +7923,17 @@ func Add(ptr Pointer, len IntegerType) Pointer
func Slice(ptr *ArbitraryType, len IntegerType) []ArbitraryType func Slice(ptr *ArbitraryType, len IntegerType) []ArbitraryType
</pre> </pre>
<!--
These conversions also apply to type parameters with suitable core types.
Determine if we can simply use core type insted of underlying type here,
of if the general conversion rules take care of this.
-->
<p> <p>
A <code>Pointer</code> is a <a href="#Pointer_types">pointer type</a> but a <code>Pointer</code> A <code>Pointer</code> is a <a href="#Pointer_types">pointer type</a> but a <code>Pointer</code>
value may not be <a href="#Address_operators">dereferenced</a>. value may not be <a href="#Address_operators">dereferenced</a>.
Any pointer or value of <a href="#Types">underlying type</a> <code>uintptr</code> can be converted to Any pointer or value of <a href="#Types">underlying type</a> <code>uintptr</code> can be
a type of underlying type <code>Pointer</code> and vice versa. <a href="#Conversions">converted</a> to a type of underlying type <code>Pointer</code> and vice versa.
The effect of converting between <code>Pointer</code> and <code>uintptr</code> is implementation-defined. The effect of converting between <code>Pointer</code> and <code>uintptr</code> is implementation-defined.
</p> </p>
@ -8055,7 +7980,8 @@ uintptr(unsafe.Pointer(&amp;x)) % unsafe.Alignof(x) == 0
<p> <p>
A (variable of) type <code>T</code> has <i>variable size</i> if <code>T</code> A (variable of) type <code>T</code> has <i>variable size</i> if <code>T</code>
is a type parameter, or if it is an array or struct type containing elements is a <a href="#Type_parameter_declarations">type parameter</a>, or if it is an
array or struct type containing elements
or fields of variable size. Otherwise the size is <i>constant</i>. or fields of variable size. Otherwise the size is <i>constant</i>.
Calls to <code>Alignof</code>, <code>Offsetof</code>, and <code>Sizeof</code> Calls to <code>Alignof</code>, <code>Offsetof</code>, and <code>Sizeof</code>
are compile-time <a href="#Constant_expressions">constant expressions</a> of are compile-time <a href="#Constant_expressions">constant expressions</a> of