<!--{
"Title": "The Go Programming Language Specification",
- "Subtitle": "Version of March 10, 2022",
+ "Subtitle": "Version of Nov 1, 2023",
"Path": "/ref/spec"
}-->
</p>
<p>
-The grammar is compact and simple to parse, allowing for easy analysis
+The syntax is compact and simple to parse, allowing for easy analysis
by automatic tools such as integrated development environments.
</p>
<h2 id="Notation">Notation</h2>
<p>
-The syntax is specified using Extended Backus-Naur Form (EBNF):
+The syntax is specified using a
+<a href="https://en.wikipedia.org/wiki/Wirth_syntax_notation">variant</a>
+of Extended Backus-Naur Form (EBNF):
</p>
<pre class="grammar">
+Syntax = { Production } .
Production = production_name "=" [ Expression ] "." .
-Expression = Alternative { "|" Alternative } .
-Alternative = Term { Term } .
-Term = production_name | token [ "…" token ] | Group | Option | Repetition .
+Expression = Term { "|" Term } .
+Term = Factor { Factor } .
+Factor = production_name | token [ "…" token ] | Group | Option | Repetition .
Group = "(" Expression ")" .
Option = "[" Expression "]" .
Repetition = "{" Expression "}" .
</pre>
<p>
-Lower-case production names are used to identify lexical tokens.
+Lowercase production names are used to identify lexical (terminal) tokens.
Non-terminals are in CamelCase. Lexical tokens are enclosed in
double quotes <code>""</code> or back quotes <code>``</code>.
</p>
in the source text.
</p>
<p>
-Each code point is distinct; for instance, upper and lower case letters
+Each code point is distinct; for instance, uppercase and lowercase letters
are different characters.
</p>
<p>
<h3 id="Characters">Characters</h3>
<p>
-The following terms are used to denote specific Unicode character classes:
+The following terms are used to denote specific Unicode character categories:
</p>
<pre class="ebnf">
newline = /* the Unicode code point U+000A */ .
unicode_char = /* an arbitrary Unicode code point except newline */ .
-unicode_letter = /* a Unicode code point classified as "Letter" */ .
-unicode_digit = /* a Unicode code point classified as "Number, decimal digit" */ .
+unicode_letter = /* a Unicode code point categorized as "Letter" */ .
+unicode_digit = /* a Unicode code point categorized as "Number, decimal digit" */ .
</pre>
<p>
<h3 id="Letters_and_digits">Letters and digits</h3>
<p>
-The underscore character <code>_</code> (U+005F) is considered a letter.
+The underscore character <code>_</code> (U+005F) is considered a lowercase letter.
</p>
<pre class="ebnf">
letter = unicode_letter | "_" .
<h3 id="Semicolons">Semicolons</h3>
<p>
-The formal grammar uses semicolons <code>";"</code> as terminators in
+The formal syntax uses semicolons <code>";"</code> as terminators in
a number of productions. Go programs may omit most of these semicolons
using the following two rules:
</p>
<p>
The following character sequences represent <a href="#Operators">operators</a>
-(including <a href="#Assignments">assignment operators</a>) and punctuation:
+(including <a href="#Assignment_statements">assignment operators</a>) and punctuation:
</p>
<pre class="grammar">
+ & += &= && == != ( )
<a href="#Constants">complex constant</a>.
It consists of an <a href="#Integer_literals">integer</a> or
<a href="#Floating-point_literals">floating-point</a> literal
-followed by the lower-case letter <code>i</code>.
+followed by the lowercase letter <code>i</code>.
The value of an imaginary literal is the value of the respective
integer or floating-point literal multiplied by the imaginary unit <i>i</i>.
</p>
</pre>
<p>
-All other sequences starting with a backslash are illegal inside rune literals.
+An unrecognized character following a backslash in a rune literal is illegal.
</p>
+
<pre class="ebnf">
rune_lit = "'" ( unicode_value | byte_value ) "'" .
unicode_value = unicode_char | little_u_value | big_u_value | escaped_char .
'\U00101234'
'\'' // rune literal containing single quote character
'aa' // illegal: too many characters
+'\k' // illegal: k is not recognized after a backslash
'\xa' // illegal: too few hexadecimal digits
'\0' // illegal: too few octal digits
+'\400' // illegal: octal value over 255
'\uDFFF' // illegal: surrogate half
'\U00110000' // illegal: invalid Unicode code point
</pre>
a <a href="#Constant_expressions">constant expression</a>,
a <a href="#Conversions">conversion</a> with a result that is a constant, or
the result value of some built-in functions such as
+<code>min</code> or <code>max</code> applied to constant arguments,
<code>unsafe.Sizeof</code> applied to <a href="#Package_unsafe">certain values</a>,
<code>cap</code> or <code>len</code> applied to
<a href="#Length_and_capacity">some expressions</a>,
A constant may be given a type explicitly by a <a href="#Constant_declarations">constant declaration</a>
or <a href="#Conversions">conversion</a>, or implicitly when used in a
<a href="#Variable_declarations">variable declaration</a> or an
-<a href="#Assignments">assignment</a> or as an
+<a href="#Assignment_statements">assignment statement</a> or as an
operand in an <a href="#Expressions">expression</a>.
It is an error if the constant value
cannot be <a href="#Representability">represented</a> as a value of the respective type.
for instance, in a <a href="#Short_variable_declarations">short variable declaration</a>
such as <code>i := 0</code> where there is no explicit type.
The default type of an untyped constant is <code>bool</code>, <code>rune</code>,
-<code>int</code>, <code>float64</code>, <code>complex128</code> or <code>string</code>
+<code>int</code>, <code>float64</code>, <code>complex128</code>, or <code>string</code>
respectively, depending on whether it is a boolean, rune, integer, floating-point,
complex, or string constant.
</p>
<p>
A variable's value is retrieved by referring to the variable in an
<a href="#Expressions">expression</a>; it is the most recent value
-<a href="#Assignments">assigned</a> to the variable.
+<a href="#Assignment_statements">assigned</a> to the variable.
If a variable has not yet been assigned a value, its value is the
<a href="#The_zero_value">zero value</a> for its type.
</p>
TypeArgs = "[" TypeList [ "," ] "]" .
TypeList = Type { "," Type } .
TypeLit = ArrayType | StructType | PointerType | FunctionType | InterfaceType |
- SliceType | MapType | ChannelType .
+ SliceType | MapType | ChannelType .
</pre>
<p>
or assignment. For instance, <code>int32</code> and <code>int</code>
are not the same type even though they may have the same size on a
particular architecture.
-
+</p>
<h3 id="String_types">String types</h3>
[2][2][2]float64 // same as [2]([2]([2]float64))
</pre>
+<p>
+An array type <code>T</code> may not have an element of type <code>T</code>,
+or of a type containing <code>T</code> as a component, directly or indirectly,
+if those containing types are only array or struct types.
+</p>
+
+<pre>
+// invalid array types
+type (
+ T1 [10]T1 // element type of T1 is T1
+ T2 [10]struct{ f T2 } // T2 contains T2 as component of a struct
+ T3 [10]T4 // T3 contains T3 as component of a struct in T4
+ T4 struct{ f T3 } // T4 contains T4 as component of array T3 in a struct
+)
+
+// valid array types
+type (
+ T5 [10]*T5 // T5 contains T5 as component of a pointer
+ T6 [10]func() T6 // T6 contains T6 as component of a function type
+ T7 [10]struct{ f []T7 } // T7 contains T7 as component of a slice in a struct
+)
+</pre>
+
<h3 id="Slice_types">Slice types</h3>
<p>
<pre class="ebnf">
StructType = "struct" "{" { FieldDecl ";" } "}" .
FieldDecl = (IdentifierList Type | EmbeddedField) [ Tag ] .
-EmbeddedField = [ "*" ] TypeName .
+EmbeddedField = [ "*" ] TypeName [ TypeArgs ] .
Tag = string_lit .
</pre>
</p>
<p>
-Given a struct type <code>S</code> and a <a href="#Type_definitions">defined type</a>
+Given a struct type <code>S</code> and a <a href="#Types">named type</a>
<code>T</code>, promoted methods are included in the method set of the struct as follows:
</p>
<ul>
}
</pre>
+<p>
+A struct type <code>T</code> may not contain a field of type <code>T</code>,
+or of a type containing <code>T</code> as a component, directly or indirectly,
+if those containing types are only array or struct types.
+</p>
+
+<pre>
+// invalid struct types
+type (
+ T1 struct{ T1 } // T1 contains a field of T1
+ T2 struct{ f [10]T2 } // T2 contains T2 as component of an array
+ T3 struct{ T4 } // T3 contains T3 as component of an array in struct T4
+ T4 struct{ f [10]T3 } // T4 contains T4 as component of struct T3 in an array
+)
+
+// valid struct types
+type (
+ T5 struct{ f *T5 } // T5 contains T5 as component of a pointer
+ T6 struct{ f func() T6 } // T6 contains T6 as component of a function type
+ T7 struct{ f [10][]T7 } // T7 contains T7 as component of a slice in an array
+)
+</pre>
+
<h3 id="Pointer_types">Pointer types</h3>
<p>
<p>
Every type that is a member of the type set of an interface implements that interface.
Any given type may implement several distinct interfaces.
-For instance, all types implement the <i>empty interface</i> which stands for the set of all types:
+For instance, all types implement the <i>empty interface</i> which stands for the set
+of all (non-interface) types:
</p>
<pre>
of its interface elements.
</li>
- <li>The type set of a method specification is the set of types
+ <li>The type set of a method specification is the set of all non-interface types
whose method sets include that method.
</li>
</li>
<li>The type set of a term of the form <code>~T</code>
- is the set of types whose underlying type is <code>T</code>.
+ is the set of all types whose underlying type is <code>T</code>.
</li>
<li>The type set of a <i>union</i> of terms
</li>
</ul>
+<p>
+The quantification "the set of all non-interface types" refers not just to all (non-interface)
+types declared in the program at hand, but all possible types in all possible programs, and
+hence is infinite.
+Similarly, given the set of all non-interface types that implement a particular method, the
+intersection of the method sets of those types will contain exactly that method, even if all
+types in the program at hand always pair that method with another method.
+</p>
+
<p>
By construction, an interface's type set never contains an interface type.
</p>
</pre>
<p>
-In a union, a term cannot be a <a href="#Type_parameter_declarations">type parameter</a>, and the type sets of all
+The type <code>T</code> in a term of the form <code>T</code> or <code>~T</code> 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).
Given a type parameter <code>P</code>:
</p>
<pre>
interface {
P // illegal: P is a type parameter
- int | P // illegal: 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)
float32 | Float // overlapping type sets but Float is an interface
}
</pre>
<p>
-An interface type <code>T</code> may not embed any type element
-that is, contains, or embeds <code>T</code>, recursively.
+An interface type <code>T</code> may not embed a type element
+that is, contains, or embeds <code>T</code>, directly or indirectly.
</p>
<pre>
-// illegal: Bad cannot embed itself
+// illegal: Bad may not embed itself
type Bad interface {
Bad
}
-// illegal: Bad1 cannot embed itself using Bad2
+// illegal: Bad1 may not embed itself using Bad2
type Bad1 interface {
Bad2
}
Bad1
}
-// illegal: Bad3 cannot embed a union containing Bad3
+// illegal: Bad3 may not embed a union containing Bad3
type Bad3 interface {
~int | ~string | Bad3
}
+
+// illegal: Bad4 may not embed an array containing Bad4 as element type
+type Bad4 interface {
+ [10]Bad4
+}
</pre>
<h4 id="Implementing_an_interface">Implementing an interface</h4>
For a map <code>m</code>, it can be discovered using the
built-in function <a href="#Length_and_capacity"><code>len</code></a>
and may change during execution. Elements may be added during execution
-using <a href="#Assignments">assignments</a> and retrieved with
+using <a href="#Assignment_statements">assignments</a> and retrieved with
<a href="#Index_expressions">index expressions</a>; they may be removed with the
-<a href="#Deletion_of_map_elements"><code>delete</code></a> built-in function.
+<a href="#Deletion_of_map_elements"><code>delete</code></a> and
+<a href="#Clear"><code>clear</code></a> built-in function.
</p>
+
<p>
A new, empty map value is made using the built-in
function <a href="#Making_slices_maps_and_channels"><code>make</code></a>,
<i>send</i> or <i>receive</i>. If a direction is given, the channel is <i>directional</i>,
otherwise it is <i>bidirectional</i>.
A channel may be constrained only to send or only to receive by
-<a href="#Assignments">assignment</a> or
+<a href="#Assignment_statements">assignment</a> or
explicit <a href="#Conversions">conversion</a>.
</p>
interface{ <-chan int | chan<- int } // directional channels have different directions
</pre>
+<p>
+Some operations (<a href="#Slice_expressions">slice expressions</a>,
+<a href="#Appending_and_copying_slices"><code>append</code> and <code>copy</code></a>)
+rely on a slightly more loose form of core types which accept byte slices and strings.
+Specifically, if there are exactly two types, <code>[]byte</code> and <code>string</code>,
+which are the underlying types of all types in the type set of interface <code>T</code>,
+the core type of <code>T</code> is called <code>bytestring</code>.
+</p>
+
+<p>
+Examples of interfaces with <code>bytestring</code> core types:
+</p>
+
+<pre>
+interface{ int } // int (same as ordinary core type)
+interface{ []byte | string } // bytestring
+interface{ ~[]byte | myString } // bytestring
+</pre>
+
+<p>
+Note that <code>bytestring</code> is not a real type; it cannot be used to declare
+variables or compose other types. It exists solely to describe the behavior of some
+operations that read from a sequence of bytes, which may be a byte slice or a string.
+</p>
+
<h3 id="Type_identity">Type identity</h3>
<p>
B0 and C0
D0[int, string] and E0
[]int and []int
-struct{ a, b *T5 } and struct{ a, b *T5 }
+struct{ a, b *B5 } and struct{ a, b *B5 }
func(x int, y float64) *[]string, func(int, float64) (result *[]string), and A5
</pre>
</li>
<li>
<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>
+but are not type parameters and at least one of <code>V</code>
or <code>T</code> is not a <a href="#Types">named type</a>.
</li>
<li>
or result variable is the function body.</li>
<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
- function.
- </li>
+ or declared by a method receiver begins after the name of the function
+ and ends at the end of the function body.</li>
<li>The scope of an identifier denoting a type parameter of a type
begins after the name of the type and ends at the end
The <i>blank identifier</i> is represented by the underscore character <code>_</code>.
It serves as an anonymous placeholder instead of a regular (non-blank)
identifier and has special meaning in <a href="#Declarations_and_scope">declarations</a>,
-as an <a href="#Operands">operand</a>, and in <a href="#Assignments">assignments</a>.
+as an <a href="#Operands">operand</a>, and in <a href="#Assignment_statements">assignment statements</a>.
</p>
nil
Functions:
- append cap close complex copy delete imag len
- make new panic print println real recover
+ append cap clear close complex copy delete imag len
+ make max min new panic print println real recover
</pre>
<h3 id="Exported_identifiers">Exported identifiers</h3>
An identifier is exported if both:
</p>
<ol>
- <li>the first character of the identifier's name is a Unicode upper case
- letter (Unicode class "Lu"); and</li>
+ <li>the first character of the identifier's name is a Unicode uppercase
+ letter (Unicode character category Lu); and</li>
<li>the identifier is declared in the <a href="#Blocks">package block</a>
or it is a <a href="#Struct_types">field name</a> or
<a href="#MethodName">method name</a>.</li>
<p>
A type definition creates a new, distinct type with the same
-<a href="#Types">underlying type</a> and operations as the given type
+<a href="#Underlying_types">underlying type</a> and operations as the given type
and binds an identifier, the <i>type name</i>, to it.
</p>
<p>
All non-blank names in the list must be unique.
Each name declares a type parameter, which is a new and different <a href="#Types">named type</a>
-that acts as a place holder for an (as of yet) unknown type in the declaration.
+that acts as a placeholder for an (as of yet) unknown type in the declaration.
The type parameter is replaced with a <i>type argument</i> upon
<a href="#Instantiations">instantiation</a> of the generic function or type.
</p>
with a generic type.
</p>
-<!--
-This section needs to explain if and what kind of cycles are permitted
-using type parameters in a type parameter list.
--->
+<p>
+Within a type parameter list of a generic type <code>T</code>, a type constraint
+may not (directly, or indirectly through the type parameter list of another
+generic type) refer to <code>T</code>.
+</p>
+
+<pre>
+type T1[P T1[P]] … // illegal: T1 refers to itself
+type T2[P interface{ T2[int] }] … // illegal: T2 refers to itself
+type T3[P interface{ m(T3[int])}] … // illegal: T3 refers to itself
+type T4[P T5[P]] … // illegal: T4 refers to T5 and
+type T5[P T4[P]] … // T5 refers to T4
+
+type T6[P int] struct{ f *T6[P] } // ok: reference to T6 is not in type parameter list
+</pre>
<h4 id="Type_constraints">Type constraints</h4>
<p>
-A type constraint is an <a href="#Interface_types">interface</a> that defines the
+A <i>type constraint</i> is an <a href="#Interface_types">interface</a> that defines the
set of permissible type arguments for the respective type parameter and controls the
operations supported by values of that type parameter.
</p>
<p>
If the constraint is an interface literal of the form <code>interface{E}</code> where
-<code>E</code> is an embedded type element (not a method), in a type parameter list
+<code>E</code> is an embedded <a href="#Interface_types">type element</a> (not a method), in a type parameter list
the enclosing <code>interface{ … }</code> may be omitted for convenience:
</p>
[T []P] // = [T interface{[]P}]
[T ~int] // = [T interface{~int}]
[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 in a type parameter list
</pre>
<!--
The <a href="#Predeclared_identifiers">predeclared</a>
<a href="#Interface_types">interface type</a> <code>comparable</code>
denotes the set of all non-interface types that are
-<a href="#Comparison_operators">comparable</a>. Specifically,
-a type <code>T</code> implements <code>comparable</code> if:
+<a href="#Comparison_operators">strictly comparable</a>.
</p>
-<ul>
-<li>
- <code>T</code> is not an interface type and <code>T</code> supports the operations
- <code>==</code> and <code>!=</code>; or
-</li>
-<li>
- <code>T</code> is an interface type and each type in <code>T</code>'s
- <a href="#Interface_types">type set</a> implements <code>comparable</code>.
-</li>
-</ul>
-
<p>
-Even though interfaces that are not type parameters can be
-<a href="#Comparison_operators">compared</a>
-(possibly causing a run-time panic) they do not implement
-<code>comparable</code>.
+Even though interfaces that are not type parameters are <a href="#Comparison_operators">comparable</a>,
+they are not strictly comparable and therefore they do not implement <code>comparable</code>.
+However, they <a href="#Satisfying_a_type_constraint">satisfy</a> <code>comparable</code>.
</p>
<pre>
-int // implements comparable
+int // implements comparable (int is strictly comparable)
[]byte // does not implement comparable (slices cannot be compared)
interface{} // does not implement comparable (see above)
-interface{ ~int | ~string } // type parameter only: implements comparable
-interface{ comparable } // type parameter only: implements comparable
-interface{ ~int | ~[]byte } // type parameter only: does not implement comparable (not all types in the type set are comparable)
+interface{ ~int | ~string } // type parameter only: implements comparable (int, string types are strictly comparable)
+interface{ comparable } // type parameter only: implements comparable (comparable implements itself)
+interface{ ~int | ~[]byte } // type parameter only: does not implement comparable (slices are not comparable)
+interface{ ~struct{ any } } // type parameter only: does not implement comparable (field any is not strictly comparable)
</pre>
<p>
values or variables, or components of other, non-interface types.
</p>
+<h4 id="Satisfying_a_type_constraint">Satisfying a type constraint</h4>
+
+<p>
+A type argument <code>T</code><i> satisfies</i> a type constraint <code>C</code>
+if <code>T</code> is an element of the type set defined by <code>C</code>; i.e.,
+if <code>T</code> <a href="#Implementing_an_interface">implements</a> <code>C</code>.
+As an exception, a <a href="#Comparison_operators">strictly comparable</a>
+type constraint may also be satisfied by a <a href="#Comparison_operators">comparable</a>
+(not necessarily strictly comparable) type argument.
+More precisely:
+</p>
+
+<p>
+A type T <i>satisfies</i> a constraint <code>C</code> if
+</p>
+
+<ul>
+<li>
+ <code>T</code> <a href="#Implementing_an_interface">implements</a> <code>C</code>; or
+</li>
+<li>
+ <code>C</code> can be written in the form <code>interface{ comparable; E }</code>,
+ where <code>E</code> is a <a href="#Basic_interfaces">basic interface</a> and
+ <code>T</code> is <a href="#Comparison_operators">comparable</a> and implements <code>E</code>.
+</li>
+</ul>
+
+<pre>
+type argument type constraint // constraint satisfaction
+
+int interface{ ~int } // satisfied: int implements interface{ ~int }
+string comparable // satisfied: string implements comparable (string is strictly comparable)
+[]byte comparable // not satisfied: slices are not comparable
+any interface{ comparable; int } // not satisfied: any does not implement interface{ int }
+any comparable // satisfied: any is comparable and implements the basic interface any
+struct{f any} comparable // satisfied: struct{f any} is comparable and implements the basic interface any
+any interface{ comparable; m() } // not satisfied: any does not implement the basic interface interface{ m() }
+interface{ m() } interface{ comparable; m() } // satisfied: interface{ m() } is comparable and implements the basic interface interface{ m() }
+</pre>
+
+<p>
+Because of the exception in the constraint satisfaction rule, comparing operands of type parameter type
+may panic at run-time (even though comparable type parameters are always strictly comparable).
+</p>
+
<h3 id="Variable_declarations">Variable declarations</h3>
<p>
<p>
If a list of expressions is given, the variables are initialized
-with the expressions following the rules for <a href="#Assignments">assignments</a>.
+with the expressions following the rules for <a href="#Assignment_statements">assignment statements</a>.
Otherwise, each variable is initialized to its <a href="#The_zero_value">zero value</a>.
</p>
</p>
<pre class="grammar">
-"var" IdentifierList = ExpressionList .
+"var" IdentifierList "=" ExpressionList .
</pre>
<pre>
and at least one of the non-<a href="#Blank_identifier">blank</a> variables is new.
As a consequence, redeclaration can only appear in a multi-variable short declaration.
Redeclaration does not introduce a new variable; it just assigns a new value to the original.
+The non-blank variable names on the left side of <code>:=</code>
+must be <a href="#Uniqueness_of_identifiers">unique</a>.
</p>
<pre>
field1, offset := nextField(str, 0)
field2, offset := nextField(str, offset) // redeclares offset
-a, a := 1, 2 // illegal: double declaration of a or no new variable if a was declared elsewhere
+x, y, x := 1, 2, 3 // illegal: x repeated on left side of :=
</pre>
<p>
<p>
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="#Assignment_statements">assignment statement</a>.
</p>
<p>
</p>
<pre>
-math.Sin // denotes the Sin function in package math
+math.Sin // denotes the Sin function in package math
</pre>
<h3 id="Composite_literals">Composite literals</h3>
<pre class="ebnf">
CompositeLit = LiteralType LiteralValue .
LiteralType = StructType | ArrayType | "[" "..." "]" ElementType |
- SliceType | MapType | TypeName .
+ SliceType | MapType | TypeName [ TypeArgs ] .
LiteralValue = "{" [ ElementList [ "," ] ] "}" .
ElementList = KeyedElement { "," KeyedElement } .
KeyedElement = [ Key ":" ] Element .
<p>
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 syntax 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 type <code>T</code>;
PrimaryExpr Arguments .
Selector = "." identifier .
-Index = "[" Expression "]" .
+Index = "[" Expression [ "," ] "]" .
Slice = "[" [ Expression ] ":" [ Expression ] "]" |
"[" [ Expression ] ":" Expression ":" Expression "]" .
TypeAssertion = "." "(" Type ")" .
that <code>P</code> is instantiated with, and the type of <code>a[x]</code> is
the type of the (identical) element types.</li>
<li><code>a[x]</code> may not be assigned to if <code>P</code>'s type set
- includes string types.
+ includes string types.</li>
</ul>
<p>
<p>
An index expression on a map <code>a</code> of type <code>map[K]V</code>
-used in an <a href="#Assignments">assignment</a> or initialization of the special form
+used in an <a href="#Assignment_statements">assignment statement</a> or initialization of the special form
</p>
<pre>
<p>
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.
+<code>a</code> must be a string, array, pointer to array, slice, or a
+<a href="#Core_types"><code>bytestring</code></a>.
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
s1 := a[3:7] // underlying array of s1 is array a; &s1[2] == &a[5]
s2 := s1[1:4] // underlying array of s2 is underlying array of s1 which is array a; &s2[1] == &a[5]
s2[1] = 42 // s2[1] == s1[2] == a[5] == 42; they all refer to the same underlying array element
+
+var s []int
+s3 := s[:0] // s3 == nil
</pre>
</pre>
<p>
-A type assertion used in an <a href="#Assignments">assignment</a> or initialization of the special form
+A type assertion used in an <a href="#Assignment_statements">assignment statement</a> or initialization of the special form
</p>
<pre>
</li>
<li>
-After substitution, each type argument must <a href="#Interface_types">implement</a>
+After substitution, each type argument must <a href="#Satisfying_a_type_constraint">satisfy</a>
the <a href="#Type_parameter_declarations">constraint</a> (instantiated, if necessary)
of the corresponding type parameter. Otherwise instantiation fails.
</li>
<pre>
type parameter list type arguments after substitution
-[P any] int int implements any
-[S ~[]E, E any] []int, int []int implements ~[]int, int implements any
-[P io.Writer] string illegal: string doesn't implement io.Writer
+[P any] int int satisfies any
+[S ~[]E, E any] []int, int []int satisfies ~[]int, int satisfies any
+[P io.Writer] string illegal: string doesn't satisfy io.Writer
+[P comparable] any any satisfies (but does not implement) comparable
</pre>
<p>
-For a generic function, type arguments may be provided explicitly, or they
-may be partially or completely <a href="#Type_inference">inferred</a>.
-A generic function that is is <i>not</i> <a href="#Calls">called</a> requires a
-type argument list for instantiation; if the list is partial, all
-remaining type arguments must be inferrable.
-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
-inferrable from the ordinary (non-type) function arguments.
+When using a generic function, type arguments may be provided explicitly,
+or they may be partially or completely <a href="#Type_inference">inferred</a>
+from the context in which the function is used.
+Provided that they can be inferred, type argument lists may be omitted entirely if the function is:
+</p>
+
+<ul>
+<li>
+ <a href="#Calls">called</a> with ordinary arguments,
+</li>
+<li>
+ <a href="#Assignment_statements">assigned</a> to a variable with a known type
+</li>
+<li>
+ <a href="#Calls">passed as an argument</a> to another function, or
+</li>
+<li>
+ <a href="#Return_statements">returned as a result</a>.
+</li>
+</ul>
+
+<p>
+In all other cases, a (possibly partial) type argument list must be present.
+If a type argument list is absent or partial, all missing type arguments
+must be inferrable from the context in which the function is used.
</p>
<pre>
-func min[T ~int|~float64](x, y T) T { … }
+// sum returns the sum (concatenation, for strings) of its arguments.
+func sum[T ~int | ~float64 | ~string](x... T) T { … }
-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
-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
-c := min(b, -1) // c has value -1.0 of type float64
+x := sum // illegal: the type of x is unknown
+intSum := sum[int] // intSum has type func(x... int) int
+a := intSum(2, 3) // a has value 5 of type int
+b := sum[float64](2.0, 3) // b has value 5.0 of type float64
+c := sum(b, -1) // c has value 4.0 of type float64
+
+type sumFunc func(x... string) string
+var f sumFunc = sum // same as var f sumFunc = sum[string]
+f = sum // same as f = sum[string]
</pre>
<p>
</p>
<pre>
-func apply[S ~[]E, E any](s S, f(E) E) S { … }
+func apply[S ~[]E, E any](s S, f func(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
<h3 id="Type_inference">Type inference</h3>
<p>
-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.
-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
-for type parameters and verify that each type argument
-<a href="#Implementing_an_interface">implements</a> the relevant constraint;
-it is possible for an inferred type argument to fail to implement a constraint, in which
-case instantiation fails.
-</p>
-
-<p>
-Type inference is based on
-</p>
-
-<ul>
-<li>
- a <a href="#Type_parameter_declarations">type parameter list</a>
-</li>
-<li>
- a substitution map <i>M</i> initialized with the known type arguments, if any
-</li>
-<li>
- a (possibly empty) list of ordinary function arguments (in case of a function call only)
-</li>
-</ul>
-
-<p>
-and then proceeds with the following steps:
-</p>
-
-<ol>
-<li>
- apply <a href="#Function_argument_type_inference"><i>function argument type inference</i></a>
- to all <i>typed</i> ordinary function arguments
-</li>
-<li>
- apply <a href="#Constraint_type_inference"><i>constraint type inference</i></a>
-</li>
-<li>
- apply function argument type inference to all <i>untyped</i> ordinary function arguments
- using the default type for each of the untyped function arguments
-</li>
-<li>
- apply constraint type inference
-</li>
-</ol>
-
-<p>
-If there are no ordinary or untyped function arguments, the respective steps are skipped.
-Constraint type inference is skipped if the previous step didn't infer any new type arguments,
-but it is run at least once if there are missing type arguments.
-</p>
-
-<p>
-The substitution map <i>M</i> is carried through all steps, and each step may add entries to <i>M</i>.
-The process stops as soon as <i>M</i> has a type argument for each type parameter or if an inference step fails.
-If an inference step fails, or if <i>M</i> is still missing type arguments after the last step, type inference fails.
-</p>
-
-<h4 id="Type_unification">Type unification</h4>
-
-<p>
-Type inference is based on <i>type unification</i>. A single unification step
-applies to a <a href="#Type_inference">substitution map</a> and two types, either
-or both of which may be or contain type parameters. The substitution map tracks
-the known (explicitly provided or already inferred) type arguments: the map
-contains an entry <code>P</code> → <code>A</code> for each type
-parameter <code>P</code> and corresponding known type argument <code>A</code>.
-During unification, known type arguments take the place of their corresponding type
-parameters when comparing types. Unification is the process of finding substitution
-map entries that make the two types equivalent.
-</p>
-
-<p>
-For unification, two types that don't contain any type parameters from the current type
-parameter list are <i>equivalent</i>
-if they are identical, or if they are channel types that are identical ignoring channel
-direction, or if their underlying types are equivalent.
+A use of a generic function may omit some or all type arguments if they can be
+<i>inferred</i> from the context within which the function is used, including
+the constraints of the function's type parameters.
+Type inference succeeds if it can infer the missing type arguments
+and <a href="#Instantiations">instantiation</a> succeeds with the
+inferred type arguments.
+Otherwise, type inference fails and the program is invalid.
</p>
<p>
-Unification works by comparing the structure of pairs of types: their structure
-disregarding type parameters must be identical, and types other than type parameters
-must be equivalent.
-A type parameter in one type may match any complete subtype in the other type;
-each successful match causes an entry to be added to the substitution map.
-If the structure differs, or types other than type parameters are not equivalent,
-unification fails.
+Type inference uses the type relationships between pairs of types for inference:
+For instance, a function argument must be <a href="#Assignability">assignable</a>
+to its respective function parameter; this establishes a relationship between the
+type of the argument and the type of the parameter.
+If either of these two types contains type parameters, type inference looks for the
+type arguments to substitute the type parameters with such that the assignability
+relationship is satisfied.
+Similarly, type inference uses the fact that a type argument must
+<a href="#Satisfying_a_type_constraint">satisfy</a> the constraint of its respective
+type parameter.
</p>
-<!--
-TODO(gri) Somewhere we need to describe the process of adding an entry to the
- substitution map: if the entry is already present, the type argument
- values are themselves unified.
--->
-
<p>
-For example, if <code>T1</code> and <code>T2</code> are type parameters,
-<code>[]map[int]bool</code> can be unified with any of the following:
+Each such pair of matched types corresponds to a <i>type equation</i> containing
+one or multiple type parameters, from one or possibly multiple generic functions.
+Inferring the missing type arguments means solving the resulting set of type
+equations for the respective type parameters.
</p>
-<pre>
-[]map[int]bool // types are identical
-T1 // adds T1 → []map[int]bool to substitution map
-[]T1 // adds T1 → map[int]bool to substitution map
-[]map[T1]T2 // adds T1 → int and T2 → bool to substitution map
-</pre>
-
<p>
-On the other hand, <code>[]map[int]bool</code> cannot be unified with any of
+For example, given
</p>
<pre>
-int // int is not a slice
-struct{} // a struct is not a slice
-[]struct{} // a struct is not a map
-[]map[T1]string // map element types don't match
-</pre>
+// dedup returns a copy of the argument slice with any duplicate entries removed.
+func dedup[S ~[]E, E comparable](S) S { … }
-<p>
-As an exception to this general rule, because a <a href="#Type_definitions">defined type</a>
-<code>D</code> and a type literal <code>L</code> are never equivalent,
-unification compares the underlying type of <code>D</code> with <code>L</code> instead.
-For example, given the defined type
-</p>
-
-<pre>
-type Vector []float64
+type Slice []int
+var s Slice
+s = dedup(s) // same as s = dedup[Slice, int](s)
</pre>
<p>
-and the type literal <code>[]E</code>, unification compares <code>[]float64</code> with
-<code>[]E</code> and adds an entry <code>E</code> → <code>float64</code> to
-the substitution map.
-</p>
-
-<h4 id="Function_argument_type_inference">Function argument type inference</h4>
-
-<!-- In this section and the section on constraint type inference we start with examples
-rather than have the examples follow the rules as is customary elsewhere in spec.
-Hopefully this helps building an intuition and makes the rules easier to follow. -->
-
-<p>
-Function argument type inference infers type arguments from function arguments:
-if a function parameter is declared with a type <code>T</code> that uses
-type parameters,
-<a href="#Type_unification">unifying</a> the type of the corresponding
-function argument with <code>T</code> may infer type arguments for the type
-parameters used by <code>T</code>.
-</p>
-
-<p>
-For instance, given the generic function
+the variable <code>s</code> of type <code>Slice</code> must be assignable to
+the function parameter type <code>S</code> for the program to be valid.
+To reduce complexity, type inference ignores the directionality of assignments,
+so the type relationship between <code>Slice</code> and <code>S</code> can be
+expressed via the (symmetric) type equation <code>Slice ≡<sub>A</sub> S</code>
+(or <code>S ≡<sub>A</sub> Slice</code> for that matter),
+where the <code><sub>A</sub></code> in <code>≡<sub>A</sub></code>
+indicates that the LHS and RHS types must match per assignability rules
+(see the section on <a href="#Type_unification">type unification</a> for
+details).
+Similarly, the type parameter <code>S</code> must satisfy its constraint
+<code>~[]E</code>. This can be expressed as <code>S ≡<sub>C</sub> ~[]E</code>
+where <code>X ≡<sub>C</sub> Y</code> stands for
+"<code>X</code> satisfies constraint <code>Y</code>".
+These observations lead to a set of two equations
</p>
<pre>
-func scale[Number ~int64|~float64|~complex128](v []Number, s Number) []Number
+ Slice ≡<sub>A</sub> S (1)
+ S ≡<sub>C</sub> ~[]E (2)
</pre>
<p>
-and the call
+which now can be solved for the type parameters <code>S</code> and <code>E</code>.
+From (1) a compiler can infer that the type argument for <code>S</code> is <code>Slice</code>.
+Similarly, because the underlying type of <code>Slice</code> is <code>[]int</code>
+and <code>[]int</code> must match <code>[]E</code> of the constraint,
+a compiler can infer that <code>E</code> must be <code>int</code>.
+Thus, for these two equations, type inference infers
</p>
<pre>
-var vector []float64
-scaledVector := scale(vector, 42)
+ S ➞ Slice
+ E ➞ int
</pre>
<p>
-the type argument for <code>Number</code> can be inferred from the function argument
-<code>vector</code> by unifying the type of <code>vector</code> with the corresponding
-parameter type: <code>[]float64</code> and <code>[]Number</code>
-match in structure and <code>float64</code> matches with <code>Number</code>.
-This adds the entry <code>Number</code> → <code>float64</code> to the
-<a href="#Type_unification">substitution map</a>.
-Untyped arguments, such as the second function argument <code>42</code> here, are ignored
-in the first round of function argument type inference and only considered if there are
-unresolved type parameters left.
+Given a set of type equations, the type parameters to solve for are
+the type parameters of the functions that need to be instantiated
+and for which no explicit type arguments is provided.
+These type parameters are called <i>bound</i> type parameters.
+For instance, in the <code>dedup</code> example above, the type parameters
+<code>S</code> and <code>E</code> are bound to <code>dedup</code>.
+An argument to a generic function call may be a generic function itself.
+The type parameters of that function are included in the set of bound
+type parameters.
+The types of function arguments may contain type parameters from other
+functions (such as a generic function enclosing a function call).
+Those type parameters may also appear in type equations but they are
+not bound in that context.
+Type equations are always solved for the bound type parameters only.
</p>
<p>
-Inference happens in two separate phases; each phase operates on a specific list of
-(parameter, argument) pairs:
+Type inference supports calls of generic functions and assignments
+of generic functions to (explicitly function-typed) variables.
+This includes passing generic functions as arguments to other
+(possibly also generic) functions, and returning generic functions
+as results.
+Type inference operates on a set of equations specific to each of
+these cases.
+The equations are as follows (type argument lists are omitted for clarity):
</p>
-<ol>
+<ul>
<li>
- The list <i>Lt</i> contains all (parameter, argument) pairs where the parameter
- type uses type parameters and where the function argument is <i>typed</i>.
+ <p>
+ For a function call <code>f(a<sub>0</sub>, a<sub>1</sub>, …)</code> where
+ <code>f</code> or a function argument <code>a<sub>i</sub></code> is
+ a generic function:
+ <br>
+ Each pair <code>(a<sub>i</sub>, p<sub>i</sub>)</code> of corresponding
+ function arguments and parameters where <code>a<sub>i</sub></code> is not an
+ <a href="#Constants">untyped constant</a> yields an equation
+ <code>typeof(p<sub>i</sub>) ≡<sub>A</sub> typeof(a<sub>i</sub>)</code>.
+ <br>
+ If <code>a<sub>i</sub></code> is an untyped constant <code>c<sub>j</sub></code>,
+ and <code>typeof(p<sub>i</sub>)</code> is a bound type parameter <code>P<sub>k</sub></code>,
+ the pair <code>(c<sub>j</sub>, P<sub>k</sub>)</code> is collected separately from
+ the type equations.
+ </p>
</li>
<li>
- The list <i>Lu</i> contains all remaining pairs where the parameter type is a single
- type parameter. In this list, the respective function arguments are untyped.
+ <p>
+ For an assignment <code>v = f</code> of a generic function <code>f</code> to a
+ (non-generic) variable <code>v</code> of function type:
+ <br>
+ <code>typeof(v) ≡<sub>A</sub> typeof(f)</code>.
+ </p>
</li>
-</ol>
-
-<p>
-Any other (parameter, argument) pair is ignored.
-</p>
+<li>
+ <p>
+ For a return statement <code>return …, f, … </code> where <code>f</code> is a
+ generic function returned as a result to a (non-generic) result variable
+ <code>r</code> of function type:
+ <br>
+ <code>typeof(r) ≡<sub>A</sub> typeof(f)</code>.
+ </p>
+</li>
+</ul>
<p>
-By construction, the arguments of the pairs in <i>Lu</i> are <i>untyped</i> constants
-(or the untyped boolean result of a comparison). And because <a href="#Constants">default types</a>
-of untyped values are always predeclared non-composite types, they can never match against
-a composite type, so it is sufficient to only consider parameter types that are single type
-parameters.
+Additionally, each type parameter <code>P<sub>k</sub></code> and corresponding type constraint
+<code>C<sub>k</sub></code> yields the type equation
+<code>P<sub>k</sub> ≡<sub>C</sub> C<sub>k</sub></code>.
</p>
<p>
-Each list is processed in a separate phase:
+Type inference gives precedence to type information obtained from typed operands
+before considering untyped constants.
+Therefore, inference proceeds in two phases:
</p>
<ol>
<li>
- In the first phase, the parameter and argument types of each pair in <i>Lt</i>
- are unified. If unification succeeds for a pair, it may yield new entries that
- are added to the substitution map <i>M</i>. If unification fails, type inference
- fails.
+ <p>
+ The type equations are solved for the bound
+ type parameters using <a href="#Type_unification">type unification</a>.
+ If unification fails, type inference fails.
+ </p>
</li>
<li>
- The second phase considers the entries of list <i>Lu</i>. Type parameters for
- which the type argument has already been determined are ignored in this phase.
- For each remaining pair, the parameter type (which is a single type parameter) and
- the <a href="#Constants">default type</a> of the corresponding untyped argument is
- unified. If unification fails, type inference fails.
+ <p>
+ For each bound type parameter <code>P<sub>k</sub></code> for which no type argument
+ has been inferred yet and for which one or more pairs
+ <code>(c<sub>j</sub>, P<sub>k</sub>)</code> with that same type parameter
+ were collected, determine the <a href="#Constant_expressions">constant kind</a>
+ of the constants <code>c<sub>j</sub></code> in all those pairs the same way as for
+ <a href="#Constant_expressions">constant expressions</a>.
+ The type argument for <code>P<sub>k</sub></code> is the
+ <a href="#Constants">default type</a> for the determined constant kind.
+ If a constant kind cannot be determined due to conflicting constant kinds,
+ type inference fails.
+ </p>
</li>
</ol>
<p>
-While unification is successful, processing of each list continues until all list elements
-are considered, even if all type arguments are inferred before the last list element has
-been processed.
+If not all type arguments have been found after these two phases, type inference fails.
</p>
<p>
-Example:
+If the two phases are successful, type inference determined a type argument for each
+bound type parameter:
</p>
<pre>
-func min[T ~int|~float64](x, y T) T
-
-var x int
-min(x, 2.0) // T is int, inferred from typed argument x; 2.0 is assignable to int
-min(1.0, 2.0) // T is float64, inferred from default type for 1.0 and matches default type for 2.0
-min(1.0, 2) // illegal: default type float64 (for 1.0) doesn't match default type int (for 2)
+ P<sub>k</sub> ➞ A<sub>k</sub>
</pre>
<p>
-In the example <code>min(1.0, 2)</code>, processing the function argument <code>1.0</code>
-yields the substitution map entry <code>T</code> → <code>float64</code>. Because
-processing continues until all untyped arguments are considered, an error is reported. This
-ensures that type inference does not depend on the order of the untyped arguments.
+A type argument <code>A<sub>k</sub></code> may be a composite type,
+containing other bound type parameters <code>P<sub>k</sub></code> as element types
+(or even be just another bound type parameter).
+In a process of repeated simplification, the bound type parameters in each type
+argument are substituted with the respective type arguments for those type
+parameters until each type argument is free of bound type parameters.
+</p>
+
+<p>
+If type arguments contain cyclic references to themselves
+through bound type parameters, simplification and thus type
+inference fails.
+Otherwise, type inference succeeds.
</p>
-<h4 id="Constraint_type_inference">Constraint type inference</h4>
+<h4 id="Type_unification">Type unification</h4>
<p>
-Constraint type inference infers type arguments by considering type constraints.
-If a type parameter <code>P</code> has a constraint with a
-<a href="#Core_types">core type</a> <code>C</code>,
-<a href="#Type_unification">unifying</a> <code>P</code> with <code>C</code>
-may infer additional type arguments, either the type argument for <code>P</code>,
-or if that is already known, possibly the type arguments for type parameters
-used in <code>C</code>.
+Type inference solves type equations through <i>type unification</i>.
+Type unification recursively compares the LHS and RHS types of an
+equation, where either or both types may be or contain bound type parameters,
+and looks for type arguments for those type parameters such that the LHS
+and RHS match (become identical or assignment-compatible, depending on
+context).
+To that effect, type inference maintains a map of bound type parameters
+to inferred type arguments; this map is consulted and updated during type unification.
+Initially, the bound type parameters are known but the map is empty.
+During type unification, if a new type argument <code>A</code> is inferred,
+the respective mapping <code>P ➞ A</code> from type parameter to argument
+is added to the map.
+Conversely, when comparing types, a known type argument
+(a type argument for which a map entry already exists)
+takes the place of its corresponding type parameter.
+As type inference progresses, the map is populated more and more
+until all equations have been considered, or until unification fails.
+Type inference succeeds if no unification step fails and the map has
+an entry for each type parameter.
</p>
<p>
-For instance, consider the type parameter list with type parameters <code>List</code> and
-<code>Elem</code>:
+For example, given the type equation with the bound type parameter
+<code>P</code>
</p>
<pre>
-[List ~[]Elem, Elem any]
+ [10]struct{ elem P, list []P } ≡<sub>A</sub> [10]struct{ elem string; list []string }
</pre>
<p>
-Constraint type inference can deduce the type of <code>Elem</code> from the type argument
-for <code>List</code> because <code>Elem</code> is a type parameter in the core type
-<code>[]Elem</code> of <code>List</code>.
-If the type argument is <code>Bytes</code>:
+type inference starts with an empty map.
+Unification first compares the top-level structure of the LHS and RHS
+types.
+Both are arrays of the same length; they unify if the element types unify.
+Both element types are structs; they unify if they have
+the same number of fields with the same names and if the
+field types unify.
+The type argument for <code>P</code> is not known yet (there is no map entry),
+so unifying <code>P</code> with <code>string</code> adds
+the mapping <code>P ➞ string</code> to the map.
+Unifying the types of the <code>list</code> field requires
+unifying <code>[]P</code> and <code>[]string</code> and
+thus <code>P</code> and <code>string</code>.
+Since the type argument for <code>P</code> is known at this point
+(there is a map entry for <code>P</code>), its type argument
+<code>string</code> takes the place of <code>P</code>.
+And since <code>string</code> is identical to <code>string</code>,
+this unification step succeeds as well.
+Unification of the LHS and RHS of the equation is now finished.
+Type inference succeeds because there is only one type equation,
+no unification step failed, and the map is fully populated.
</p>
-<pre>
-type Bytes []byte
-</pre>
-
<p>
-unifying the underlying type of <code>Bytes</code> with the core type means
-unifying <code>[]byte</code> with <code>[]Elem</code>. That unification succeeds and yields
-the <a href="#Type_unification">substitution map</a> entry
-<code>Elem</code> → <code>byte</code>.
-Thus, in this example, constraint type inference can infer the second type argument from the
-first one.
+Unification uses a combination of <i>exact</i> and <i>loose</i>
+unification depending on whether two types have to be
+<a href="#Type_identity">identical</a>,
+<a href="#Assignability">assignment-compatible</a>, or
+only structurally equal.
+The respective <a href="#Type_unification_rules">type unification rules</a>
+are spelled out in detail in the <a href="#Appendix">Appendix</a>.
</p>
<p>
-Using the core type of a constraint may lose some information: In the (unlikely) case that
-the constraint's type set contains a single <a href="#Type_definitions">defined type</a>
-<code>N</code>, the corresponding core type is <code>N</code>'s underlying type rather than
-<code>N</code> itself. In this case, constraint type inference may succeed but instantiation
-will fail because the inferred type is not in the type set of the constraint.
-Thus, constraint type inference uses the <i>adjusted core type</i> of
-a constraint: if the type set contains a single type, use that type; otherwise use the
-constraint's core type.
+For an equation of the form <code>X ≡<sub>A</sub> Y</code>,
+where <code>X</code> and <code>Y</code> are types involved
+in an assignment (including parameter passing and return statements),
+the top-level type structures may unify loosely but element types
+must unify exactly, matching the rules for assignments.
</p>
<p>
-Generally, constraint type inference proceeds in two phases: Starting with a given
-substitution map <i>M</i>
+For an equation of the form <code>P ≡<sub>C</sub> C</code>,
+where <code>P</code> is a type parameter and <code>C</code>
+its corresponding constraint, the unification rules are bit
+more complicated:
</p>
-<ol>
+<ul>
<li>
-For all type parameters with an adjusted core type, unify the type parameter with that
-type. If any unification fails, constraint type inference fails.
+ If <code>C</code> has a <a href="#Core_types">core type</a>
+ <code>core(C)</code>
+ and <code>P</code> has a known type argument <code>A</code>,
+ <code>core(C)</code> and <code>A</code> must unify loosely.
+ If <code>P</code> does not have a known type argument
+ and <code>C</code> contains exactly one type term <code>T</code>
+ that is not an underlying (tilde) type, unification adds the
+ mapping <code>P ➞ T</code> to the map.
</li>
-
<li>
-At this point, some entries in <i>M</i> may map type parameters to other
-type parameters or to types containing type parameters. For each entry
-<code>P</code> → <code>A</code> in <i>M</i> where <code>A</code> is or
-contains type parameters <code>Q</code> for which there exist entries
-<code>Q</code> → <code>B</code> in <i>M</i>, substitute those
-<code>Q</code> with the respective <code>B</code> in <code>A</code>.
-Stop when no further substitution is possible.
+ If <code>C</code> does not have a core type
+ and <code>P</code> has a known type argument <code>A</code>,
+ <code>A</code> must have all methods of <code>C</code>, if any,
+ and corresponding method types must unify exactly.
</li>
-</ol>
-
-<p>
-The result of constraint type inference is the final substitution map <i>M</i> from type
-parameters <code>P</code> to type arguments <code>A</code> where no type parameter <code>P</code>
-appears in any of the <code>A</code>.
-</p>
-
-<p>
-For instance, given the type parameter list
-</p>
-
-<pre>
-[A any, B []C, C *A]
-</pre>
-
-<p>
-and the single provided type argument <code>int</code> for type parameter <code>A</code>,
-the initial substitution map <i>M</i> contains the entry <code>A</code> → <code>int</code>.
-</p>
-
-<p>
-In the first phase, the type parameters <code>B</code> and <code>C</code> are unified
-with the core type of their respective constraints. This adds the entries
-<code>B</code> → <code>[]C</code> and <code>C</code> → <code>*A</code>
-to <i>M</i>.
-
-<p>
-At this point there are two entries in <i>M</i> where the right-hand side
-is or contains type parameters for which there exists other entries in <i>M</i>:
-<code>[]C</code> and <code>*A</code>.
-In the second phase, these type parameters are replaced with their respective
-types. It doesn't matter in which order this happens. Starting with the state
-of <i>M</i> after the first phase:
-</p>
-
-<p>
-<code>A</code> → <code>int</code>,
-<code>B</code> → <code>[]C</code>,
-<code>C</code> → <code>*A</code>
-</p>
-
-<p>
-Replace <code>A</code> on the right-hand side of → with <code>int</code>:
-</p>
-
-<p>
-<code>A</code> → <code>int</code>,
-<code>B</code> → <code>[]C</code>,
-<code>C</code> → <code>*int</code>
-</p>
-
-<p>
-Replace <code>C</code> on the right-hand side of → with <code>*int</code>:
-</p>
-
-<p>
-<code>A</code> → <code>int</code>,
-<code>B</code> → <code>[]*int</code>,
-<code>C</code> → <code>*int</code>
-</p>
+</ul>
<p>
-At this point no further substitution is possible and the map is full.
-Therefore, <code>M</code> represents the final map of type parameters
-to type arguments for the given type parameter list.
+When solving type equations from type constraints,
+solving one equation may infer additional type arguments,
+which in turn may enable solving other equations that depend
+on those type arguments.
+Type inference repeats type unification as long as new type
+arguments are inferred.
</p>
<h3 id="Operators">Operators</h3>
statements, not expressions, they fall
outside the operator hierarchy.
As a consequence, statement <code>*p++</code> is the same as <code>(*p)++</code>.
+</p>
<p>
There are five precedence levels for binary operators.
Multiplication operators bind strongest, followed by addition
</p>
<pre>
-+x
-23 + 3*x[i]
-x <= f()
-^a >> b
-f() || g()
-x == y+1 && <-chanInt > 0
++x // x
+42 + a - b // (42 + a) - b
+23 + 3*x[i] // 23 + (3 * x[i])
+x <= f() // x <= f()
+^a >> b // (^a) >> b
+f() || g() // f() || g()
+x == y+1 && <-chanInt > 0 // (x == (y+1)) && ((<-chanInt) > 0)
</pre>
</p>
<pre>
- x, q
+ x, q
int8 -128
int16 -32768
int32 -2147483648
</p>
<p>
The equality operators <code>==</code> and <code>!=</code> apply
-to operands that are <i>comparable</i>.
+to operands of <i>comparable</i> types.
The ordering operators <code><</code>, <code><=</code>, <code>></code>, and <code>>=</code>
-apply to operands that are <i>ordered</i>.
+apply to operands of <i>ordered</i> types.
These terms and the result of the comparisons are defined as follows:
</p>
<ul>
<li>
- Boolean values are comparable.
+ Boolean types are comparable.
Two boolean values are equal if they are either both
<code>true</code> or both <code>false</code>.
</li>
<li>
- Integer values are comparable and ordered, in the usual way.
+ Integer types are comparable and ordered.
+ Two integer values are compared in the usual way.
</li>
<li>
- Floating-point values are comparable and ordered,
- as defined by the IEEE-754 standard.
+ Floating-point types are comparable and ordered.
+ Two floating-point values are compared as defined by the IEEE-754 standard.
</li>
<li>
- Complex values are comparable.
+ Complex types are comparable.
Two complex values <code>u</code> and <code>v</code> are
equal if both <code>real(u) == real(v)</code> and
<code>imag(u) == imag(v)</code>.
</li>
<li>
- String values are comparable and ordered, lexically byte-wise.
+ String types are comparable and ordered.
+ Two string values are compared lexically byte-wise.
</li>
<li>
- Pointer values are comparable.
+ Pointer types are comparable.
Two pointer values are equal if they point to the same variable or if both have value <code>nil</code>.
Pointers to distinct <a href="#Size_and_alignment_guarantees">zero-size</a> variables may or may not be equal.
</li>
<li>
- Channel values are comparable.
+ Channel types are comparable.
Two channel values are equal if they were created by the same call to
<a href="#Making_slices_maps_and_channels"><code>make</code></a>
or if both have value <code>nil</code>.
</li>
<li>
- Interface values are comparable.
+ Interface types that are not type parameters are comparable.
Two interface values are equal if they have <a href="#Type_identity">identical</a> dynamic types
and equal dynamic values or if both have value <code>nil</code>.
</li>
<li>
A value <code>x</code> of non-interface type <code>X</code> and
- a value <code>t</code> of interface type <code>T</code> are comparable when values
- of type <code>X</code> are comparable and
+ a value <code>t</code> of interface type <code>T</code> can be compared
+ if type <code>X</code> is comparable and
<code>X</code> <a href="#Implementing_an_interface">implements</a> <code>T</code>.
They are equal if <code>t</code>'s dynamic type is identical to <code>X</code>
and <code>t</code>'s dynamic value is equal to <code>x</code>.
</li>
<li>
- Struct values are comparable if all their fields are comparable.
+ Struct types are comparable if all their field types are comparable.
Two struct values are equal if their corresponding
- non-<a href="#Blank_identifier">blank</a> fields are equal.
+ non-<a href="#Blank_identifier">blank</a> field values are equal.
+ The fields are compared in source order, and comparison stops as
+ soon as two field values differ (or all fields have been compared).
</li>
<li>
- Array values are comparable if values of the array element type are comparable.
- Two array values are equal if their corresponding elements are equal.
+ Array types are comparable if their array element types are comparable.
+ Two array values are equal if their corresponding element values are equal.
+ The elements are compared in ascending index order, and comparison stops
+ as soon as two element values differ (or all elements have been compared).
+ </li>
+
+ <li>
+ Type parameters are comparable if they are strictly comparable (see below).
</li>
</ul>
<p>
A comparison of two interface values with identical dynamic types
-causes a <a href="#Run_time_panics">run-time panic</a> if values
-of that type are not comparable. This behavior applies not only to direct interface
+causes a <a href="#Run_time_panics">run-time panic</a> if that type
+is not comparable. This behavior applies not only to direct interface
value comparisons but also when comparing arrays of interface values
or structs with interface-valued fields.
</p>
<p>
-Slice, map, and function values are not comparable.
+Slice, map, and function types are not comparable.
However, as a special case, a slice, map, or function value may
be compared to the predeclared identifier <code>nil</code>.
Comparison of pointer, channel, and interface values to <code>nil</code>
)
</pre>
+<p>
+A type is <i>strictly comparable</i> if it is comparable and not an interface
+type nor composed of interface types.
+Specifically:
+</p>
+
+<ul>
+ <li>
+ Boolean, numeric, string, pointer, and channel types are strictly comparable.
+ </li>
+
+ <li>
+ Struct types are strictly comparable if all their field types are strictly comparable.
+ </li>
+
+ <li>
+ Array types are strictly comparable if their array element types are strictly comparable.
+ </li>
+
+ <li>
+ Type parameters are strictly comparable if all types in their type set are strictly comparable.
+ </li>
+</ul>
+
<h3 id="Logical_operators">Logical operators</h3>
<p>
Logical operators apply to <a href="#Boolean_types">boolean</a> values
and yield a result of the same type as the operands.
-The right operand is evaluated conditionally.
+The left operand is evaluated, and then the right if the condition requires it.
</p>
<pre class="grammar">
</pre>
<p>
-A receive expression used in an <a href="#Assignments">assignment</a> or initialization of the special form
+A receive expression used in an <a href="#Assignment_statements">assignment statement</a> or initialization of the special form
</p>
<pre>
float64(-1e-1000) // 0.0 of type float64
string('x') // "x" of type string
string(0x266c) // "♬" of type string
-MyString("foo" + "bar") // "foobar" of type MyString
+myString("foo" + "bar") // "foobar" of type myString
string([]byte{'a'}) // not a constant: []byte{'a'} is not a constant
(*int)(nil) // not a constant: nil is not a constant, *int is not a boolean, numeric, or string type
int(1.2) // illegal: 1.2 cannot be represented as an int
ignoring struct tags (see below),
<code>x</code>'s type and <code>T</code> are not
<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="#Underlying_types">underlying types</a>.
</li>
<li>
ignoring struct tags (see below),
<code>x</code> is a string and <code>T</code> is a slice of bytes or runes.
</li>
<li>
- <code>x</code> is a slice, <code>T</code> is a pointer to an array,
+ <code>x</code> is a slice, <code>T</code> is an array or a pointer to an array,
and the slice and array types have <a href="#Type_identity">identical</a> element types.
</li>
</ul>
<h4 id="Conversions_to_and_from_a_string_type">Conversions to and from a string type</h4>
<ol>
-<li>
-Converting a signed or unsigned integer value to a string type yields a
-string containing the UTF-8 representation of the integer. Values outside
-the range of valid Unicode code points are converted to <code>"\uFFFD"</code>.
-
-<pre>
-string('a') // "a"
-string(-1) // "\ufffd" == "\xef\xbf\xbd"
-string(0xf8) // "\u00f8" == "ø" == "\xc3\xb8"
-type MyString string
-MyString(0x65e5) // "\u65e5" == "日" == "\xe6\x97\xa5"
-</pre>
-</li>
-
<li>
Converting a slice of bytes to a string type yields
a string whose successive bytes are the elements of the slice.
string([]byte{}) // ""
string([]byte(nil)) // ""
-type MyBytes []byte
-string(MyBytes{'h', 'e', 'l', 'l', '\xc3', '\xb8'}) // "hellø"
+type bytes []byte
+string(bytes{'h', 'e', 'l', 'l', '\xc3', '\xb8'}) // "hellø"
+
+type myByte byte
+string([]myByte{'w', 'o', 'r', 'l', 'd', '!'}) // "world!"
+myString([]myByte{'\xf0', '\x9f', '\x8c', '\x8d'}) // "🌍"
</pre>
</li>
string([]rune{}) // ""
string([]rune(nil)) // ""
-type MyRunes []rune
-string(MyRunes{0x767d, 0x9d6c, 0x7fd4}) // "\u767d\u9d6c\u7fd4" == "白鵬翔"
+type runes []rune
+string(runes{0x767d, 0x9d6c, 0x7fd4}) // "\u767d\u9d6c\u7fd4" == "白鵬翔"
+
+type myRune rune
+string([]myRune{0x266b, 0x266c}) // "\u266b\u266c" == "♫♬"
+myString([]myRune{0x1f30e}) // "\U0001f30e" == "🌎"
</pre>
</li>
<li>
Converting a value of a string type to a slice of bytes type
-yields a slice whose successive elements are the bytes of the string.
+yields a non-nil slice whose successive elements are the bytes of the string.
<pre>
-[]byte("hellø") // []byte{'h', 'e', 'l', 'l', '\xc3', '\xb8'}
-[]byte("") // []byte{}
+[]byte("hellø") // []byte{'h', 'e', 'l', 'l', '\xc3', '\xb8'}
+[]byte("") // []byte{}
+
+bytes("hellø") // []byte{'h', 'e', 'l', 'l', '\xc3', '\xb8'}
-MyBytes("hellø") // []byte{'h', 'e', 'l', 'l', '\xc3', '\xb8'}
+[]myByte("world!") // []myByte{'w', 'o', 'r', 'l', 'd', '!'}
+[]myByte(myString("🌏")) // []myByte{'\xf0', '\x9f', '\x8c', '\x8f'}
</pre>
</li>
yields a slice containing the individual Unicode code points of the string.
<pre>
-[]rune(MyString("白鵬翔")) // []rune{0x767d, 0x9d6c, 0x7fd4}
-[]rune("") // []rune{}
+[]rune(myString("白鵬翔")) // []rune{0x767d, 0x9d6c, 0x7fd4}
+[]rune("") // []rune{}
+
+runes("白鵬翔") // []rune{0x767d, 0x9d6c, 0x7fd4}
+
+[]myRune("♫♬") // []myRune{0x266b, 0x266c}
+[]myRune(myString("🌐")) // []myRune{0x1f310}
+</pre>
+</li>
+
+<li>
+Finally, for historical reasons, an integer value may be converted to a string type.
+This form of conversion yields a string containing the (possibly multi-byte) UTF-8
+representation of the Unicode code point with the given integer value.
+Values outside the range of valid Unicode code points are converted to <code>"\uFFFD"</code>.
+
+<pre>
+string('a') // "a"
+string(65) // "A"
+string('\xf8') // "\u00f8" == "ø" == "\xc3\xb8"
+string(-1) // "\ufffd" == "\xef\xbf\xbd"
-MyRunes("白鵬翔") // []rune{0x767d, 0x9d6c, 0x7fd4}
+type myString string
+myString('\u65e5') // "\u65e5" == "日" == "\xe6\x97\xa5"
</pre>
+
+Note: This form of conversion may eventually be removed from the language.
+The <a href="/pkg/cmd/vet"><code>go vet</code></a> tool flags certain
+integer-to-string conversions as potential errors.
+Library functions such as
+<a href="/pkg/unicode/utf8#AppendRune"><code>utf8.AppendRune</code></a> or
+<a href="/pkg/unicode/utf8#EncodeRune"><code>utf8.EncodeRune</code></a>
+should be used instead.
</li>
</ol>
-<h4 id="Conversions_from_slice_to_array_pointer">Conversions from slice to array pointer</h4>
+<h4 id="Conversions_from_slice_to_array_or_array_pointer">Conversions from slice to array or array pointer</h4>
<p>
-Converting a slice to an array pointer yields a pointer to the underlying array of the slice.
-If the <a href="#Length_and_capacity">length</a> of the slice is less than the length of the array,
+Converting a slice to an array yields an array containing the elements of the underlying array of the slice.
+Similarly, converting a slice to an array pointer yields a pointer to the underlying array of the slice.
+In both cases, if the <a href="#Length_and_capacity">length</a> of the slice is less than the length of the array,
a <a href="#Run_time_panics">run-time panic</a> occurs.
</p>
<pre>
s := make([]byte, 2, 4)
+
+a0 := [0]byte(s)
+a1 := [1]byte(s[1:]) // a1[0] == s[1]
+a2 := [2]byte(s) // a2[0] == s[0]
+a4 := [4]byte(s) // panics: len([4]byte) > len(s)
+
s0 := (*[0]byte)(s) // s0 != nil
s1 := (*[1]byte)(s[1:]) // &s1[0] == &s[1]
s2 := (*[2]byte)(s) // &s2[0] == &s[0]
s4 := (*[4]byte)(s) // panics: len([4]byte) > len(s)
var t []string
-t0 := (*[0]string)(t) // t0 == nil
-t1 := (*[1]string)(t) // panics: len([1]string) > len(t)
+t0 := [0]string(t) // ok for nil slice t
+t1 := (*[0]string)(t) // t1 == nil
+t2 := (*[1]string)(t) // panics: len([1]string) > len(t)
u := make([]byte, 0)
u0 := (*[0]byte)(u) // u0 != nil
Otherwise, when evaluating the <a href="#Operands">operands</a> of an
expression, assignment, or
<a href="#Return_statements">return statement</a>,
-all function calls, method calls, and
-communication operations are evaluated in lexical left-to-right
-order.
+all function calls, method calls,
+<a href="#Receive operator">receive operations</a>,
+and <a href="#Logical_operators">binary logical operations</a>
+are evaluated in lexical left-to-right order.
</p>
<p>
For example, in the (function-local) assignment
</p>
<pre>
-y[f()], ok = g(h(), i()+x[j()], <-c), k()
+y[f()], ok = g(z || h(), i()+x[j()], <-c), k()
</pre>
<p>
the function calls and communication happen in the order
-<code>f()</code>, <code>h()</code>, <code>i()</code>, <code>j()</code>,
+<code>f()</code>, <code>h()</code> (if <code>z</code>
+evaluates to false), <code>i()</code>, <code>j()</code>,
<code><-c</code>, <code>g()</code>, and <code>k()</code>.
However, the order of those events compared to the evaluation
and indexing of <code>x</code> and the evaluation
-of <code>y</code> is not specified.
+of <code>y</code> and <code>z</code> is not specified,
+except as required lexically. For instance, <code>g</code>
+cannot be called before its arguments are evaluated.
</p>
<pre>
<pre>
append cap complex imag len make new real
-unsafe.Add unsafe.Alignof unsafe.Offsetof unsafe.Sizeof unsafe.Slice
+unsafe.Add unsafe.Alignof unsafe.Offsetof unsafe.Sizeof unsafe.Slice unsafe.SliceData unsafe.String unsafe.StringData
</pre>
<pre>
</pre>
<p>
-The following <a href="#Assignments">assignment statements</a> are semantically
+The following <a href="#Assignment_statements">assignment statements</a> are semantically
equivalent:
</p>
</pre>
-<h3 id="Assignments">Assignments</h3>
+<h3 id="Assignment_statements">Assignment statements</h3>
+
+<p>
+An <i>assignment</i> replaces the current value stored in a <a href="#Variables">variable</a>
+with a new value specified by an <a href="#Expressions">expression</a>.
+An assignment statement may assign a single value to a single variable, or multiple values to a
+matching number of variables.
+</p>
<pre class="ebnf">
Assignment = ExpressionList assign_op ExpressionList .
for i, x[i] = range x { // set i, x[2] = 0, x[0]
break
}
-// after this loop, i == 0 and x == []int{3, 5, 3}
+// after this loop, i == 0 and x is []int{3, 5, 3}
</pre>
<p>
<p>
A "for" statement with a "range" clause
-iterates through all entries of an array, slice, string or map,
-or values received on a channel. For each entry it assigns <i>iteration values</i>
+iterates through all entries of an array, slice, string or map, values received on
+a channel, or integer values from zero to an upper limit.
+For each entry it assigns <i>iteration values</i>
to corresponding <i>iteration variables</i> if present and then executes the block.
</p>
<p>
The expression on the right in the "range" clause is called the <i>range expression</i>,
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>.
+an array, pointer to an array, slice, string, map, channel permitting
+<a href="#Receive_operator">receive operations</a>, or an integer.
As with an assignment, if present the operands on the left must be
<a href="#Address_operators">addressable</a> or map index expressions; they
-denote the iteration variables. If the range expression is a channel, at most
-one iteration variable is permitted, otherwise there may be up to two.
+denote the iteration variables. If the range expression is a channel or integer,
+at most one iteration variable is permitted, otherwise there may be up to two.
If the last iteration variable is the <a href="#Blank_identifier">blank identifier</a>,
the range clause is equivalent to the same clause without that identifier.
</p>
string s string type index i int see below rune
map m map[K]V key k K m[k] V
channel c chan E, <-chan E element e E
+integer n integer type I value i I
</pre>
<ol>
the channel until the channel is <a href="#Close">closed</a>. If the channel
is <code>nil</code>, the range expression blocks forever.
</li>
+
+<li>
+For an integer value <code>n</code>, the iteration values 0 through <code>n-1</code>
+are produced in increasing order, with the same type as <code>n</code>.
+If <code>n</code> <= 0, the loop does not run any iterations.
+</li>
</ol>
<p>
The iteration values are assigned to the respective
-iteration variables as in an <a href="#Assignments">assignment statement</a>.
+iteration variables as in an <a href="#Assignment_statements">assignment statement</a>.
</p>
<p>
// empty a channel
for range ch {}
+
+// call f(0), f(1), ... f(9)
+for i := range 10 {
+ // type of i is int (default type for untyped constant 10)
+ f(i)
+}
</pre>
<p>
A "continue" statement begins the next iteration of the
-innermost <a href="#For_statements">"for" loop</a> at its post statement.
+innermost enclosing <a href="#For_statements">"for" loop</a>
+by advancing control to the end of the loop block.
The "for" loop must be within the same function.
</p>
they cannot be used as function values.
</p>
+
+<h3 id="Appending_and_copying_slices">Appending to and copying slices</h3>
+
+<p>
+The built-in functions <code>append</code> and <code>copy</code> assist in
+common slice operations.
+For both functions, the result is independent of whether the memory referenced
+by the arguments overlaps.
+</p>
+
+<p>
+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>
+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
+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
+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
+<a href="#Core_types"><code>bytestring</code></a> followed by <code>...</code>.
+This form appends the bytes of the byte slice or string.
+</p>
+
+<pre class="grammar">
+append(s S, x ...E) S // core type of S is []E
+</pre>
+
+<p>
+If the capacity of <code>s</code> is not large enough to fit the additional
+values, <code>append</code> <a href="#Allocation">allocates</a> a new, sufficiently large underlying
+array that fits both the existing slice elements and the additional values.
+Otherwise, <code>append</code> re-uses the underlying array.
+</p>
+
+<pre>
+s0 := []int{0, 0}
+s1 := append(s0, 2) // append a single element s1 is []int{0, 0, 2}
+s2 := append(s1, 3, 5, 7) // append multiple elements s2 is []int{0, 0, 2, 3, 5, 7}
+s3 := append(s2, s0...) // append a slice s3 is []int{0, 0, 2, 3, 5, 7, 0, 0}
+s4 := append(s3[3:6], s3[2:]...) // append overlapping slice s4 is []int{3, 5, 7, 2, 3, 5, 7, 0, 0}
+
+var t []interface{}
+t = append(t, 42, 3.1415, "foo") // t is []interface{}{42, 3.1415, "foo"}
+
+var b []byte
+b = append(b, "bar"...) // append string contents b is []byte{'b', 'a', 'r' }
+</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.
+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, if the destination's core type is <code>[]byte</code>,
+<code>copy</code> also accepts a source argument with core type
+</a> <a href="#Core_types"><code>bytestring</code></a>.
+This form copies the bytes from the byte slice or string into the byte slice.
+</p>
+
+<pre class="grammar">
+copy(dst, src []T) int
+copy(dst []byte, src string) int
+</pre>
+
+<p>
+Examples:
+</p>
+
+<pre>
+var a = [...]int{0, 1, 2, 3, 4, 5, 6, 7}
+var s = make([]int, 6)
+var b = make([]byte, 5)
+n1 := copy(s, a[0:]) // n1 == 6, s is []int{0, 1, 2, 3, 4, 5}
+n2 := copy(s, s[2:]) // n2 == 4, s is []int{2, 3, 4, 5, 4, 5}
+n3 := copy(b, "Hello, World!") // n3 == 5, b is []byte("Hello")
+</pre>
+
+
+<h3 id="Clear">Clear</h3>
+
+<p>
+The built-in function <code>clear</code> takes an argument of <a href="#Map_types">map</a>,
+<a href="#Slice_types">slice</a>, or <a href="#Type_parameter_declarations">type parameter</a> type,
+and deletes or zeroes out all elements.
+</p>
+
+<pre class="grammar">
+Call Argument type Result
+
+clear(m) map[K]T deletes all entries, resulting in an
+ empty map (len(m) == 0)
+
+clear(s) []T sets all elements up to the length of
+ <code>s</code> to the zero value of T
+
+clear(t) type parameter see below
+</pre>
+
+<p>
+If the type of the argument to <code>clear</code> is a
+<a href="#Type_parameter_declarations">type parameter</a>,
+all types in its type set must be maps or slices, and <code>clear</code>
+performs the operation corresponding to the actual type argument.
+</p>
+
+<p>
+If the map or slice is <code>nil</code>, <code>clear</code> is a no-op.
+</p>
+
+
<h3 id="Close">Close</h3>
<p>
returns a received value along with an indication of whether the channel is closed.
</p>
+
+<h3 id="Complex_numbers">Manipulating complex numbers</h3>
+
+<p>
+Three functions assemble and disassemble complex numbers.
+The built-in function <code>complex</code> constructs a complex
+value from a floating-point real and imaginary part, while
+<code>real</code> and <code>imag</code>
+extract the real and imaginary parts of a complex value.
+</p>
+
+<pre class="grammar">
+complex(realPart, imaginaryPart floatT) complexT
+real(complexT) floatT
+imag(complexT) floatT
+</pre>
+
+<p>
+The type of the arguments and return value correspond.
+For <code>complex</code>, the two arguments must be of the same
+<a href="#Numeric_types">floating-point type</a> and the return type is the
+<a href="#Numeric_types">complex type</a>
+with the corresponding floating-point constituents:
+<code>complex64</code> for <code>float32</code> arguments, and
+<code>complex128</code> for <code>float64</code> arguments.
+If one of the arguments evaluates to an untyped constant, it is first implicitly
+<a href="#Conversions">converted</a> to the type of the other argument.
+If both arguments evaluate to untyped constants, they must be non-complex
+numbers or their imaginary parts must be zero, and the return value of
+the function is an untyped complex constant.
+</p>
+
+<p>
+For <code>real</code> and <code>imag</code>, the argument must be
+of complex type, and the return type is the corresponding floating-point
+type: <code>float32</code> for a <code>complex64</code> argument, and
+<code>float64</code> for a <code>complex128</code> argument.
+If the argument evaluates to an untyped constant, it must be a number,
+and the return value of the function is an untyped floating-point constant.
+</p>
+
+<p>
+The <code>real</code> and <code>imag</code> functions together form the inverse of
+<code>complex</code>, so for a value <code>z</code> of a complex type <code>Z</code>,
+<code>z == Z(complex(real(z), imag(z)))</code>.
+</p>
+
+<p>
+If the operands of these functions are all constants, the return
+value is a constant.
+</p>
+
+<pre>
+var a = complex(2, -2) // complex128
+const b = complex(1.0, -1.4) // untyped complex constant 1 - 1.4i
+x := float32(math.Cos(math.Pi/2)) // float32
+var c64 = complex(5, -x) // complex64
+var s int = complex(1, 0) // untyped complex constant 1 + 0i can be converted to int
+_ = complex(1, 2<<s) // illegal: 2 assumes floating-point type, cannot shift
+var rl = real(c64) // float32
+var im = imag(a) // float64
+const c = imag(b) // untyped constant -1.4
+_ = imag(3 << s) // illegal: 3 assumes complex type, cannot shift
+</pre>
+
+<p>
+Arguments of type parameter type are not permitted.
+</p>
+
+
+<h3 id="Deletion_of_map_elements">Deletion of map elements</h3>
+
+<p>
+The built-in function <code>delete</code> removes the element with key
+<code>k</code> from a <a href="#Map_types">map</a> <code>m</code>. The
+value <code>k</code> must be <a href="#Assignability">assignable</a>
+to the key type of <code>m</code>.
+</p>
+
+<pre class="grammar">
+delete(m, k) // remove element m[k] from map m
+</pre>
+
+<p>
+If the type of <code>m</code> is a <a href="#Type_parameter_declarations">type parameter</a>,
+all types in that type set 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.
+</p>
+
+
<h3 id="Length_and_capacity">Length and capacity</h3>
<p>
var z complex128
</pre>
-<h3 id="Allocation">Allocation</h3>
-
-<p>
-The built-in function <code>new</code> takes a type <code>T</code>,
-allocates storage for a <a href="#Variables">variable</a> of that type
-at run time, and returns a value of type <code>*T</code>
-<a href="#Pointer_types">pointing</a> to it.
-The variable is initialized as described in the section on
-<a href="#The_zero_value">initial values</a>.
-</p>
-
-<pre class="grammar">
-new(T)
-</pre>
-
-<p>
-For instance
-</p>
-
-<pre>
-type S struct { a int; b float64 }
-new(S)
-</pre>
-
-<p>
-allocates storage for a variable of type <code>S</code>,
-initializes it (<code>a=0</code>, <code>b=0.0</code>),
-and returns a value of type <code>*S</code> containing the address
-of the location.
-</p>
<h3 id="Making_slices_maps_and_channels">Making slices, maps and channels</h3>
make(T, n) channel buffered channel of type T, buffer size n
</pre>
-
<p>
-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>.
+Each of the size arguments <code>n</code> and <code>m</code> must be of <a href="#Numeric_types">integer type</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>
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
<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,
+For slices and channels, if <code>n</code> is negative or larger than <code>m</code> at run time,
a <a href="#Run_time_panics">run-time panic</a> occurs.
</p>
</p>
-<h3 id="Appending_and_copying_slices">Appending to and copying slices</h3>
+<h3 id="Min_and_max">Min and max</h3>
<p>
-The built-in functions <code>append</code> and <code>copy</code> assist in
-common slice operations.
-For both functions, the result is independent of whether the memory referenced
-by the arguments overlaps.
+The built-in functions <code>min</code> and <code>max</code> compute the
+smallest—or largest, respectively—value of a fixed number of
+arguments of <a href="#Comparison_operators">ordered types</a>.
+There must be at least one argument.
</p>
<p>
-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>
-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 ...E) S // E is the element type of the core type of S
-</pre>
-
-<p>
-If the capacity of <code>s</code> is not large enough to fit the additional
-values, <code>append</code> allocates a new, sufficiently large underlying
-array that fits both the existing slice elements and the additional values.
-Otherwise, <code>append</code> re-uses the underlying array.
+The same type rules as for <a href="#Operators">operators</a> apply:
+for <a href="#Comparison_operators">ordered</a> arguments <code>x</code> and
+<code>y</code>, <code>min(x, y)</code> is valid if <code>x + y</code> is valid,
+and the type of <code>min(x, y)</code> is the type of <code>x + y</code>
+(and similarly for <code>max</code>).
+If all arguments are constant, the result is constant.
</p>
<pre>
-s0 := []int{0, 0}
-s1 := append(s0, 2) // append a single element s1 == []int{0, 0, 2}
-s2 := append(s1, 3, 5, 7) // append multiple elements s2 == []int{0, 0, 2, 3, 5, 7}
-s3 := append(s2, s0...) // append a slice s3 == []int{0, 0, 2, 3, 5, 7, 0, 0}
-s4 := append(s3[3:6], s3[2:]...) // append overlapping slice s4 == []int{3, 5, 7, 2, 3, 5, 7, 0, 0}
-
-var t []interface{}
-t = append(t, 42, 3.1415, "foo") // t == []interface{}{42, 3.1415, "foo"}
-
-var b []byte
-b = append(b, "bar"...) // append string contents b == []byte{'b', 'a', 'r' }
+var x, y int
+m := min(x) // m == x
+m := min(x, y) // m is the smaller of x and y
+m := max(x, y, 10) // m is the larger of x and y but at least 10
+c := max(1, 2.0, 10) // c == 10.0 (floating-point kind)
+f := max(0, float32(x)) // type of f is float32
+var s []string
+_ = min(s...) // invalid: slice arguments are not permitted
+t := max("", "foo", "bar") // t == "foo" (string kind)
</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.
-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, 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.
+For numeric arguments, assuming all NaNs are equal, <code>min</code> and <code>max</code> are
+commutative and associative:
</p>
-<pre class="grammar">
-copy(dst, src []T) int
-copy(dst []byte, src string) int
+<pre>
+min(x, y) == min(y, x)
+min(x, y, z) == min(min(x, y), z) == min(x, min(y, z))
</pre>
<p>
-Examples:
+For floating-point arguments negative zero, NaN, and infinity the following rules apply:
</p>
<pre>
-var a = [...]int{0, 1, 2, 3, 4, 5, 6, 7}
-var s = make([]int, 6)
-var b = make([]byte, 5)
-n1 := copy(s, a[0:]) // n1 == 6, s == []int{0, 1, 2, 3, 4, 5}
-n2 := copy(s, s[2:]) // n2 == 4, s == []int{2, 3, 4, 5, 4, 5}
-n3 := copy(b, "Hello, World!") // n3 == 5, b == []byte("Hello")
-</pre>
-
-
-<h3 id="Deletion_of_map_elements">Deletion of map elements</h3>
-
-<p>
-The built-in function <code>delete</code> removes the element with key
-<code>k</code> from a <a href="#Map_types">map</a> <code>m</code>. The
-value <code>k</code> must be <a href="#Assignability">assignable</a>
-to the key type of <code>m</code>.
-</p>
+ x y min(x, y) max(x, y)
-<pre class="grammar">
-delete(m, k) // remove element m[k] from map m
+ -0.0 0.0 -0.0 0.0 // negative zero is smaller than (non-negative) zero
+ -Inf y -Inf y // negative infinity is smaller than any other number
+ +Inf y y +Inf // positive infinity is larger than any other number
+ NaN y NaN NaN // if any argument is a NaN, the result is a NaN
</pre>
<p>
-If the type of <code>m</code> is a <a href="#Type_parameter_declarations">type parameter</a>,
-all types in that type set 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.
+For string arguments the result for <code>min</code> is the first argument
+with the smallest (or for <code>max</code>, largest) value,
+compared lexically byte-wise:
</p>
+<pre>
+min(x, y) == if x <= y then x else y
+min(x, y, z) == min(min(x, y), z)
+</pre>
-<h3 id="Complex_numbers">Manipulating complex numbers</h3>
+<h3 id="Allocation">Allocation</h3>
<p>
-Three functions assemble and disassemble complex numbers.
-The built-in function <code>complex</code> constructs a complex
-value from a floating-point real and imaginary part, while
-<code>real</code> and <code>imag</code>
-extract the real and imaginary parts of a complex value.
+The built-in function <code>new</code> takes a type <code>T</code>,
+allocates storage for a <a href="#Variables">variable</a> of that type
+at run time, and returns a value of type <code>*T</code>
+<a href="#Pointer_types">pointing</a> to it.
+The variable is initialized as described in the section on
+<a href="#The_zero_value">initial values</a>.
</p>
<pre class="grammar">
-complex(realPart, imaginaryPart floatT) complexT
-real(complexT) floatT
-imag(complexT) floatT
+new(T)
</pre>
<p>
-The type of the arguments and return value correspond.
-For <code>complex</code>, the two arguments must be of the same
-<a href="#Numeric_types">floating-point type</a> and the return type is the
-<a href="#Numeric_types">complex type</a>
-with the corresponding floating-point constituents:
-<code>complex64</code> for <code>float32</code> arguments, and
-<code>complex128</code> for <code>float64</code> arguments.
-If one of the arguments evaluates to an untyped constant, it is first implicitly
-<a href="#Conversions">converted</a> to the type of the other argument.
-If both arguments evaluate to untyped constants, they must be non-complex
-numbers or their imaginary parts must be zero, and the return value of
-the function is an untyped complex constant.
-</p>
-
-<p>
-For <code>real</code> and <code>imag</code>, the argument must be
-of complex type, and the return type is the corresponding floating-point
-type: <code>float32</code> for a <code>complex64</code> argument, and
-<code>float64</code> for a <code>complex128</code> argument.
-If the argument evaluates to an untyped constant, it must be a number,
-and the return value of the function is an untyped floating-point constant.
-</p>
-
-<p>
-The <code>real</code> and <code>imag</code> functions together form the inverse of
-<code>complex</code>, so for a value <code>z</code> of a complex type <code>Z</code>,
-<code>z == Z(complex(real(z), imag(z)))</code>.
-</p>
-
-<p>
-If the operands of these functions are all constants, the return
-value is a constant.
+For instance
</p>
<pre>
-var a = complex(2, -2) // complex128
-const b = complex(1.0, -1.4) // untyped complex constant 1 - 1.4i
-x := float32(math.Cos(math.Pi/2)) // float32
-var c64 = complex(5, -x) // complex64
-var s int = complex(1, 0) // untyped complex constant 1 + 0i can be converted to int
-_ = complex(1, 2<<s) // illegal: 2 assumes floating-point type, cannot shift
-var rl = real(c64) // float32
-var im = imag(a) // float64
-const c = imag(b) // untyped constant -1.4
-_ = imag(3 << s) // illegal: 3 assumes complex type, cannot shift
+type S struct { a int; b float64 }
+new(S)
</pre>
<p>
-Arguments of type parameter type are not permitted.
+allocates storage for a variable of type <code>S</code>,
+initializes it (<code>a=0</code>, <code>b=0.0</code>),
+and returns a value of type <code>*S</code> containing the address
+of the location.
</p>
+
<h3 id="Handling_panics">Handling panics</h3>
<p> Two built-in functions, <code>panic</code> and <code>recover</code>,
</p>
<p>
-The return value of <code>recover</code> is <code>nil</code> if any of the following conditions holds:
+The return value of <code>recover</code> is <code>nil</code> when the
+goroutine is not panicking or <code>recover</code> was not called directly by a deferred function.
+Conversely, if a goroutine is panicking and <code>recover</code> was called directly by a deferred function,
+the return value of <code>recover</code> is guaranteed not to be <code>nil</code>.
+To ensure this, calling <code>panic</code> with a <code>nil</code> interface value (or an untyped <code>nil</code>)
+causes a <a href="#Run_time_panics">run-time panic</a>.
</p>
-<ul>
-<li>
-<code>panic</code>'s argument was <code>nil</code>;
-</li>
-<li>
-the goroutine is not panicking;
-</li>
-<li>
-<code>recover</code> was not called directly by a deferred function.
-</li>
-</ul>
<p>
The <code>protect</code> function in the example below invokes
<a href="#Types">types</a> must be supported.
</p>
+
<h2 id="Packages">Packages</h2>
<p>
</p>
<p>
-Assume we have compiled a package containing the package clause
+Consider a compiled a package containing the package clause
<code>package math</code>, which exports function <code>Sin</code>, and
installed the compiled package in the file identified by
<code>"lib/math"</code>.
by the order in which the files are presented to the compiler: Variables
declared in the first file are declared before any of the variables declared
in the second file, and so on.
+To ensure reproducible initialization behavior, build systems are encouraged
+to present multiple files belonging to the same package in lexical file name
+order to a compiler.
</p>
<p>
</p>
<p>
-A package with no imports is initialized by assigning initial values
-to all its package-level variables followed by calling all <code>init</code>
-functions in the order they appear in the source, possibly in multiple files,
-as presented to the compiler.
+The entire package is initialized by assigning initial values
+to all its package-level variables followed by calling
+all <code>init</code> functions in the order they appear
+in the source, possibly in multiple files, as presented
+to the compiler.
+</p>
+
+<h3 id="Program_initialization">Program initialization</h3>
+
+<p>
+The packages of a complete program are initialized stepwise, one package at a time.
If a package has imports, the imported packages are initialized
before initializing the package itself. If multiple packages import
a package, the imported package will be initialized only once.
The importing of packages, by construction, guarantees that there
can be no cyclic initialization dependencies.
+More precisely:
+</p>
+
+<p>
+Given the list of all packages, sorted by import path, in each step the first
+uninitialized package in the list for which all imported packages (if any) are
+already initialized is <a href="#Package_initialization">initialized</a>.
+This step is repeated until all packages are initialized.
</p>
<p>
until the previous one has returned.
</p>
-<p>
-To ensure reproducible initialization behavior, build systems are encouraged
-to present multiple files belonging to the same package in lexical file name
-order to a compiler.
-</p>
-
-
<h3 id="Program_execution">Program execution</h3>
<p>
A complete program is created by linking a single, unimported package
</pre>
<p>
-Program execution begins by initializing the main package and then
-invoking the function <code>main</code>.
+Program execution begins by <a href="#Program_initialization">initializing the program</a>
+and then invoking the function <code>main</code> in package <code>main</code>.
When that function invocation returns, the program exits.
It does not wait for other (non-<code>main</code>) goroutines to complete.
</p>
type IntegerType int // shorthand for an integer type; it is not a real type
func Add(ptr Pointer, len IntegerType) Pointer
func Slice(ptr *ArbitraryType, len IntegerType) []ArbitraryType
+func SliceData(slice []ArbitraryType) *ArbitraryType
+func String(ptr *byte, len IntegerType) string
+func StringData(str string) *byte
</pre>
+<!--
+These conversions also apply to type parameters with suitable core types.
+Determine if we can simply use core type instead of underlying type here,
+of if the general conversion rules take care of this.
+-->
+
<p>
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>.
-Any pointer or value of <a href="#Types">underlying type</a> <code>uintptr</code> can be converted to
-a type of underlying type <code>Pointer</code> and vice versa.
+Any pointer or value of <a href="#Underlying_types">underlying type</a> <code>uintptr</code> can be
+<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.
</p>
<p>
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>.
Calls to <code>Alignof</code>, <code>Offsetof</code>, and <code>Sizeof</code>
are compile-time <a href="#Constant_expressions">constant expressions</a> of
a <a href="#Run_time_panics">run-time panic</a> occurs.
</p>
+<p>
+The function <code>SliceData</code> returns a pointer to the underlying array of the <code>slice</code> argument.
+If the slice's capacity <code>cap(slice)</code> is not zero, that pointer is <code>&slice[:1][0]</code>.
+If <code>slice</code> is <code>nil</code>, the result is <code>nil</code>.
+Otherwise it is a non-<code>nil</code> pointer to an unspecified memory address.
+</p>
+
+<p>
+The function <code>String</code> returns a <code>string</code> value whose underlying bytes start at
+<code>ptr</code> and whose length is <code>len</code>.
+The same requirements apply to the <code>ptr</code> and <code>len</code> argument as in the function
+<code>Slice</code>. If <code>len</code> is zero, the result is the empty string <code>""</code>.
+Since Go strings are immutable, the bytes passed to <code>String</code> must not be modified afterwards.
+</p>
+
+<p>
+The function <code>StringData</code> returns a pointer to the underlying bytes of the <code>str</code> argument.
+For an empty string the return value is unspecified, and may be <code>nil</code>.
+Since Go strings are immutable, the bytes returned by <code>StringData</code> must not be modified.
+</p>
+
<h3 id="Size_and_alignment_guarantees">Size and alignment guarantees</h3>
<p>
<p>
A struct or array type has size zero if it contains no fields (or elements, respectively) that have a size greater than zero. Two distinct zero-size variables may have the same address in memory.
</p>
+
+<h2 id="Appendix">Appendix</h2>
+
+<h3 id="Type_unification_rules">Type unification rules</h3>
+
+<p>
+The type unification rules describe if and how two types unify.
+The precise details are relevant for Go implementations,
+affect the specifics of error messages (such as whether
+a compiler reports a type inference or other error),
+and may explain why type inference fails in unusual code situations.
+But by and large these rules can be ignored when writing Go code:
+type inference is designed to mostly "work as expected",
+and the unification rules are fine-tuned accordingly.
+</p>
+
+<p>
+Type unification is controlled by a <i>matching mode</i>, which may
+be <i>exact</i> or <i>loose</i>.
+As unification recursively descends a composite type structure,
+the matching mode used for elements of the type, the <i>element matching mode</i>,
+remains the same as the matching mode except when two types are unified for
+<a href="#Assignability">assignability</a> (<code>≡<sub>A</sub></code>):
+in this case, the matching mode is <i>loose</i> at the top level but
+then changes to <i>exact</i> for element types, reflecting the fact
+that types don't have to be identical to be assignable.
+</p>
+
+<p>
+Two types that are not bound type parameters unify exactly if any of
+following conditions is true:
+</p>
+
+<ul>
+<li>
+ Both types are <a href="#Type_identity">identical</a>.
+</li>
+<li>
+ Both types have identical structure and their element types
+ unify exactly.
+</li>
+<li>
+ Exactly one type is an <a href="#Type_inference">unbound</a>
+ type parameter with a <a href="#Core_types">core type</a>,
+ and that core type unifies with the other type per the
+ unification rules for <code>≡<sub>A</sub></code>
+ (loose unification at the top level and exact unification
+ for element types).
+</li>
+</ul>
+
+<p>
+If both types are bound type parameters, they unify per the given
+matching modes if:
+</p>
+
+<ul>
+<li>
+ Both type parameters are identical.
+</li>
+<li>
+ At most one of the type parameters has a known type argument.
+ In this case, the type parameters are <i>joined</i>:
+ they both stand for the same type argument.
+ If neither type parameter has a known type argument yet,
+ a future type argument inferred for one the type parameters
+ is simultaneously inferred for both of them.
+</li>
+<li>
+ Both type parameters have a known type argument
+ and the type arguments unify per the given matching modes.
+</li>
+</ul>
+
+<p>
+A single bound type parameter <code>P</code> and another type <code>T</code> unify
+per the given matching modes if:
+</p>
+
+<ul>
+<li>
+ <code>P</code> doesn't have a known type argument.
+ In this case, <code>T</code> is inferred as the type argument for <code>P</code>.
+</li>
+<li>
+ <code>P</code> does have a known type argument <code>A</code>,
+ <code>A</code> and <code>T</code> unify per the given matching modes,
+ and one of the following conditions is true:
+ <ul>
+ <li>
+ Both <code>A</code> and <code>T</code> are interface types:
+ In this case, if both <code>A</code> and <code>T</code> are
+ also <a href="#Type_definitions">defined</a> types,
+ they must be <a href="#Type_identity">identical</a>.
+ Otherwise, if neither of them is a defined type, they must
+ have the same number of methods
+ (unification of <code>A</code> and <code>T</code> already
+ established that the methods match).
+ </li>
+ <li>
+ Neither <code>A</code> nor <code>T</code> are interface types:
+ In this case, if <code>T</code> is a defined type, <code>T</code>
+ replaces <code>A</code> as the inferred type argument for <code>P</code>.
+ </li>
+ </ul>
+</li>
+</ul>
+
+<p>
+Finally, two types that are not bound type parameters unify loosely
+(and per the element matching mode) if:
+</p>
+
+<ul>
+<li>
+ Both types unify exactly.
+</li>
+<li>
+ One type is a <a href="#Type_definitions">defined type</a>,
+ the other type is a type literal, but not an interface,
+ and their underlying types unify per the element matching mode.
+</li>
+<li>
+ Both types are interfaces (but not type parameters) with
+ identical <a href="#Interface_types">type terms</a>,
+ both or neither embed the predeclared type
+ <a href="#Predeclared_identifiers">comparable</a>,
+ corresponding method types unify exactly,
+ and the method set of one of the interfaces is a subset of
+ the method set of the other interface.
+</li>
+<li>
+ Only one type is an interface (but not a type parameter),
+ corresponding methods of the two types unify per the element matching mode,
+ and the method set of the interface is a subset of
+ the method set of the other type.
+</li>
+<li>
+ Both types have the same structure and their element types
+ unify per the element matching mode.
+</li>
+</ul>