Some questions after re-reading...
invoking a consuming method on a value, or accessing a property of the value through a consuming get
or consuming set
accessor:
Do you happen to have an example of where one would ever use a consuming set
? (Though I see why this operation could be included if just for the sake of composability.)
passing an argument to an init
parameter that is not explicitly borrowing
:
Does this imply all parameters of the generated memberwise init are consuming and implicit copies are made for all copyable types?
pattern-matching a value with switch
, if let
, or if case
:
- Assuming
Optional<noncopyable T>
was allowed why is the explicit consume needed here if let y = consume x { ... }
?
- Is the idea that one could write
switch borrow x
to avoid this consume-by-default behavior?
Iterating a Sequence with a for loop:
let xs = [1, 2, 3]
for x in consume xs {}
use(xs) // ERROR: xs consumed by `for` loop
Same question about explicit consume
, otherwise this case seems covered by “explicitly consuming a value with the consume operator”
guard let condition = getCondition() else {
consume(x)
}
This would probably clearer to the reader with a function called consumesAnX(x)
and an explicit return
Accessing a computed property or subscript through borrowing or nonmutating getter or setter borrows the self parameter for the duration of the accessor’s execution.
Does this imply that nonmutating
would be discouraged in favor of borrowing
in swift 6?
it must declare whether the parameter uses the borrowing, consuming, or inout convention:
Is there a rational to requiring this as opposed to defaulting to borrowing like methods mentioned just below?
class Foo {
var fd: FileDescriptor
init(fd: FileDescriptor) { self.fd = fd }
}
This appears to be missing a borrowing or consuming
A @noncopyable struct or enum may declare a deinit, which will run implicitly when the lifetime of the value ends
is it possible to call MyType.deinit
as an explicit consuming operation or is the only way to write this consume myInstance
?
A noncopyable type can be made copyable while generally maintaining source compatibility.
Do you have an example or deeper description of how this might work when making noncopyable with a deinit copyable? Would I assume you would be forced to remove the deinit and if so would that not be ABI breaking unlike: “However, an noncopyable type can be made copyable without breaking its ABI.“?
However, for progressive disclosure and source compatibility reasons, we still want the majority of types to be Copyable by default, without making them explicitly declare it; noncopyable types are likely to remain the exception rather than the rule, with automatic lifetime management via ARC by the compiler being sufficient for most code like it is today.
I could see a package/module where you one would not want this default. Ex: if you’re writing embedded firmware or device drivers (aspirational). In this case you would want a way to spell the “positive” case. I argue that this spelling is naturally extension MyType: Copyable
. In which case the negative spelling (to mirror Sendable) would be extension MyType: @unavailable Copyable
.
This could expressed to the compiler in a configurable manner as something like --implicit-sendable=internal
or --implicit-copyable=public
so a embedded language mode could be made where one could not set these flags.
Additionally, is there ever a world in which we may want a type to be immovable, e.g. Literals stored in a .rodata
/STRINGS
sections? In this case I think spelling this would be extension MyType: @unavailable Moveable
. While I don't think necessarily think this would be written frequently, I think it would be nice to be able to show these semantics in a generated interface when jumping to a module definition in Xcode/vscode.