This discussion can be focused on a couple of interesting choices. I'll point those out here rather than rehashing the long, meandering discussion of lifetime behavior in the pitch thread: [Pitch] Noncopyable (or "move-only") structs and enums - #98 by Andrew_Trick
For copyable values, opting into ownership control means:
consuming
values are eagerly consumed.
borrowing
values are associated with a lexical scope.
With consuming
, there aren't any subtle do-what-I-mean rules (that probabilistically guess the author's intention). There is no association with a lexical scope, and "deinit barriers" are irrelevant. Lifetimes are fully, progressively optimized. That's necessary to optimize CoW and ARC. If the programmer escapes an unsafe pointer or weak reference, they need to borrow the parent value for the duration of that escape.
A noncopyable let
should be defined as consuming
since we can't mimic the behavior of a copyable let
. I do not think that noncopyable let
s should have anything to do with a lexical scopes or with "deinit barriers". There's no coherent way to do that. We could do a best effort "maximal" lifetime, but that would be highly confusing. It would mean that programmers can escape pointers, and sometimes it would just happen to work. Changing a consume in an unrelated part of the code could easily break their assumptions. The simple rule should be: use a borrow scope to protect escaping pointers. If they fail to do this, we want the code to break sooner rather than later.
The more interesting question is whether noncopyable types should have strict lifetimes vs. optimized lifetimes. For owned noncopyable values, an optimized lifetime can result in running a struct deinit early after dead code elimination. For borrowed noncopyable values, it means that a struct deinit can be reordered with other side effects inside the borrow scope.
I'm in favor of strict lifetimes for noncopyable types, particularly when the struct has a deinit, because this ensures consistent behavior independent of the optimizer. There is a compelling argument that programmers should not rely on struct deinit side effects, but not compelling enough to me.
I can provide examples in a follow-up if needed.