aboutsummaryrefslogtreecommitdiff
path: root/doc
diff options
context:
space:
mode:
authorRobert Griesemer <gri@golang.org>2022-03-07 14:48:28 -0800
committerRobert Griesemer <gri@golang.org>2022-03-08 02:22:37 +0000
commit6e63be7b69aab25ac66029e7dfec47303d3b7505 (patch)
treeff9a57d7711c066ff8e56ae9cd50bea280dde280 /doc
parent31be6285a879af94c7283e6599e3f9b64266bc1a (diff)
downloadgo-6e63be7b69aab25ac66029e7dfec47303d3b7505.tar.gz
go-6e63be7b69aab25ac66029e7dfec47303d3b7505.zip
spec: document that type inference doesn't apply to generic types
Type inference for types was always a "nice to have" feature. Given the under-appreciated complexity of making it work in all cases, and the fact that we don't have a good understanding of how it might affect readability of generic code, require explicit type arguments for generic types. This matches the current implementation. Change-Id: Ie7ff6293d3fbea92ddc54c46285a4cabece7fe01 Reviewed-on: https://go-review.googlesource.com/c/go/+/390577 Trust: Robert Griesemer <gri@golang.org> Run-TryBot: Robert Griesemer <gri@golang.org> TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Ian Lance Taylor <iant@golang.org> Reviewed-by: Robert Findley <rfindley@google.com>
Diffstat (limited to 'doc')
-rw-r--r--doc/go_spec.html61
1 files changed, 29 insertions, 32 deletions
diff --git a/doc/go_spec.html b/doc/go_spec.html
index e8061f94b92..6278b8252de 100644
--- a/doc/go_spec.html
+++ b/doc/go_spec.html
@@ -11,11 +11,6 @@ For the pre-Go1.18 specification without generics support see
<a href="/doc/go1.17_spec.html">The Go Programming Language Specification</a>.
</p>
-<!-- TODO(gri) remove this before the final release -->
-<p><b>
-[For reviewers: Sections where we know of missing prose are marked like this. The markers will be removed before the release.]
-</b></p>
-
<h2 id="Introduction">Introduction</h2>
<p>
@@ -4230,7 +4225,7 @@ with the same underlying array.
<p>
A generic function or type is <i>instantiated</i> by substituting <i>type arguments</i>
for the type parameters.
-Instantiation proceeds in two phases:
+Instantiation proceeds in two steps:
</p>
<ol>
@@ -4262,31 +4257,12 @@ type parameter list type arguments after substitution
</pre>
<p>
-Type arguments may be provided explicitly, or they may be partially or completely
-<a href="#Type_inference">inferred</a>.
-A partially provided type argument list cannot be empty; there must be at least the
-first argument.
-</p>
-
-<pre>
-type T[P1 ~int, P2 ~[]P1] struct{ … }
-
-T[] // illegal: at least the first type argument must be present, even if it could be inferred
-T[int] // argument for P1 explicitly provided, argument for P2 inferred
-T[int, []int] // both arguments explicitly provided
-</pre>
-
-<p>
-A partial type argument list specifies a prefix of the full list of type arguments, leaving
-the remaining arguments to be inferred. Loosely speaking, type arguments may be omitted from
-"right to left".
-</p>
-
-<p>
-Generic types, and generic functions that are not <a href="#Calls">called</a>,
-require a type argument list for instantiation; if the list is partial, all
+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.
-Calls to generic functions may provide a (possibly partial) type
+A generic function that is called may provide a (possibly partial) type
argument list, or may omit it entirely if the omitted type arguments are
inferrable from the ordinary (non-type) function arguments.
</p>
@@ -4294,17 +4270,38 @@ inferrable from the ordinary (non-type) function arguments.
<pre>
func min[T ~int|~float64](x, y T) T { … }
-f := min // illegal: min must be instantiated when used without being called
+f := min // illegal: min must be instantiated with type arguments when used without being called
minInt := min[int] // minInt has type func(x, y int) int
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
</pre>
+<p>
+A partial type argument list cannot be empty; at least the first argument must be present.
+The list is a prefix of the full list of type arguments, leaving the remaining arguments
+to be inferred. Loosely speaking, type arguments may be omitted from "right to left".
+</p>
+
+<pre>
+func apply[S ~[]E, E any](s S, f(E) E) S { … }
+
+f0 := apply[] // illegal: type argument list cannot be empty
+f1 := apply[[]int] // type argument for S explicitly provided, type argument for E inferred
+f2 := apply[[]string, string] // both type arguments explicitly provided
+
+var bytes []byte
+r := apply(bytes, func(byte) byte { … }) // both type arguments inferred from the function arguments
+</pre>
+
+<p>
+For a generic type, all type arguments must always be provided explicitly.
+</p>
+
<h3 id="Type_inference">Type inference</h3>
<p>
-Missing type arguments may be <i>inferred</i> by a series of steps, described below.
+Missing function type arguments may be <i>inferred</i> by a series of steps, described below.
Each step attempts to use known information to infer additional type arguments.
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