@@ -2762,6 +2762,32 @@ sil-opt, one will see that we actually have an ownership violation due to the
2762
2762
two uses of "value", one for initializing value2 and the other for the return
2763
2763
value.
2764
2764
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
+
2765
2791
Runtime Failure
2766
2792
---------------
2767
2793
@@ -4219,6 +4245,25 @@ operations::
4219
4245
If ``T `` is a trivial type, then ``copy_addr `` is always equivalent to its
4220
4246
take-initialization form.
4221
4247
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
+
4222
4267
destroy_addr
4223
4268
````````````
4224
4269
::
@@ -5557,6 +5602,8 @@ independent of the operand. In terms of specific types:
5557
5602
In ownership qualified functions, a ``copy_value `` produces a +1 value that must
5558
5603
be consumed at most once along any path through the program.
5559
5604
5605
+ It is illegal in non-Raw SIL to `copy_value `_ a value that is "move only".
5606
+
5560
5607
explicit_copy_value
5561
5608
```````````````````
5562
5609
@@ -5566,27 +5613,18 @@ explicit_copy_value
5566
5613
5567
5614
%1 = explicit_copy_value %0 : $A
5568
5615
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
5587
5618
treated as an explicit copy asked for by the user that should not be rewritten
5588
5619
and should be treated as a non-consuming use.
5589
5620
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
+
5590
5628
move_value
5591
5629
``````````
5592
5630
0 commit comments