Skip to content

Commit bd42aa8

Browse files
griesemerRobert Griesemer
authored and
Robert Griesemer
committed
spec: describe new semantics for comparable and constraint satisfaction
For #56548. Fixes #57012. Change-Id: I44f850522e52b1811025fb31bcef289da8f8089d Reviewed-on: https://go-review.googlesource.com/c/go/+/457437 TryBot-Bypass: Robert Griesemer <[email protected]> Reviewed-by: Ian Lance Taylor <[email protected]> Reviewed-by: Robert Findley <[email protected]> Reviewed-by: Robert Griesemer <[email protected]>
1 parent ffefcd3 commit bd42aa8

File tree

1 file changed

+57
-23
lines changed

1 file changed

+57
-23
lines changed

doc/go_spec.html

+57-23
Original file line numberDiff line numberDiff line change
@@ -2652,7 +2652,7 @@ <h3 id="Type_parameter_declarations">Type parameter declarations</h3>
26522652
<h4 id="Type_constraints">Type constraints</h4>
26532653

26542654
<p>
2655-
A type constraint is an <a href="#Interface_types">interface</a> that defines the
2655+
A <i>type constraint</i> is an <a href="#Interface_types">interface</a> that defines the
26562656
set of permissible type arguments for the respective type parameter and controls the
26572657
operations supported by values of that type parameter.
26582658
</p>
@@ -2663,15 +2663,15 @@ <h4 id="Type_constraints">Type constraints</h4>
26632663

26642664
<p>
26652665
If the constraint is an interface literal of the form <code>interface{E}</code> where
2666-
<code>E</code> is an embedded type element (not a method), in a type parameter list
2666+
<code>E</code> is an embedded <a href="#Interface_types">type element</a> (not a method), in a type parameter list
26672667
the enclosing <code>interface{ … }</code> may be omitted for convenience:
26682668
</p>
26692669

26702670
<pre>
26712671
[T []P] // = [T interface{[]P}]
26722672
[T ~int] // = [T interface{~int}]
26732673
[T int|string] // = [T interface{int|string}]
2674-
type Constraint ~int // illegal: ~int is not inside a type parameter list
2674+
type Constraint ~int // illegal: ~int is not in a type parameter list
26752675
</pre>
26762676

26772677
<!--
@@ -2684,25 +2684,13 @@ <h4 id="Type_constraints">Type constraints</h4>
26842684
The <a href="#Predeclared_identifiers">predeclared</a>
26852685
<a href="#Interface_types">interface type</a> <code>comparable</code>
26862686
denotes the set of all non-interface types that are
2687-
<a href="#Comparison_operators">strictly comparable</a>. Specifically,
2688-
a type <code>T</code> implements <code>comparable</code> if:
2687+
<a href="#Comparison_operators">strictly comparable</a>.
26892688
</p>
26902689

2691-
<ul>
2692-
<li>
2693-
<code>T</code> is not an interface type and <code>T</code> is strictly comparable; or
2694-
</li>
2695-
<li>
2696-
<code>T</code> is an interface type and each type in <code>T</code>'s
2697-
<a href="#Interface_types">type set</a> is strictly comparable.
2698-
</li>
2699-
</ul>
2700-
27012690
<p>
2702-
Even though interfaces that are not type parameters can be
2703-
<a href="#Comparison_operators">compared</a>
2704-
(possibly causing a run-time panic) they do not implement
2705-
<code>comparable</code>.
2691+
Even though interfaces that are not type parameters are <a href="#Comparison_operators">comparable</a>,
2692+
they are not strictly comparable and therefore they do not implement <code>comparable</code>.
2693+
However, they <a href="#Satisfying_a_type_constraint">satisfy</a> <code>comparable</code>.
27062694
</p>
27072695

27082696
<pre>
@@ -2721,6 +2709,51 @@ <h4 id="Type_constraints">Type constraints</h4>
27212709
values or variables, or components of other, non-interface types.
27222710
</p>
27232711

2712+
<h4 id="Satisfying_a_type_constraint">Satisfying a type constraint</h4>
2713+
2714+
<p>
2715+
A type argument <code>T</code><i> satisfies</i> a type constraint <code>C</code>
2716+
if <code>T</code> is an element of the type set defined by <code>C</code>; i.e.,
2717+
if <code>T</code> <a href="#Implementing_an_interface">implements</a> <code>C</code>.
2718+
As an exception, a <a href="#Comparison_operators">strictly comparable</a>
2719+
type constraint may also be satisfied by a <a href="#Comparison_operators">comparable</a>
2720+
(not necessarily strictly comparable) type argument.
2721+
More precisely:
2722+
</p>
2723+
2724+
<p>
2725+
A type T <i>satisfies</i> a constraint <code>C</code> if
2726+
</p>
2727+
2728+
<ul>
2729+
<li>
2730+
<code>T</code> <a href="#Implementing_an_interface">implements</a> <code>C</code>; or
2731+
</li>
2732+
<li>
2733+
<code>C</code> can be written in the form <code>interface{ comparable; E }</code>,
2734+
where <code>E</code> is a <a href="#Basic_interfaces">basic interface</a> and
2735+
<code>T</code> is <a href="#Comparison_operators">comparable</a> and implements <code>E</code>.
2736+
</li>
2737+
</ul>
2738+
2739+
<pre>
2740+
type argument type constraint // constraint satisfaction
2741+
2742+
int interface{ ~int } // satisfied: int implements interface{ ~int }
2743+
string comparable // satisfied: string implements comparable (string is stricty comparable)
2744+
[]byte comparable // not satisfied: slices are not comparable
2745+
any interface{ comparable; int } // not satisfied: any does not implement interface{ int }
2746+
any comparable // satisfied: any is comparable and implements the basic interface any
2747+
struct{f any} comparable // satisfied: struct{f any} is comparable and implements the basic interface any
2748+
any interface{ comparable; m() } // not satisfied: any does not implement the basic interface interface{ m() }
2749+
interface{ m() } interface{ comparable; m() } // satisfied: interface{ m() } is comparable and implements the basic interface interface{ m() }
2750+
</pre>
2751+
2752+
<p>
2753+
Because of the exception in the constraint satisfaction rule, comparing operands of type parameter type
2754+
may panic at run-time (even though comparable type parameters are always strictly comparable).
2755+
</p>
2756+
27242757
<h3 id="Variable_declarations">Variable declarations</h3>
27252758

27262759
<p>
@@ -4221,7 +4254,7 @@ <h3 id="Instantiations">Instantiations</h3>
42214254
</li>
42224255

42234256
<li>
4224-
After substitution, each type argument must <a href="#Interface_types">implement</a>
4257+
After substitution, each type argument must <a href="#Satisfying_a_type_constraint">satisfy</a>
42254258
the <a href="#Type_parameter_declarations">constraint</a> (instantiated, if necessary)
42264259
of the corresponding type parameter. Otherwise instantiation fails.
42274260
</li>
@@ -4235,9 +4268,10 @@ <h3 id="Instantiations">Instantiations</h3>
42354268
<pre>
42364269
type parameter list type arguments after substitution
42374270

4238-
[P any] int int implements any
4239-
[S ~[]E, E any] []int, int []int implements ~[]int, int implements any
4240-
[P io.Writer] string illegal: string doesn't implement io.Writer
4271+
[P any] int int satisfies any
4272+
[S ~[]E, E any] []int, int []int satisfies ~[]int, int satisfies any
4273+
[P io.Writer] string illegal: string doesn't satisfy io.Writer
4274+
[P comparable] any any satisfies (but does not implement) comparable
42414275
</pre>
42424276

42434277
<p>

0 commit comments

Comments
 (0)