|
1 | 1 | <!--{
|
2 | 2 | "Title": "The Go Programming Language Specification",
|
3 |
| - "Subtitle": "Version of July 25, 2023", |
| 3 | + "Subtitle": "Version of July 31, 2023", |
4 | 4 | "Path": "/ref/spec"
|
5 | 5 | }-->
|
6 | 6 |
|
@@ -4620,13 +4620,13 @@ <h4 id="Type_unification">Type unification</h4>
|
4620 | 4620 | <p>
|
4621 | 4621 | Type inference solves type equations through <i>type unification</i>.
|
4622 | 4622 | Type unification recursively compares the LHS and RHS types of an
|
4623 |
| -equation, where either or both types may be or contain type parameters, |
| 4623 | +equation, where either or both types may be or contain bound type parameters, |
4624 | 4624 | and looks for type arguments for those type parameters such that the LHS
|
4625 | 4625 | and RHS match (become identical or assignment-compatible, depending on
|
4626 | 4626 | context).
|
4627 | 4627 | To that effect, type inference maintains a map of bound type parameters
|
4628 |
| -to inferred type arguments. |
4629 |
| -Initially, the type parameters are known but the map is empty. |
| 4628 | +to inferred type arguments; this map is consulted and updated during type unification. |
| 4629 | +Initially, the bound type parameters are known but the map is empty. |
4630 | 4630 | During type unification, if a new type argument <code>A</code> is inferred,
|
4631 | 4631 | the respective mapping <code>P ➞ A</code> from type parameter to argument
|
4632 | 4632 | is added to the map.
|
@@ -4674,9 +4674,12 @@ <h4 id="Type_unification">Type unification</h4>
|
4674 | 4674 |
|
4675 | 4675 | <p>
|
4676 | 4676 | Unification uses a combination of <i>exact</i> and <i>loose</i>
|
4677 |
| -Unification (see Appendix) depending on whether two types have |
4678 |
| -to be <a href="#Type_identity">identical</a> or simply |
4679 |
| -<a href="#Assignability">assignment-compatible</a>: |
| 4677 | +unification depending on whether two types have to be |
| 4678 | +<a href="#Type_identity">identical</a>, |
| 4679 | +<a href="#Assignability">assignment-compatible</a>, or |
| 4680 | +only structurally equal. |
| 4681 | +The respective <a href="#Type_unification_rules">type unification rules</a> |
| 4682 | +are spelled out in detail in the <a href="#Appendix">Appendix</a>. |
4680 | 4683 | </p>
|
4681 | 4684 |
|
4682 | 4685 | <p>
|
@@ -8357,3 +8360,148 @@ <h3 id="Size_and_alignment_guarantees">Size and alignment guarantees</h3>
|
8357 | 8360 | <p>
|
8358 | 8361 | 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.
|
8359 | 8362 | </p>
|
| 8363 | + |
| 8364 | +<h2 id="Appendix">Appendix</h2> |
| 8365 | + |
| 8366 | +<h3 id="Type_unification_rules">Type unification rules</h3> |
| 8367 | + |
| 8368 | +<p> |
| 8369 | +The type unification rules describe if and how two types unify. |
| 8370 | +The precise details are relevant for Go implementations, |
| 8371 | +affect the specifics of error messages (such as whether |
| 8372 | +a compiler reports a type inference or other error), |
| 8373 | +and may explain why type inference fails in unusual code situations. |
| 8374 | +But by and large these rules can be ignored when writing Go code: |
| 8375 | +type inference is designed to mostly "work as expected", |
| 8376 | +and the unification rules are fine-tuned accordingly. |
| 8377 | +</p> |
| 8378 | + |
| 8379 | +<p> |
| 8380 | +Type unification is controlled by a <i>matching mode</i>, which may |
| 8381 | +be <i>exact</i> or <i>loose</i>. |
| 8382 | +As unification recursively descends a composite type structure, |
| 8383 | +the matching mode used for elements of the type, the <i>element matching mode</i>, |
| 8384 | +remains the same as the matching mode except when two types are unified for |
| 8385 | +<a href="#Assignability">assignability</a> (<code>≡<sub>A</sub></code>): |
| 8386 | +in this case, the matching mode is <i>loose</i> at the top level but |
| 8387 | +then changes to <i>exact</i> for element types, reflecting the fact |
| 8388 | +that types don't have to be identical to be assignable. |
| 8389 | +</p> |
| 8390 | + |
| 8391 | +<p> |
| 8392 | +Two types that are not bound type parameters unify exactly if any of |
| 8393 | +following conditions is true: |
| 8394 | +</p> |
| 8395 | + |
| 8396 | +<ul> |
| 8397 | +<li> |
| 8398 | + Both types are <a href="#Type_identity">identical</a>. |
| 8399 | +</li> |
| 8400 | +<li> |
| 8401 | + Both types have identical structure and their element types |
| 8402 | + unify exactly. |
| 8403 | +</li> |
| 8404 | +<li> |
| 8405 | + Exactly one type is an <a href="#Type_inference">unbound</a> |
| 8406 | + type parameter with a <a href="#Core_types">core type</a>, |
| 8407 | + and that core type unifies with the other type per the |
| 8408 | + unification rules for <code>≡<sub>A</sub></code> |
| 8409 | + (loose unification at the top level and exact unification |
| 8410 | + for element types). |
| 8411 | +</li> |
| 8412 | +</ul> |
| 8413 | + |
| 8414 | +<p> |
| 8415 | +If both types are bound type parameters, they unify per the given |
| 8416 | +matching modes if: |
| 8417 | +</p> |
| 8418 | + |
| 8419 | +<ul> |
| 8420 | +<li> |
| 8421 | + Both type parameters are identical. |
| 8422 | +</li> |
| 8423 | +<li> |
| 8424 | + At most one of the type parameters has a known type argument. |
| 8425 | + In this case, the type parameters are <i>joined</i>: |
| 8426 | + they both stand for the same type argument. |
| 8427 | + If neither type parameter has a known type argument yet, |
| 8428 | + a future type argument inferred for one the type parameters |
| 8429 | + is simultaneously inferred for both of them. |
| 8430 | +</li> |
| 8431 | +<li> |
| 8432 | + Both type parameters have a known type argument |
| 8433 | + and the type arguments unify per the given matching modes. |
| 8434 | +</li> |
| 8435 | +</ul> |
| 8436 | + |
| 8437 | +<p> |
| 8438 | +A single bound type parameter <code>P</code> and another type <code>T</code> unify |
| 8439 | +per the given matching modes if: |
| 8440 | +</p> |
| 8441 | + |
| 8442 | +<ul> |
| 8443 | +<li> |
| 8444 | + <code>P</code> doesn't have a known type argument. |
| 8445 | + In this case, <code>T</code> is inferred as the type argument for <code>P</code>. |
| 8446 | +</li> |
| 8447 | +<li> |
| 8448 | + <code>P</code> does have a known type argument <code>A</code>, |
| 8449 | + <code>A</code> and <code>T</code> unify per the given matching modes, |
| 8450 | + and one of the following conditions is true: |
| 8451 | + <ul> |
| 8452 | + <li> |
| 8453 | + Both <code>A</code> and <code>T</code> are interface types: |
| 8454 | + In this case, if both <code>A</code> and <code>T</code> are |
| 8455 | + also <a href="#Type_definitions">defined</a> types, |
| 8456 | + they must be <a href="#Type_identity">identical</a>. |
| 8457 | + Otherwise, if neither of them is a defined type, they must |
| 8458 | + have the same number of methods |
| 8459 | + (unification of <code>A</code> and <code>T</code> already |
| 8460 | + established that the methods match). |
| 8461 | + </li> |
| 8462 | + <li> |
| 8463 | + Neither <code>A</code> nor <code>T</code> are interface types: |
| 8464 | + In this case, if <code>T</code> is a defined type, <code>T</code> |
| 8465 | + replaces <code>A</code> as the inferred type argument for <code>P</code>. |
| 8466 | + </li> |
| 8467 | + <li> |
| 8468 | + In all other cases unification of <code>P</code> and <code>T</code> fails. |
| 8469 | + </li> |
| 8470 | + </ul> |
| 8471 | +</li> |
| 8472 | +</ul> |
| 8473 | + |
| 8474 | +<p> |
| 8475 | +Finally, two types that are not bound type parameters unify loosely |
| 8476 | +(and per the element matching mode) if: |
| 8477 | +</p> |
| 8478 | + |
| 8479 | +<ul> |
| 8480 | +<li> |
| 8481 | + Both types unify exactly. |
| 8482 | +</li> |
| 8483 | +<li> |
| 8484 | + One type is a <a href="#Type_definitions">defined type</a>, |
| 8485 | + the other type is a type literal, but not an interface, |
| 8486 | + and their underlying types unify per the element matching mode. |
| 8487 | +</li> |
| 8488 | +<li> |
| 8489 | + Both types are interfaces (but not type parameters) with |
| 8490 | + identical <a href="#Interface_types">type terms</a>, |
| 8491 | + both or neither embed the predeclared type |
| 8492 | + <a href="#Predeclared_identifiers">comparable</a>, |
| 8493 | + corresponding method types unify per the element matching mode, |
| 8494 | + and the method set of one of the interfaces is a subset of |
| 8495 | + the method set of the other interface. |
| 8496 | +</li> |
| 8497 | +<li> |
| 8498 | + Only one type is an interface (but not a type parameter), |
| 8499 | + corresponding methods of the two types unify per the element matching mode, |
| 8500 | + and the method set of the interface is a subset of |
| 8501 | + the method set of the other type. |
| 8502 | +</li> |
| 8503 | +<li> |
| 8504 | + Both types have the same structure and their element types |
| 8505 | + unify per the element matching mode. |
| 8506 | +</li> |
| 8507 | +</ul> |
0 commit comments