@@ -2762,6 +2762,32 @@ sil-opt, one will see that we actually have an ownership violation due to the
27622762two uses of "value", one for initializing value2 and the other for the return
27632763value.
27642764
2765+ Move Only Types
2766+ ---------------
2767+
2768+ NOTE: This is experimental and is just an attempt to describe where the design
2769+ is currently for others reading SIL today. It should not be interpreted as
2770+ final.
2771+
2772+ Currently there are two kinds of "move only types" in SIL: pure move only types
2773+ that are always move only and move only wrapped types that are move only
2774+ versions of copyable types. The invariant that values of Move Only type obey is
2775+ that they can only be copied (e.x.: operand to a `copy_value `_, ``copy_addr [init] ``) during the
2776+ guaranteed passes when we are in Raw SIL. Once we are in non-Raw SIL though
2777+ (i.e. Canonical and later SIL stages), a program is ill formed if one copies a
2778+ move only type.
2779+
2780+ The reason why we have this special rule for move only types is that this allows
2781+ for SIL code generators to insert copies and then have a later guaranteed
2782+ checker optimization pass recover the underlying move only semantics by
2783+ reconstructing needed copies and removing unneeded copies using Ownership
2784+ SSA. If any such copies are actually needed according to Ownership SSA, the
2785+ checker pass emits a diagnostic stating that move semantics have been
2786+ violated. If such a diagnostic is emitted then the checker pass transforms all
2787+ copies on move only types to their explicit copy forms to ensure that once we
2788+ leave the diagnostic passes and enter canonical SIL, our "copy" invariant is
2789+ maintained.
2790+
27652791Runtime Failure
27662792---------------
27672793
@@ -4219,6 +4245,25 @@ operations::
42194245If ``T `` is a trivial type, then ``copy_addr `` is always equivalent to its
42204246take-initialization form.
42214247
4248+ It is illegal in non-Raw SIL to apply ``copy_addr [init] `` to a value that is
4249+ move only.
4250+
4251+ explicit_copy_addr
4252+ ``````````````````
4253+ ::
4254+
4255+ sil-instruction ::= 'explicit_copy_addr' '[take]'? sil-value
4256+ 'to' '[initialization]'? sil-operand
4257+
4258+ explicit_copy_addr [take] %0 to [initialization] %1 : $*T
4259+ // %0 and %1 must be of the same $*T address type
4260+
4261+ This instruction is exactly the same as `copy_addr `_ except that it has special
4262+ behavior for move only types. Specifically, an `explicit_copy_addr `_ is viewed
4263+ as a copy_addr that is allowed on values that are move only. This is only used
4264+ by a move checker after it has emitted an error diagnostic to preserve the
4265+ general ``copy_addr [init] `` ban in Canonical SIL on move only types.
4266+
42224267destroy_addr
42234268````````````
42244269::
@@ -5557,6 +5602,8 @@ independent of the operand. In terms of specific types:
55575602In ownership qualified functions, a ``copy_value `` produces a +1 value that must
55585603be consumed at most once along any path through the program.
55595604
5605+ It is illegal in non-Raw SIL to `copy_value `_ a value that is "move only".
5606+
55605607explicit_copy_value
55615608```````````````````
55625609
@@ -5566,27 +5613,18 @@ explicit_copy_value
55665613
55675614 %1 = explicit_copy_value %0 : $A
55685615
5569- Performs a copy of a loadable value as if by the value's type lowering and
5570- returns the copy. The returned copy semantically is a value that is completely
5571- independent of the operand. In terms of specific types:
5572-
5573- 1. For trivial types, this is equivalent to just propagating through the trivial
5574- value.
5575- 2. For reference types, this is equivalent to performing a ``strong_retain ``
5576- operation and returning the reference.
5577- 3. For ``@unowned `` types, this is equivalent to performing an
5578- ``unowned_retain `` and returning the operand.
5579- 4. For aggregate types, this is equivalent to recursively performing a
5580- ``copy_value `` on its components, forming a new aggregate from the copied
5581- components, and then returning the new aggregate.
5582-
5583- In ownership qualified functions, a ``explicit_copy_value `` produces a +1 value
5584- that must be consumed at most once along any path through the program.
5585-
5586- When move only variable checking is performed, ``explicit_copy_value `` is
5616+ This is exactly the same instruction semantically as `copy_value `_ with the
5617+ exception that when move only checking is performed, `explicit_copy_value `_ is
55875618treated as an explicit copy asked for by the user that should not be rewritten
55885619and should be treated as a non-consuming use.
55895620
5621+ This is used for two things:
5622+
5623+ 1. Implementing a copy builtin for no implicit copy types.
5624+ 2. To enable the move checker, once it has emitted an error diagnostic, to still
5625+ produce valid Ownership SSA SIL at the end of the guaranteed optimization
5626+ pipeline when we enter the Canonical SIL stage.
5627+
55905628move_value
55915629``````````
55925630
0 commit comments